Arduino: GSM Modul und Keypad zusammen macht Probleme

So dele, seit Anfang diesen Jahres bastle ich mehr oder weniger regelmäßig in meiner Freizeit an einem "Schloss" für ein Baumhaus.
Die Idee: Der Arduino bekommt vom Webserver einen Code als SMS gesendet, der ausgewertet wird. Die SMS enthält ein bisschen Text (geheimer Prefix! Aus Securitysicht natürlich ein Witz. :) ) und hinterher dann den Code. Dieser Code ist dann solange gültig, bis irgendwann eine Lösch SMS kommt. Der Code wird via Keypad eingegeben: Ist der Code richtig, öffnet sich ein Relais und damit das Schloss.
Sobald aber nun ein Code drin ist, ist der Arduino im "Code Eingabe" Modus und leider gibt es keinen Interrupt vom GSM Modul, der mir mitteilen würde, dass gerade eine SMS gekommen ist.
Deshalb hängt sich der Arduino regelmäßig auf und nach ein paar Mal testen kann das Modul keine SMS mehr empfangen. Sprich die Idee ist zwar eigentlich nicht schlecht, aber momentan viel zu unzuverlässig.

Das kann nun an mehreren Sachen liegen:
1. Die Hardware ist doof. (Würde ich aber fast mal ausschließen wollen, da es selbst mit einem Original Arduino nicht zuverlässig funktioniert!)
2. Ich hab einen Mist programmiert (dabei hab ich die logischen Dinge schon in Funktionen ausgelagert, damit sie nur dann aufgerufen werden, wenn es explizit erforderlich ist)
3. Das GSM macht generell zu viele Probleme.

Vermutlich eine Mischung aus allen 3 Punkten + X!

Irgendwann stelle ich vielleicht den Code nochmal online. Muss dazu aber noch ein paar Dinge wie PIN und Prefix entfernen!

Aber es gibt ja noch andere Ideen: Man nimmt statt einem GSM Modul ein RTC Modul, mit dem man immer ein aktuelles Datum hat. Anhand vom Datum kann man einen Code generieren (ein paar Mal multiplizieren, damit es nicht ganz so offensichtlich ist.) und einem Teil für die Anzahl der Tage. Hinterher kann dann der Besucher einmal den Code eingeben und er wird solange gültig sein, bis irgendwann die Anzahl der Tage überschritten wurde. Das sollte relativ einfach und zuverlässig funktionieren. Der Code Generierungsalgorithmus ist dann einmal auf dem Arduino und einmal auf dem Webserver. Beide sollten gegen Reverse Engineering einigermaßen sicher sein. Zumindest vom Arduino fällt mir gerade keine einfach Methode ein.

Alternative 2: Man generiert einen QR-Code und liest diesen dann per Kamera an einem Raspberry Pi aus. Das hätte auch Stil und wäre bequem. Wie zuverlässig es funktioniert bleibt mal dahin gestellt. Wenn ich ab und an mal ein Paket bekomme, dass in der Packstation gelagert wird war es oft mühselig den normalen Barcode erfolgreich einscannen zu lassen. Aber wahrscheinlich hab ich es nur nicht im richtigen Winkel hingehoben oder bin einfach zu doof. Nach Quadrilliarden Versuchen hat es aber dann doch immer geklappt. ;)

Soviel mal zu diesem Thema. Näheres dann, wenn alles klappt. Den Code werde ich dann vermutlich mal einscannen. Den Algorithmus aus Gründen der nationalen Sicherheit natürlich nicht! Das dürfen findige Hacker selbst herausfinden! So schwer wird es aber nicht sein.

Ganz aufgeben möchte ich das GSM Modul noch nicht. Denn zumindest der SMS Versand funktioniert recht zuverlässig. Also könnte man diese Funktion in Form einer Alarmsicherung mit Reedkontakt noch gut verwenden! Jetzt muss aber erstmal ein funktionerendes Schloss her, danach sehen wir weiter! Der Rest ist eher nettes Beiwerk!

Als dritte Alternative kann man sich auch einfach "Android meets Arduino" ansehen. Die Smartphones sind nicht mehr teuer und haben schon einiges an Sensoren dabei, da wäre es ganz nett wenn man diese auch nutzen könnte.

WTF Duino - Aus "einfach" wird kompliziert

Eigentlich ist es nur ein Scherz. Ein Brite hat den Hype um Arduino ein wenig aufs Korn genommen und eine Platine in Form einer Banane entwickelt. Den WTF Duino Technisch ist es ein Klon eines ganz normalen Arduinos. Der Hauptunterschied: Die Form ist eine Banane und sie ist gelb.
Das Schwierige ist: Die GPIO Pins sind nicht gerade angeordnet, sondern immer etwas versetzt zueinander. Damit ist das einfache Anstecken auf ein Breadboard gegessen. Es funktioniert einfach nicht. Um den Schwierigkeitsgrad noch weiter zu erhöhen: Die Beschriftungen sind nicht mit der Funktion identisch. Sprich man muss erstmal herausfinden, welcher Pin zu welcher Beschreibung passt.
Und letztlich gibt es keinen Platinenplan und kein Open-Source. Das Ganze ist Closed Source.

Das Ganze hört sich bescheuert an, ist es eigentlich auch. Aber die Leute im Internet finden das so cool, dass sie eine Kickstarter Kampange fordern. Um das Getrolle endgültig auf die Spitze zu treiben, hat der Münchener CCC gleich mal ein Layout der Banane, einer Kirsche und einer Erdbeere erstellt und auf GitHub gestellt.

Hier noch zwei Video zum WTF Duino.

[youtube]https://www.youtube.com/watch?v=H9GFnzRUP3A[/youtube]

[youtube]https://www.youtube.com/watch?v=KAL0XMIszVk[/youtube]

Sublime Text 2 mit Stino und Arduino 1.0.5 für Arduino Entwicklung

Anfang diesen Jahres hab ich mit der Arduino Programmierung bzw. Experimentieren angefangen. Was mich immer gestört hat, war diese hässliche Standard Arduino IDE. Man bekommt sie zwar kostenlos und kann damit auch schon alle Standard Boards und weitere Boards ansteuern und den Code dafür kompilieren. Aber sie hat nen weißen Hintergrund, keine Autoformatierung und vor allem keine Autocompletion. Wer unter Windows mit Visual Studio entwickelt weiß diese Autocompletion einfach zu schätzen. Das ist goldwert.

Damals hat ich auch schon probiert meine alte Sublime Text Lizenz (die mit 70$ nicht günstig ist) wieder auf meinem Laptop zum Laufen zu bekommen. Das hat auch wunderbar geklappt. Aber das tolle Stino Plugin konnte ich leider nicht zum Kompilieren überreden.
Deshalb bin ich damals doch auf ArduIDE hängen geblieben, nachdem ich vieles ausprobiert habe und irgendwie nichts wirklich funktioniert hat. Damit hab ich dann in letzter Zeit meinen ganzen Code für die Türöffnung geschrieben. Das hat gut funktioniert, das Syntax Highlighting ist schon besser. Aber das Plugin wird eben auch nicht weiter entwickelt und mir selbst fehlt die Muse und das Know How.

Dann hat Herr monkel neulich erwähnt, dass er gerade auch Sublime Text verwendet. Da morgen die GPN beginnt und ich dort ein bisschen coden möchte, hab ich eben mal wieder eine neue SIM Karte und das GSM Modem ausprobieren wollen.
Und ich hab nochmal Stino ausprobiert. Es kam immer der beknackte Error 127 und die Google Ergebnisse haben sich immer auf Mac OS bezogen. Da kann ich mit Xubuntu 14.04 einpacken. :(

Aber nun hab ich die Lösung gefunden:

1. Sublime Text 2 installieren. Da gibt es hier diesen Blogpost dazu.

sudo add-apt-repository ppa:webupd8team/sublime-text-2
sudo apt-get update
sudo apt-get install sublime-text

Natürlich sollte man sich klarmachen, dass Fremdquellen auch potenziell gefährlich sein können. Als alter Windows User klickt man aber ja auch immer überall drauf. Und ich halte diese Quelle für Vertrauenswürdig, schließlich stellt er den besten Texteditor der Welt (tm) als Paket zur Verfügung.

2. Befolgt diese Anleitung:
Das nachfolgende ist nur eine grobe Zusammenfassung!
- Installiert in Sublime Text 2 "Package Control"
- Dann Package Control aufrufen (Preferences - Package Control)
- "Install" eingeben.
- "Arduino-like IDE" eingeben (sollte von Robert Will und sein Stino sein!)
- Dann im neuen Arduino Menu, die Preferences einstellen. Wenn man möchte auch die Sprache und vor allem den Pfad zur Arduino Version (wegen GSM brauch ich die 1.0.5).
- Sketch Ordner hinzufügen.
- Board einstellen.
- Ersten Sketch kompilieren und freuen!

Stino und Sublime Text 2 ist einfach genial.
Es gibt endlich eine Autocompletion für Arduino! Das ist soooo geil!

Oder wisst ihr alle Befehle auswendig?
Ich nicht, daher freu ich mich darüber.

Darüber freut sich jeder. Gut bei Richard Stallman würde ich vielleicht eine Ausnahme machen!

ArduIDE - Die alternative IDE für Arduino unter Linux

Seit einer Weile beschäftige ich mich ja mit Arduino. Als überzeugter Linux Benutzer (ich muss mich schließlich schon im Geschäft immer wieder mit Windows und seinem nervigem Update Verhalten herumärgern!) wollte ich natürlich auch eine native Anwendung haben. Arduino bietet zwar auch eine IDE an. Mit der kann man zwar die Anfangsbeispiele noch gut nachprogrammieren. Aber sobald man ernsthaft etwas programmieren möchte wird es einfach nervig. Keine Auto Completion und die Syntax Highlighting kommt auch erst wenn man das Wort zu Ende geschrieben hat. Kurzum die bequemen Sachen die man beispielsweise von Visual Studio (ja ich benutze das recht gerne!) kennt gibt es dort alles nicht. Der einzige Vorteil ist: Der Compiler unterstützt alle offiziellen Boards.

Also hab ich vor längerer Zeit mal diesen Beitrag angeschaut und versucht mit MarioMole glücklich zu werden. Nachdem ich aber nun mit dem GSM Modul arbeiten möchte, brauch ich zwingend noch die 1.0.5er Arduino Version. Und irgendwie hat das mit MarioMole nie so richtig bei mir funktioniert. Also mal den Komodo Edit ausprobiert, hat aber auch nicht funktioniert. Stino für Sublime Text wäre noch eine Möglichkeit gewesen. Ich war aber immer zu faul Sublime wieder zu installieren. Außerdem fand ich den Startvorgang immer enorm langsam. Da ist unter Windows Notepad++ immer noch schneller und unter Linux ein Gedit auch schneller. Dann hab ich die letzten Tage noch den Geany ausprobiert. Ein sehr schicker Editor mit leichten IDE Fähigkeiten. Ich hab nach dieser Anleitung versucht das Ding zum Laufen zu bekommen, hat bei mir (Ubuntu 14.04) aber leider nicht geklappt. Zumindest als ich ein Standard GSM Beispiel ausprobiert habe. Also wieder weg und dann mal richtig gegoogelt: "Alternative Arduino IDE Linux" und die folgende Seite gefunden.
Dann einfach mal die Anleitung zum Installieren Schritt für Schritt nachgemacht und mir sozusagen die IDE selbst aus den Quellen kompiliert. Beim ersten Starten wollte ich die Arduino 1.0.5er Installation von Ubuntu Quellen angeben. Die wurde aber nicht akzeptiert.
Also einfach die 1.0.5 von Arduino geladen in mein Home entpackt und plötzlich funktioniert es auch schon. Der alles entscheidende Test war mal wieder das Kompilieren eines GSM Beispiels und Hochladen. Hat funktioniert. Es gibt auch einen Serial Monitor in dieser IDE. Den hab ich noch nicht ganz kapiert, aber auf jeden Fall hab ich endlich mal eine funktionierende IDE für Linux, die sogar relativ schick aussieht und stabil läuft.

Java Leute hätten mir ja wieder Eclipse empfohlen, aber ich mag kein Java. Das wirft immer seltsame Fehlermeldungen und naja die Runtime lässt sich seit Jahren unter Windows 7 nicht als normaler Benutzer updaten (ich geb ja schon meine Admin Credentials ein!).

Das ino Projekt wäre noch eine interessante Kommandozeilen Sache gewesen. Aber ich möchte gerne eine grafische IDE haben, die einfach das macht, was ich erwarte. Das Kompilieren und Uploaden soll einfach funktionieren. Das Programmieren ist ja auch schon schwer genug.

In diesem Fall: Daumen hoch an die Entwickler von ArduIDE. Schöne IDE und sie funktioniert sogar!

//Update vom 8.3.2015:
Nachdem ich gestern den ganzen Tag mit der IDE gearbeitet habe, gibt es doch noch ein paar Nachteile. Wenn man auf Hochladen (Upload) klickt wäre es schön, wenn er automatisch in die Ausgabe springen würde. Denn manchmal klappt das Hochladen einfach nicht, weil vielleicht die USB Kommunikation wieder auf einen anderen Port gewechselt hat. Oder es liegt ein Fehler im Code vor.
Und die Autocompletion fehlt immer noch. Allerdings gefällt mir die IDE trotzdem sehr gut. Der Code wird relativ gut dargestellt und vor allem auf schwarzem Hintergrund. Da lässt es sich einfach gut lesen und bearbeiten. Wenn der Editor noch mit der Zeit erweitert wird, könnte es noch richtig gut werden. Ich kann den ArduIDE aber weiterhin empfehlen. Mit 1.0.5 von Arduino funktioniert es richtig gut.

Einen (einfachen) Würfelgenerator mit Arduino bauen

Für ein Baumhausprojekt soll ich mit einigen anderen Leuten den Pfadfinder Kids etwas von Mikrocontrollern beibringen. Dazu machen wir natürlich erstmal die Standardbeispiele. LED ein und ausschalten, eine kleine Ampel und andere Dinge.
Da ich mich mit einem anderen ITler zusammen gehockt habe um etwas vorzubereiten war uns langweilig und wir wollten mal etwas eigenständiges entwickeln. Die 7 Segment Anzeige kennt ja jeder, der noch eine alten Radiowecker hat. Das tolle dabei: Man kann jeden einzelnen Strich ansteuern. Also haben wir das einfach mal gemacht und wollten einen Würfel bauen, der per Knopfdruck "zufällig" eine Zahl zwischen 1 und 6 anzeigt. Quasi die Nerd Variante für Leute, die gerne Würfelspiele spielen. :)

Das Ganze hat uns anfangs erstmal Fragen an den Kopf geworfen. Als blutiger Anfänger im Arduino Bereich könnte man ja denken, dass einfach alles in setup() und loop() untergebracht werden. Also definieren für Setup einen Anfangszustand und im loop dann die Ansteuerung vom Würfel und den Zahlen. Das fiese ist: Alles was in loop() steht wird immer von oben bis unten ausgeführt. Wenn ich dort also den Zustand des Druckknopfes abfrage wird danach trotzdem die Zufallsfunktion abgefragt. Deshalb hat der Button keine Bedeutung mehr.

Also lagern wir die Switch Anweisung mit den ganzen Zahlen in einen eigene Funktion aus und rufen diese dann nur noch auf loop() aus. Wenn man dann noch den Zustand vom Button richtig abfrägt (also beispielsweise anfangs mal den Zustand mit Seriel.println() ausliest) kann die if() Funktion auch greifen.
Unter Arduino gibt es nicht wirklich guten Zufall. Es lohnt sich aber den Zufall mit randomSeed() pseudomäßig zu verbessern. Dann kommt auch mal statt immer nur 1, 2, 3, 5 auch mal 4, 6 zum Vorschein. Mit random() wird dann der Zufall erzeugt.

Das Ganze funktioniert relativ gut. Wenn man noch die Muse hätte und ein kleines Gehäuse und einen kleinen Teensy oder arduino mini verwenden würde, hätte man einen elektronischen Würfel. Das wäre ein netter Gag für zwischendurch.

Die Sprache für Arduino ist ja hauptsächlich C und C++. Das hab ich das letzte Mal in der Berufschule gelernt und programmiert. Aber dieser Code ist mir dann doch relativ leicht gefallen. Natürlich ist es immer sinnvoll auch ein bisschen Literatur über die Bauteile zu haben. Anfangs haben wir es zusammen ausprobiert, später hab ich es alleine noch mit den Knopf hinprobiert und den Code optimiert, damit er besseren Zufall generiert und auch wirklich alle 6 Zahlen anzeigen kann. Das random(1,6) hat nämlich nicht funktioniert. Dann nimmt er nur Zahlen von 1 bis 5. Deshalb muss immer max+1 sein. Also in diesem Fall 7.
Es ist eine gute Kombination aus Anfängerbeispielen (Druckknöpfe, Werte auslesen, 7 Segment Anzeige). Und man muss etwas Verständnis von Programmiersprachen mitbringen. Ich hab in den letzten Jahren hauptsächlich VB.NET Programme geschrieben. Aber auch dort ist es ja ähnlich. Man hat Funktionen die man mit Inhalt füttern kannn und bekommt hinterher wieder etwas zurück. Der einzige Unterschied zwischen Rechnern und dem Arduino ist: Das Fehlen eines grafischen User Interfaces. Doch das macht genau den Reiz aus, man kann wieder neue Dinge überlegen. Eine LED als Status oder ein Button als Eingabe Taste. Und man muss wieder diese ; setzen, sonst meckert der Compiler. äöü in Variablen Namen mag der Compiler auch nicht. Das hab ich erst gestern wieder gemerkt, als wir die Ampelschaltung nachgebaut haben. :) Ich hätte es ja noch wissen können, aber es macht einfach Spaß Fehler zu machen und dann hinterher die Hand an die Stirn zu klatschen!

Anbei noch der Code mit Kommentaren zum Nachbauen.

//Programm um per Knopfdruck eine Zahl zwischen 1 und 6 zu bekommen.
//Die Zahl muss explizit an eine eigene Funktion übergeben werden.
//Andernfalls läuft der Controller andauernd alle Zahlen durch und ignoriert
//den Zustand des Buttons.

//Ersteller: Daniel Pfeil und Tobias Aichele
//Datum: 31.01.2015

//Button muss auf GND und 5V angeschlossen werden.
//Zwischen Button und 5V muss ein 10k Widerstand rein.
//Button auf Pin 1

//7Segment Anzeige
//oben (links nach rechts)
// 10 9 8 7 6
// Pin 8 mit 220 Widerstand auf GND
// 7Segment Pin --> Arduino
// 10 --> 11
// 9 --> 10
// 7 --> 8
// 6 --> 7
//
// unten (links nach rechts)
// 1 2 3 4 5
// Pin 3 bleibt leer
// 7Segment Pin --> Arduino
// 1 --> 2
// 2 --> 3
// 4 --> 5
// 5 --> 6

//Pins der 7 Segment Anzeige
int a=8;
int b=7;
int c=5;
int d=3;
int e=2;
int f=10;
int g=11;
int dp=6;

//Pin vom Druckknopf
int pinButton=1;

void randomNumber(int number)
{
  switch (number)
  {
    case 1:
    digitalWrite(a,LOW);
    digitalWrite(b,HIGH);
    digitalWrite(c,HIGH);
    digitalWrite(d,LOW);
    digitalWrite(e,LOW);
    digitalWrite(f,LOW);
    digitalWrite(g,LOW);
    digitalWrite(dp,LOW);
    break;
       
    case 2:
    digitalWrite(a,HIGH);
    digitalWrite(b,HIGH);
    digitalWrite(c,LOW);
    digitalWrite(d,HIGH);
    digitalWrite(e,HIGH);
    digitalWrite(f,LOW);
    digitalWrite(g,HIGH);
    digitalWrite(dp,LOW);
    break;
       
    case 3:
    digitalWrite(a,HIGH);
    digitalWrite(b,HIGH);
    digitalWrite(c,HIGH);
    digitalWrite(d,HIGH);
    digitalWrite(e,LOW);
    digitalWrite(f,LOW);
    digitalWrite(g,HIGH);
    digitalWrite(dp,LOW);
    break;
       
    case 4:
    digitalWrite(a,LOW);
    digitalWrite(b,HIGH);
    digitalWrite(c,HIGH);
    digitalWrite(d,LOW);
    digitalWrite(e,LOW);
    digitalWrite(f,HIGH);
    digitalWrite(g,HIGH);
    digitalWrite(dp,LOW);
    break;
       
    case 5:
    digitalWrite(a,HIGH);
    digitalWrite(b,LOW);
    digitalWrite(c,HIGH);
    digitalWrite(d,HIGH);
    digitalWrite(e,LOW);
    digitalWrite(f,HIGH);
    digitalWrite(g,HIGH);
    digitalWrite(dp,LOW);
    break;
       
    case 6:
    digitalWrite(a,HIGH);
    digitalWrite(b,LOW);
    digitalWrite(c,HIGH);
    digitalWrite(d,HIGH);
    digitalWrite(e,HIGH);
    digitalWrite(f,HIGH);
    digitalWrite(g,HIGH);
    digitalWrite(dp,LOW);
    break;
  } //Ende switch
} //Ende setup()

void setup()
{
  digitalWrite(a,LOW);
  digitalWrite(b,LOW);
  digitalWrite(c,HIGH);
  digitalWrite(d,LOW);
  digitalWrite(e,HIGH);
  digitalWrite(f,LOW);
  digitalWrite(g,LOW);
  digitalWrite(dp,LOW);
  pinMode(pinButton, INPUT);
  randomSeed(analogRead(0)); //Anlog Pin 0 ist nicht angeschlossen
  //Generiert etwas besseren Zufall
}

//Variablen für loop()
int zufall;
int buttonstate = 0;

void loop()
{
  buttonstate = digitalRead(pinButton);
 // Serial.println(buttonstate);

    if (buttonstate == LOW)
    { 
    zufall = random (1,7); //min: 1 ; max: 7-1 =6
    randomNumber(zufall);
    delay(500);
    }
} //Ende loop
//Programm fertig.

//Falls man alle 6 Zahlen hintereinander ausgeben möchte:
//  //Gebe alle Zahlen von 1 bis 6 aus.
//Delay macht Sinn um eine kurze Pause zwischen den einzelnen Zahlen zu haben.
//
//delay(500);
//  
////   case 1:
//digitalWrite(a,LOW);
//digitalWrite(b,HIGH);
//digitalWrite(c,HIGH);
//digitalWrite(d,LOW);
//digitalWrite(e,LOW);
//digitalWrite(f,LOW);
//digitalWrite(g,LOW);
//digitalWrite(dp,LOW);
//
//delay(500);
//
////   case 2:
//digitalWrite(a,HIGH);
//digitalWrite(b,HIGH);
//digitalWrite(c,LOW);
//digitalWrite(d,HIGH);
//digitalWrite(e,HIGH);
//digitalWrite(f,LOW);
//digitalWrite(g,HIGH);
//digitalWrite(dp,LOW);
//
//delay(500);
//
////   case 3:
//digitalWrite(a,HIGH);
//digitalWrite(b,HIGH);
//digitalWrite(c,HIGH);
//digitalWrite(d,HIGH);
//digitalWrite(e,LOW);
//digitalWrite(f,LOW);
//digitalWrite(g,HIGH);
//digitalWrite(dp,LOW);
//
//delay(500);
//
////   case 4:
//digitalWrite(a,LOW);
//digitalWrite(b,HIGH);
//digitalWrite(c,HIGH);
//digitalWrite(d,LOW);
//digitalWrite(e,LOW);
//digitalWrite(f,HIGH);
//digitalWrite(g,HIGH);
//digitalWrite(dp,LOW);
//
//delay(500);
//
////   case 5:
//digitalWrite(a,HIGH);
//digitalWrite(b,LOW);
//digitalWrite(c,HIGH);
//digitalWrite(d,HIGH);
//digitalWrite(e,LOW);
//digitalWrite(f,HIGH);
//digitalWrite(g,HIGH);
//digitalWrite(dp,LOW);
//
//delay(500);
//
////   case 6:
//digitalWrite(a,HIGH);
//digitalWrite(b,LOW);
//digitalWrite(c,HIGH);
//digitalWrite(d,HIGH);
//digitalWrite(e,HIGH);
//digitalWrite(f,HIGH);
//digitalWrite(g,HIGH);
//digitalWrite(dp,LOW);
//  
//delay(2000);