Android App Entwicklung: ESP Controller ansprechen #1

Auf dem Markt gibt es diverse ESP Controller, der Vorteil eines solchen Microcontrollers ist es, das dieser über analoge & digitale Ein/Ausgänge verfügt und als Schnittstelle WiFi besitzt.

ESP12
ESP12

In diesem Tutorial möchte ich erläutern wie man für diese Microcontroller eine Android App entwickelt und verschiedene Sensoren / Aktoren ansprechen oder auch auswerten kann.

Solltest du im nachfolgenden Tutorial Fehler finden, oder Fragen haben, so kannst du dich gerne per E-Mail oder über das Kontaktformular an mich wenden.

Voraussetzung

Ich setze in diesem Tutorial voraus dass, das Tool Android Studio installiert, konfiguriert und lauffähig ist.

Wie man Android Studio installiert habe ich im Tutorial https://draeger-it.blog/android-app-mit-einer-mysql-datenbank-verbinden-16-01-2016/#Entwicklungsumgebung ausführlich erläutert.

leeres Projekt zum Mitmachen

Am Anfang möchte ich gerne ein leeres Projekt zum Download anbieten.

Dieses Projekt kann in Android Studio importiert werden und für die nächsten Schritte weiter ausgebaut werden.

Kommunikation zwischen den Geräten

Zuerst möchte ich meine Lösung für die Kommunikation zwischen den Geräten erläutern.

Sicherlich gibt es mehrere Lösung für dieses Problem, jedoch habe ich mit dieser Lösung sehr gute Erfahrungen gesammelt.

Das Android Gerät sendet einen Request an den ESP in dem dieser eine HTTP Adresse aufruft. An diese Adresse können HTTP GET Parameter angehängt und vom ESP ausgewertet werden. Als Ergebnis sendet der ESP ein Respond mit einem JSON String.

Kommunikation zwischen Android & ESP
Kommunikation zwischen Android & ESP

Der Vorteil an einem JSON ist, das es ein kompaktes Datenformat in einer leicht lesbaren Sprache (in diesem Fall deutsch) ist.

Wenn du mehr über das JSON Format erfahren möchtest so empfehle ich dir den Wikipedia Artikel

Seite „JavaScript Object Notation“. In: Wikipedia, Die freie Enzyklopädie. Bearbeitungsstand: 11. Januar 2019, 11:21 UTC. URL: https://de.wikipedia.org/w/index.php?title=JavaScript_Object_Notation&oldid=184617074 (Abgerufen: 16. Januar 2019, 14:28 UTC)

Layout 

Für dieses Tutorial nutze ich ein einfaches TableLayout mit 4 TableRows.
Die erste Zeile enthält ein EditText  für die IP Adresse, die zweite Zeile ein EditText für den Text welcher abgesendet werden soll und die dritte Zeile enthält eine Schaltfläche für das ausführen der Aktion zum absenden des Textes. Die letzte Zeile enthält nur eine einfache TextView für das Anzeigen des empfangenen Ergebnisses.

ESPTutorialApp - Layout
ESPTutorialApp – Layout

Das Layout für das Hauptfenster wird in der Datei „activity_main.xml“ definiert. 

Damit wir die Komponenten später verwenden können legen wir uns jeweils ein Feld in der Klasse „MainActivity.java“ an. Zusätzlich müssen diesen Feldern dann noch eine „Verbindung“ zur Komponente mit „findViewById“ in der Funktion „onCreate“ hergestellt werden.

Da wir „nur“ eine Handvoll komponenten für dieses Beispiel verwenden ersetze ich nicht die IDs durch sprechende Bezeichnungen. Jedoch empfehle ich wie bei dem Eingabefeld „ipAdressEditText“ eine sprechende Bezeichnung zu wählen.

Berechtigungen der App setzen

Damit man mit einem Netzwerk kommunizieren kann, muss man der App die Berechtigung zum Zugriff auf das Internet geben. Der nachfolgende Text wird in der Datei „AndroidManifest.xml“ eingetragen.

Damit wir zusätzlich den Status abfragen können ob das Gerät mit einem Netzwerk verbunden ist, müssen wir die Berechtigung 

hinzufügen.

Wenn die AndroidApp später über den GooglePlay Store ausgeliefert wird, muss der Benutzer diese Berechtigung manuell bestätigen.

Abfrage des Netzwerkstatus

Bevor wir ein Request an einen ESP Controller senden können benötigen wir eine Netzwerkverbindung. Diese baut das Handy/ Tablet in der Regel selber auf so das wir diese aus der App nutzen können. Jedoch kann es passieren das keine Netzwerverbindung besteht. Hier sollten wir den Benutzer mit einem einfachen Dialog darauf hinweisen. 

Wir holen uns also zuerst den „ConnectivityManager“ aus den SystemServices. Der Manager kann null sein also prüfen wir zusätzlich ob dieser null ist bevor wir uns die Informationen über das aktive Netzwerk auslesen.

Wenn das Gerät mit keinem Netzwerk verbunden ist so liefert die Methode „connectivityManager.getActiveNetworkInfo()“ null zurück d.h. auch hier müssen wir auf null prüfen bevor wir mit der Methode „isConnected“ prüfen können. Wenn keine Netzwerkverbindung besteht so wird ein Dialog angezeigt welcher den Titel „Fehlermeldung“ trägt und als Text „Es besteht keine Netzwerkverbindung!“ hat. Es wird für diesen Dialog nur eine Schaltfläche benötigt und beim betätigen wird der Dialog geschlossen.

Wenn kein WLAN aktiviert ist, wird also nun ein Dialog angezeigt. Nun muss der Benutzer die App verlassen und manuell das WLAN aktivieren.

Aktivieren der WLAN Verbindung aus der App

Hier können wir den Benutzer im Dialog unterstützen und die „negative Schaltfläche“ für das aktivieren des WLANs benutzen.

Wir holen uns zuerst wieder den „WifiManager“ aus den SystemServices und aktivieren dort das Wifi über die Methode „setWifiEnabled“.

Damit wir diese Funktion nutzen können müssen wir der App noch 2 zusätzliche Berechtigungen in der „AndroidManifest.xml“ geben.

"Fehlermeldung keine Netzwerkverbindung"
„Fehlermeldung keine Netzwerkverbindung“

Je nach Android Version und gewählten Theme kann die Farbe und das Layout abweichen.

Absenden eines Request

Nachdem wir nun die Vorbereitungen zum erfolgreichen absenden eines Request erstellt haben möchten wir eine URLConnection zu einem Gerät aufbauen.

Vorbereitungen

Damit wir den Text aus dem Textfeld mit dem Button absenden können müssen wir zunächst diesem eine Aktion zuweisen. Dazu setzen wir der Funktion „setOnClickListener“ das Interface „View.OnClickListener“ ein. 

Zusätzlich prüfen wir in der Methode, ob eine aktive Netzwerkverbindung besteht.

Alternativ könnten wir auch der Klasse „MainActivity“ das Interface „View.OnClickListener“ implementieren und somit die Funktion „onClick“. Das hätte den Vorteil das bei mehr als einen Button nur eine Funktion alles Regelt.

Wir rufen in der Funktion dann die weitere neue Funktion sendRequest auf, dieser Funktion übergeben wir den Text aus dem EditText.

Aufbauen einer asynchronen Verbindung

Die Verbindung zum ESP wird asynchron aufgebaut. Dieses macht man immer dann wenn man Daten an einen Empfänger sendet und nicht auf das Ergebnis warten möchte. Das Ergebnis wird dann abgearbeitet wenn dieses bereit steht. Wenn nach einer bestimmten Zeit keine Antwort kommt wir ein Timeout ausgelöst.

Wir benötigen zunächst eine interne Klasse welche die Abstrakte Klasse „AsyncTask“ erweitert. 

Und einen Konstruktor welchem wir die IPAdresse und den Text als Parameter übergeben können.

Mit dem einbinden der Abstrakten Klasse müssen wir mindestens die Methode „doBackground“ implementieren.

In dieser Methode senden wir unseren Text an den ESP.
Zuerst möchten wir eine einfache Begrüßung absenden und empfangen. Dazu senden wir einen Text an den ESP Controller.

Dazu bauen wir uns zuerst die Adresse zusammen, diese besteht aus

  • dem Protokoll „http“ (gefolgt von einem Doppelpunkt und zwei Slashes)
  • der IP Adresse des ESP Controllers,
  • dem Servlet welches angesprochen werden soll, in unserem Fall heißt dieses „greeting“
  • und dem Parameter

Möchte man mehrere Parameter anhängen so müssen diese mit einem „&“ getrennt werden. Dazu aber später mehr.

Da bei der Verbindung eine Exception auftreten kann muss diese abgefangen werden. Hier könnte man diese Fehlermeldung noch an die Oberfläche mit einem Dialog weitergeben. 

Als erstes erzeugen wir uns ein neues Feld vom Typ „String“ um die ggf. auftretende Fehlermeldung zu speichern.

Dieses Feld befüllen wir dann in dem Catch Block mit der Fehlermeldung:

Ich gebe zusätzlich den Stacktrace auf der Console aus. Die Fehlermeldung wird dann ausgewertet wenn das Ergebnis der Asyncronen Verbindung ausgewertet wird.

Wenn keine Fehlermeldung aufgetreten ist so wird von der URLConnection das Ergebnis gelesen.

Dieses Ergebnis geben wir dann in der Methode „doInBackground“ zurück, die Verarbeitung dieses Ergebnisses wird dann in der Methode „onPostExecute“ verarbeitet. 

Wir haben uns im Catch Block beim absenden uns eine ggf. auftretende Fehlermeldung gespeichert, nun prüfen wir also ob dieses Feld befüllt ist. Da das Feld initial mit „null“ belegt ist machen wir einen einfachen Null Check und prüfen zusätzlich ob das „result“ nicht leer ist. (Wir sollten ja ein JSON vom ESP Controller erhalten.) Wenn das Feld „errorMsg“ jedoch befüllt ist so zeigen wir die Fehlermeldung an.

Anzeigen der Fehlermeldung in einem Dialog

Die neue Methode baut dann die Fehlermeldung auf und zeigt diese an.

Sollte also nun zbsp. eine Verbindung nicht aufgebaut werden können, so wird eine Fehlermeldung angezeigt.

Fehlermeldung beim aufbau einer Verbindung zu einem Gerät
Fehlermeldung beim aufbau einer Verbindung zu einem Gerät

Sketch für den ESP Controller

Nachdem wir unsere AndroidApp geschrieben haben wollen wir uns nun dem ESP Controller widmen. Dieser muss den Request annehmen, verarbeiten und eine Antwort (Respond) an das Android Gerät senden.

Wir benötigen zunächst einen Microcontroller mit einem WiFi Chip, zumeist ist dieses ein ESP8266 oder ähnliches. Diese Microcontroller gibt es günstig bei ebay.de zu kaufen zbsp. den NodeMCU, WemosD1Mini.

Wemos D1 Mini mit ESP8266 Chip
Wemos D1 Mini mit ESP8266 Chip

Ich verwende in diesem Tutorial den WittyCloud , dieser Microcontroller verfügt neben den üblichen Ein/Ausgängen noch zusätzlich über einen Fotowiderstand und einem NeoPixel. 

Ausführen der App - Absenden eines Request an den WittyCloud
Ausführen der App – Absenden eines Request an den WittyCloud

Download

 

Review & Ausblick

Die erste Ausbaustufe ist geschafft und als nächstes folgt nun die Umwandlung des JSONs mit Hilfe von Google Gson. Und da der WittyCloud mit einem Sensor & einen Aktor daherkommt wollen wir diese verwenden und die Daten senden bzw. empfangen. D.h. den Fotowiderstand auslesen und dem NeoPixel einen Farbwert zuzuweisen.

 

 

Schreibe einen Kommentar

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