Arduino mit dem Smartphone steuern

Über den Beitrag

Im letzten Beitrag hatte ich gezeigt, wie man Bluetooth Module konfigurieren und für die Kommunikation von Arduino zu Arduino nutzen kann. In diesem Beitrag geht es nun um das spannende Thema wie man den Arduino mit dem Smartphone steuern kann. Man kann sehr leicht sogar eine Sprachsteuerung realisieren.

Der Beitrag ist in folgende Abschnitte gegliedert:

Ardroid – eine fertige Lösung

Es gibt eine Reihe von Apps mit denen man seinen Arduino recht bequem ansteuern kann. Die zugehörigen Sketche werden mitgeliefert und müssen oder können meist noch ein wenig angepasst werden. Als Beispiel stelle ich die Ardroid App vor, die man sich bei Google Play besorgen kann. Die App kann die Arduino Pins digital oder analog steuern und Text senden bzw. empfangen:

Arduino mit dem Smartphone steuern - Ardroid App
Die drei Bildschirmansichten von Ardroid

Vorbereitungen

Auf der Arduinoseite verwende ich ein HC-05 Bluetooth Modul, welches als Slave konfiguriert sein muss. Die Default-Baudrate am HC-05 ist 38400. Entsprechend muss man die Baudrate im Sketch und am seriellen Monitor anpassen. Oder man ändert die Baudrate des HC-05 wie in meinem vorherigen Beitrag beschrieben.

Da ich ein bequemer Mensch bin, habe ich die Ardroid App mit nur zwei LEDs an Pin 5 und 6 getestet. Die Schaltung dazu sieht so aus: 

Schaltung für

Den Spannungsteiler (1 kΩ / 2 k) habe ich der Korrektheit wegen eingezeichnet, denn der RX-Pin am HC-05 verträgt offiziell nur 3.3 V.  Bisher habe ich das allerdings konsequent ignoriert und habe mit 5 V noch nie Probleme bekommen.

Die 3.3 V an A0 dienen lediglich dazu an diesem Eingang einen definierten Wert auslesen zu können.  

Das Pairing des HC-05 mit dem Smartphone funktioniert wie mit jedem anderen Bluetooth Gerät. Einmalig muss der Pin (Voreinstellung: 1234) eingegeben werden. Dann kann man sich in der Ardroid App verbinden (Einstellungen -> Paired Devices). 

Der Ardroid Sketch

Auf Google Play (oder hier) erhält man über einen Link den zugehörigen Sketch. Man muss dort nur die Baudrate anpassen, wenn diese von 9600 abweicht.  Beim Hochladen des Sketches bekommt Ihr wahrscheinlich eine Fehlermeldung, wenn der HC-05 schon am RX des Arduinos angeschlossen ist. Trennen beim Hochladen, dann geht es. Und so sieht der mitgelieferte Sketch aus:

/*
 PROJECT: Ardroid
 CODED BY: Anurag Goel
 PUBLIC Licence Free To Modify
*/

#define START_CMD_CHAR '*'
#define END_CMD_CHAR '#'
#define DIV_CMD_CHAR '|'
#define CMD_DIGITALWRITE 10
#define CMD_ANALOGWRITE 11
#define CMD_TEXT 12
#define CMD_READ_ARDROID 13
#define MAX_COMMAND 20  
#define MIN_COMMAND 10  
#define IN_STRING_LENGHT 40
#define MAX_ANALOGWRITE 255
#define PIN_HIGH 3
#define PIN_LOW 2

String inText;

void setup() {
  Serial.begin(38400);
  Serial.println("Ardroid By : Anurag Goel");
  Serial.flush();
}

void loop()
{
  Serial.flush();
  int ard_command = 0;
  int pin_num = 0;
  int pin_value = 0;

  char get_char = ' ';  //read serial

  // wait for incoming data
  if (Serial.available() < 1) return; // if serial empty, return to loop().

  // parse incoming command start flag 
  get_char = Serial.read();
  if (get_char != START_CMD_CHAR) return; // if no command start flag, return to loop().

  // parse incoming command type
  ard_command = Serial.parseInt(); // read the command
  // parse incoming pin# and value  
  pin_num = Serial.parseInt(); // read the pin
  pin_value = Serial.parseInt();  // read the value
  // 1) GET TEXT COMMAND FROM ARDROID
  if (ard_command == CMD_TEXT){   
    inText =""; //clears variable for new input   
    while (Serial.available())  {
   char c = Serial.read();
  
     //gets one byte from serial buffer
      delay(5);
      if (c == END_CMD_CHAR) { // if we the complete string has been read
        // add your code here
        Serial.println(inText);
        break;
      }              
      else {
        if (c !=  DIV_CMD_CHAR) {
          inText += c; 
          delay(5);
        }
      }
    }
  }

  // 2) GET digitalWrite DATA FROM ARDROID
  if (ard_command == CMD_DIGITALWRITE){  
    if (pin_value == PIN_LOW) pin_value = LOW;
    else if (pin_value == PIN_HIGH) pin_value = HIGH;
    else return; // error in pin value. return. 
    set_digitalwrite( pin_num,  pin_value);  
    return;  // return from start of loop()
  }

  // 3) GET analogWrite DATA FROM ARDROID
  if (ard_command == CMD_ANALOGWRITE) {  
    analogWrite(  pin_num, pin_value ); 
    // add your code here
    return;  // Done. return to loop();
  }

  // 4) SEND DATA TO ARDROID
  if (ard_command == CMD_READ_ARDROID) { 
//    char send_to_android[] = "Place your text here." ;
//    Serial.println(send_to_android);   // Example: Sending text
    Serial.print(" Analog 0 = "); 
    Serial.println(analogRead(A0));  // Example: Read and send Analog pin value to Arduino
    return;  // Done. return to loop();
  }
}

// 2a) select the requested pin# for DigitalWrite action
void set_digitalwrite(int pin_num, int pin_value)
{
  switch (pin_num) {
  case 13:
    pinMode(13, OUTPUT);
    digitalWrite(13, pin_value);  
    // add your code here      
    break;
  case 12:
    pinMode(12, OUTPUT);
    digitalWrite(12, pin_value);   
    // add your code here       
    break;
  case 11:
    pinMode(11, OUTPUT);
    digitalWrite(11, pin_value);         
    // add your code here 
    break;
  case 10:
    pinMode(10, OUTPUT);
    digitalWrite(10, pin_value);         
    // add your code here 
    break;
  case 9:
    pinMode(9, OUTPUT);
    digitalWrite(9, pin_value);         
    // add your code here 
    break;
  case 8:
    pinMode(8, OUTPUT);
    digitalWrite(8, pin_value);         
    // add your code here 
    break;
  case 7:
    pinMode(7, OUTPUT);
    digitalWrite(7, pin_value);         
    // add your code here 
    break;
  case 6:
    pinMode(6, OUTPUT);
    digitalWrite(6, pin_value);         
    // add your code here 
    break;
  case 5:
    pinMode(5, OUTPUT);
    digitalWrite(5, pin_value); 
    // add your code here       
    break;
  case 4:
    pinMode(4, OUTPUT);
    digitalWrite(4, pin_value);         
    // add your code here 
    break;
  case 3:
    pinMode(3, OUTPUT);
    digitalWrite(3, pin_value);         
    // add your code here 
    break;
  case 2:
    pinMode(2, OUTPUT);
    digitalWrite(2, pin_value); 
    // add your code here       
    break;      
  
  } 
}

Die Kommandos aus der Ardroid App erreichen den Arduino als Zeichenkette über den seriellen Eingang. Die Zeichenkette startet mit einem Starttag („*“). Im weiteren Verlauf enthält die Zeichenkette drei Zahlen, die den Befehl, die Pinnummer und den Wert kodieren. Die Zahlen werden über parseInt() Befehle aus der Zeichenkette extrahiert, was eine sehr schlanke Methode ist.

Es gibt vier Kommandos: eins für digitalWrite, eins für analogWrite, eins zum Senden von Text und eines quasi zur freien Verfügung (CMD_READ_ARDROID), welches hier verwendet wird, um A0 mit einem analogRead auszulesen. 

Die LEDs zu schalten und zu dimmen (=> Abschnitte „DIGITAL“ und „ANALOG“ in der Ardroid App) hat sehr gut funktioniert. Der Abschnitt  „DATA“ ist anscheinend noch nicht ganz ausgereift. Man muss dem zu versendenden Text ein *irgendeine_Zahl*irgendeine_Zahl voranstellen. Also z.B.:

*1*1Text    ergibt auf dem seriellen Monitor die Ausgabe „Text“

Die Funktion zum Auslesen von A0 wird anscheinend gar nicht durch die App erreicht. Das kann man „reparieren“, da kommen wir gleich zu. Außerdem dient dieser Teil des Beitrages sowieso vor allem als Einstieg in die Entwicklung einer eigenen App in der wir dann die volle Kontrolle haben.  

Bluetooth Terminal

Im nächsten Schritt lasse ich die Arduinoseite mit dem Ardroid Sketch unverändert, aber ersetze die Ardroid App durch die App Bluetooth Terminal. Mit dieser sehr einfachen App kann man gut nachvollziehen, wie die Ardroid App hinter den Kulissen arbeitet. Natürlich muss zunächst auch in dieser App eine Verbindung mit dem HC-05 hergestellt werden (Einstellung -> Connect a device – Secure oder -Insecure). Um die Leerzeilen bei der Ausgabe im seriellen Monitor loszuwerden, kann man  in den Einstellungen der App im Setup „Append newline (\r\n)“ deaktivieren.

Um nun zum Beispiel die LED an Pin 5 einzuschalten, sendet man:

*10bla5blabla3 oder einfacher: *10*5*3  (Kodierung: siehe #define Vereinbarungen im Sketch)

Wichtig ist das erste Zeichen „*“ und dass drei Zahlen enthalten sind. Die Zeichen dazwischen werden ignoriert. Um die LED an Pin 6 zum schwachen Leuchten zu bringen, sendet man zum Beispiel:

*11*6*30  

Um Text auf den seriellen Monitor zu beamen:

*12*9*9Gruß vom Smartphone#

Man muss also auch hier drei Zahlen eingeben, da der Sketch drei parseInt() Befehle verwendet. Allerdings ist in diesem Fall egal, welches die hinteren beiden Zahlen sind. Wiederum wichtig ist das abschließende Hashzeichen, da das die Abbruchbedingung für das Auslesen der Zeichenkette ist.

Für das Auslösen der analogRead Funktion ist wiederum ein einfaches

*13

ausreichend. 

die Bluetooth Terminal App
Bluetooth Terminal App in Aktion

Ardroid Sketch „reparieren“

Mit diesem Wissen lässt sich auch der Ardroid Sketch modifizieren, so dass man im Bereich DATA in der Ardroid App sowohl Texte verschicken wie auch A0 auslesen kann. Oder man fügt noch andere Funktionen ein. Ihr könnt den (schnell und schmutzig) modifizierten Sketch „Ardroid_repaired“ hier herunterladen. Bei Verwendung dieses Sketches setzt Ihr im Appbereich DATA ein *1*1 vor den zu versendenden Text oder ein *2*1 wenn Ihr A0 auslesen wollt. Ich will den Beitrag nicht zu lang werden lassen, deswegen bespreche ich das nicht im Detail. Bei Fragen: fragen!

Steuerung über den PC

Man die Steuerung auch über den PC vornehmen. Dafür gibt es z.B. das kostenlose Programm Bluetooth Serial Terminal, dass der zuvor besprochenen Smartphone App sehr ähnlich ist. Man braucht einen Bluetooth Adapter, muss diesen in den Windows Einstellungen aktivieren, das Pairing vornehmen und schließlich im Programm den PC mit dem Modul verbinden. Der Rest funktioniert wie oben für’s Smartphone beschrieben. 

Bluetooth Serial Terminal in Aktion.

Eine App mit MIT App Inventor entwickeln

Vorbereitung auf der Arduinoseite

Ich habe den Ardroid Sketch für die Entwicklung einer eigenen App noch etwas modifiziert, verkürzt und ihm den Namen „bt_receiver.ino“ gegeben. Unter anderem habe ich geändert:

  • SoftwareSerial ersetzt Hardware Serial (vermeidet oben beschriebene Upload Probleme)
  • die Kommandos habe ich als enum definiert
  • das Auslesen einer Textnachricht erfolgt über ein einfaches readString()
  • die lange case Konstruktion habe ich entfernt
  •  „High“ und „Low“ Anweisungen werden direkt übermittelt und nicht kodiert

Der Sketch sollte ansonsten selbsterklärend sein. Die zu übermittelnden Zeichenketten sehen damit ein wenig anders aus, hier ein paar Beispiele: 

*1*5*1    –>    Pin 5 HIGH

*2*6*100    –>    analogWrite PIN 6 mit Wert 100 

*3Hallo    –>    gibt „Hallo“ auf dem seriellen Monitor aus

*4    –>    analogRead von PIN 0 und Senden des Ergebnisses 

Zu beachten ist noch, dass die Baudrate am seriellen Monitor auf 9600 gestellt werden muss und dass RX und TX am Arduino jetzt Pin 10 und 11 sind. 

Schaltung des Arduino bei Verwendung von bt_receiver.ino
Arduino mit dem Smartphone steuern – mit SoftwareSerial
#include <SoftwareSerial.h>
#define START_CMD_CHAR '*'

SoftwareSerial mySerial(10, 11);
enum command {DIGITALWRITE=1, ANALOGWRITE, DISPL_TXT_MSG, EXEC_TASK};

void setup() {
  Serial.begin(9600);
  mySerial.begin(38400);
  Serial.println("Bluetooth Empfänger bereit");
}

void loop(){
  
  if(mySerial.available()){
    analyzeMsg();
  }
}

void analyzeMsg(){
  int cmdType;
  int pinNum, pinValue = 0;
  char getChar = ' ';  //read serial

  getChar = mySerial.read();
  if(getChar != START_CMD_CHAR) return; 
  cmdType = mySerial.parseInt(); // read the command
  
  if(cmdType==DIGITALWRITE){
    pinNum = mySerial.parseInt();
    pinValue = mySerial.parseInt();
    pinMode(pinNum, OUTPUT);
    digitalWrite(pinNum, pinValue);
  }

  if(cmdType==ANALOGWRITE){
    pinNum = mySerial.parseInt();
    pinValue = mySerial.parseInt();
    pinMode(pinNum, OUTPUT);
    analogWrite(pinNum, pinValue);
  }
  
  if(cmdType==DISPL_TXT_MSG){
    String msg = mySerial.readString();
    Serial.println(msg);
  }

  if(cmdType==EXEC_TASK){
    execTask();
  }
}      
    
void execTask(){
  int value = analogRead(A0);
  mySerial.print("Analog 0 = ");
  mySerial.println(value);
} 

Smartphone Apps schreiben

Smartphone Apps zu programmieren ist eigentlich nichts, was man mal so eben nebenbei erlernen kann. Wer richtig tief in dieses Thema einsteigen möchte, sollte die Programmiersprache Java erlernen und sich mit Entwicklungsumgebungen wie Eclipse oder Android Studio beschäftigen. Die gute Nachricht ist, dass es eine einfache, für unsere Zwecke völlig ausreichende Alternative gibt und die heißt MIT App Inventor. Wenn Ihr diesem Link folgt, bekommt Ihr viele Informationen, wer hinter diesem Projekt steht, wie es funktioniert, welche Tutorials es gibt (als Einstieg sehr empfehlenswert) und vieles mehr. Eine Schritt-für-Schritt Anleitung würde den Rahmen dieses Beitrags sprengen, ich werde aber versuchen Euch die wesentlichen Punkte zu vermitteln. 

Das Ziel: eine eigene App zur Arduino Steuerung

Ich fange einfach mal mit dem Ergebnis an um hoffentlich euer Interesse wecken. Ich habe eine kleine App mit dem Namen „Arduino BT Control“ entwickelt, die alle Funktionen der Ardroid App beinhaltet und darüber hinaus eine Sprachsteuerung (!) hat. Da ich – wie schon erwähnt – bequem bin, habe ich mich bzgl. der Pinsteuerung auf zwei Pins beschränkt. Ihr könnt das aber problemlos erweitern. Also, so sieht die App aus: 

Arduino mit dem Smartphone steuern - Die Oberfläche der Arduino BT Control App
Arduino BT Control – eine eigene App

Der große Button „Connect HC-05“ stellt die Verbindung zum HC-05 her. „Analog Control“ und „Digital Control“ erklärt sich von selbst. „Talk2Me“ startet die Sprachsteuerung, z.B. kann man eine LED mit einem gesprochenen „Pin fünf an“ anschalten. „SendTxt“ sendet Text an den seriellen Monitor, „Analogread“ wertet den Pin A0 aus.

Auf der Arduinoseite wird wie schon erwähnt der bt_receiver.ino Sketch von weiter oben verwendet.  

Wie funktioniert MIT App Inventor?

Zunächst einmal handelt es sich bei MIT App Inventor um eine Online Lösung, d.h. es ist keine Installation eines Programmes erforderlich. Man schreibt bei der Appentwicklung keine einzige Programmzeile, sondern konstruiert Programmblöcke visuell aus vorgefertigten Einzelteilen. Wer schon mal mit Scratch gearbeitet hat, der wird sich hier schnell reinfinden.

Besonders cool ist, dass man die Entstehung seiner Apps direkt in Echtzeit auf dem Smartphone verfolgen kann. Das betrifft sowohl das Design wie auch die Funktionalität. Es ist nicht notwendig zwischendurch Code zu kompilieren und sich apk Dateien auf das Smartphone zu beamen. Das macht man erst ganz am Ende, wenn man mit seinem Ergebnis zufrieden ist und die App unabhängig von der Entwicklungsumgebung laufen soll.

Um das Smartphone mit MIT App Inventor zu verbinden, muss man zunächst die App MIT AI2 Companion installieren. MIT App Inventor stellt dann wahlweise einen Zahlen- oder QR-Code für die Verbindung zur Verfügung. Sehr bequem! Bei mir wurde allerdings mit Edge keine Verbindung aufgebaut, mit Chrome hingegen kein Problem. 

Unter diesem Link erreicht ihr die Programmieroberfläche, zu der man sich mit seinem Google Konto anmeldet. 

Der Designer Bildschirm

Wie erwähnt kann ich hier keine Schritt-für-Schritt Anleitung bieten, sondern nur das Konzept erklären. Im wesentlichen besteht die App Entwicklung aus zwei Schritten, nämlich dem Design und der Definition der Funktionen dahinter. Dazu gibt es zwei Bildschirme zwischen denen man wechseln kann und zwar „Designer“ und „Blocks“.  Der Designer Bildschirm sieht für die Arduino BT Control App so aus:

MIT App Inventor - Designer Ansicht
Die Designer Ansicht

Auf der linken Seite hat man die Palette mit den unterschiedlichen Elementen, die sich einfügen lassen. Im Untermenü „User Interface“ sind das Buttons, Checkboxen, Slider, usw. Unter „Layout“ findet man Elemente wie z.B. Horizontal und Vertical Arrangements, die zur Abstandshaltung und Anordnung dienen. Bluetooth findet sich unter Connectivity. Schaut einfach mal durch. 

Das Fenster „Components“ gibt die Struktur der Komponenten wieder. Hier kann man Komponenten auch unbenennen, was absolut ratsam ist, um nicht den Überblick zu verlieren. „Pin5_Slider“ ergibt z.B. mehr Sinn als das voreinstellte „Slider1“. 

Im Fenster „Properties“ kann man die Eigenschaften der Komponenten festlegen, z.B. Form, Farbe oder im Falle der Slider welche Werte abgebildet werden. Für einen analogRead Slider wird man z.B. einen Bereich von 0 bis 255 angeben.  

Der Blocks Bildschirm

Die im Designer Bildschirm zusammengestellten Komponenten können zunächst nichts. Was sie unter welchen Bedingungen auslösen oder wie sie sich verändern sollen, wird im Blocks Bildschirm festgelegt: 

MIT App Inventor - Blocks Ansicht
Die Blocks Ansicht

Klickt man im Fenster „Blocks“ auf eine der Komponenten bekommt man eine Auswahl verschiedener Blöcke zur Auswahl. Den ausgewählten Block zieht man in das Viewer Fenster Fenster wo er frei verschiebbar ist. Da zum Beispiel ein Slider nur bestimmte Dinge kann, werden auch nur die entsprechenden Blöcke vorgeschlagen. Dadurch kann man recht intuitiv und schnell arbeiten. Zusätzlich gibt es unter „Built-In“ allgemeine Blöcke z.B. für Text, if-then-else Konstruktionen und vieles mehr. 

Eine weitere Hilfe ist, dass die Blöcke wie Puzzleteile geformt sind. Dadurch passen nur bestimmte Komponenten zusammen und alles muss abgeschlossen sein. Dadurch werden Syntaxfehler vermieden, auf die Logikfehler hingegen muss man natürlich selbst achtgeben. 

Die entwickelte App installieren

Zum Schluss kann man dann unter dem Menüpunkt „Build“ eine apk Datei generieren, die bequem über einen QR-Code auf das Smartphone transferiert werden kann.  

Das Projekt wird online gespeichert. Man kann es aber auch als „.aia“-Datei exportieren, auf dem PC speichern, mit anderen teilen und dann wieder importieren. Die „.aia“-Datei für die hier vorgestellte Arduino BT Control App könnt Ihr hier herunterladen und nach Lust und Laune anpassen. Alternativ findet Ihr das Projekt in der Gallerie von MIT App Inventor (Menüpunkt „Gallery“, Suchbegriff: Arduino_BT_Control). 

Nach einer kurzen Gewöhnungsphase ist man schnell mit MIT App Inventor vertraut. Ich finde das eine geniale Erfindung und hoffe ihr habt genauso viel Spaß damit wie ich. 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.