HTML5 Icon 10 Jahre Thailand 

Hausbeleuchtung mit dem Smartphone steuern

by Nudels


Posted on Mittwoch Juli 21, 2021 at 05:23PM in Technik - Steuern und Regeln


Die Hausbeleuchtung mit einer 5$-Hardware über das Smartphone steuern


Ich lebe in der thailändischen Provinz, das Klima ist tropisch und der Körper stellt sich automatisch auf einen bewegungsarmen Tagesablauf ein. Einen großen Teil der Tageszeit verbringen wir in unseren Aussenbereichen, besonders in den Morgen- und Abendstunden – mit Beleuchtung. Meine Hauselektik habe ich auf einen deutschen Standard umgebaut, das heißt unter anderem: Lichtschalter, und Steckdosen befindet sich immer dort, wo sie benötigt werden. Auf langen Wegen sind Wechselschalter notwendig – oder nicht ? Stop! Weitere Kabelinstallationen und Schalter brauche ich doch gar nicht, wenn ich das Licht mit meinem Smartphone schalten könnte. Das Gerät habe ich doch sowieso immer bei mir. Die Idee war geboren, und es folgt die Umsetzung.  




Unser Haus mit dem vorderen Aussenbereich. Hinten ist ein weiterer und der Weg dorthin geht durch 3 Räume.




Was brauche ich?


Damit ich nicht unverhältnismäßig mehr Zeit benötige, als für eine Kabelinstallation, lasse ich mich zunächst auf ein Prototypenkonzept ein, welches später komponentenweise auf einen Release-Status gehoben werden kann. Skalierbarkeit ist also die Devise. Es soll erstmal nur funktionieren.

Das Grobkonzept ist schnell entwickelt. Eine kostengünstige Micrcontroller-Alternative zum Industriestandard ist der Arduino. Ein Open-Source-Zwerg, der mit etwas Phantasie, leistungsstark fast auf Augenhöhe mit den Platzhirschen stehen kann. Weiter ist eine Smartphone-App erforderlich, die ich erstmal nur für Android-Endgeräte entwickeln werde.

Eine überschaubare Aufgabe, die in einem überschaubaren Zeitrahmen durchfürbar sein sollte. Ich nehme es vorweg – von der Idee bis zum ersten Schalten aller Beleuchtungen sind 2 Wochen vergangen.






Hier hängt schon das fertige Produkt in der 20 Baht-Käsebox:


1 - wichtig! Die Lichtleitungen kommen alle einzeln am Sicherungskasten an.


2 - Hier werden sie durch die Relais in Reihe zum Standard Schalter nochmal unterbrochen


3 - Ein ausgedientes Smartphonenetzteil als Stromversorgung





Die Stückliste:



    • Arduino Uno AMTEL MEGA328P 1 Stck
    • Wemos R1 D1 ESP8266 1 Stck
    • Tongling Relais 5V/250V 10A 3 Stck (optional auf n erweiterbar)
    • Display 1602A I²C 1 Stck
    • Breadboard 48pins 1 Stck
    • solderless Cables ausreichend
    • Widerstand 220Ohm 3 Stck

Als Netzteil nehme ich ein ausgemustertes Smartphoneladegerät. Das fertige Assembly wird in eine 20 Baht-Klarsicht-Käsebox mit M2-Schrauben montiert und dann in die Wand verschraubt. Der Prototyp wird zunächst für die Licht-Stromkreise unseres längsten Weges entwickelt, das sind 3. Er muss natürlich beliebig erweiterbar sein. Warum ich mich für ein weiteres Mikrocontroller-Board entschieden habe, ist eine Frage der Skaliebarkeit. Das Wemos-Board wird als Komunikations-Server programmiert. Es händelt die TCP/IP-Anfragen und verteilt sie auf einen Feld-Bus, der beliebig viele, z.B.: Uno-Boards bedient, die funktional abgegrenzte Aufgaben erledigen.






Es funktioniert ;-) Ein Display zeigt den Verbindungsstatus, letzte Aktionen ... etc. an.





Die Entwicklungsumgebungen


Vor 10 Jahren konnte man dieses Projekt noch vollständig mit der Eclipse-IDE abwickeln. Ich arbeite seit Ewigkeiten mit Eclipse und ich schätze es, meine Aufgaben in einer vertrauten Umgebung zu erledigen. Leider wird Android-Unterstüzung nicht mehr weiterentwickelt. Mit dem Sloeber-plugin läßt sich die Arduino-Entwicklung in Eclipse realisieren. Das Sloeber-plugin arbeitet sehr performant. Das ESP8266-Board muss in den Window-Preferences-Arduino-Third Party Index urls eingetragen werden: http://arduino.esp8266.com/stable/package_esp8266com_index.json und in Platform and Boards ausgewählt werden.



    • Eclipse-IDE (mit Sloeber-plugin)
    • Arduino-IDE (alternativ)
    • Android-Studio



Die Arduino-IDE hat keine Subversion-Schnittstelle. (kleine Anregung an die Entwickler). Ich erwähne es nur der Vollständigkeit: Subversion, oder ein anderes Produkt, als Tool für verteiltes Entwickeln und Versionskontrolle ist ein must have für Softwareprojekte. Warum benutze ich 3rd-Party-Boards? Die Antwort ist keine Frage des Preise, viel mehr eine Frage der schnellen Verfügbarkeit. Wie erwähnt, lebe ich in Thailand und eine Lieferung aus China ist in der Zollabwicklung ein Durchlaufposten, während die Lieferung eines Genuinen-Boards aus Europa ein Geduldsspiel ist.









Der Prototyp ist fertig - beachte die grünen LEDs auf der Platine.






Welche Voraussetzung sind zu erfüllen?


Um einen Mikrocontroller zu programmieren, ist es unbedingt erforderlich, zu verstehen, wie er funktioniert. Der Arduino kann in C oder C++ programmiert werden. Der interne Speicher ist sehr begrenzt. C++ ist eine Erweitrung von C und keine eigene Programmiersprache. Ich gebe also pure C den Vorzug. C-Programmierung ist sehr effizient, hat dafür aber auch diverse Fallstricke. Prüfe Dich selbst und revidiere die Begriffe: Heap, Stack, DataSegment und CodeSegment. Wenn Du alle 4 Begriffe genau erklären kannst und auch noch weißt, was Pointer und Adressoperatoren sind, wirst Du wenig Probleme mit der Programmiersprache C haben.
Ein Server läuft üblicherweise als Service- and Childs-Modell. Auf dem Arduino muss ich aber POSIX-Threads verwenden, oder ein eigenes Time-Slicing-Verfahren entwickeln, um das gleiche Verhalten zu erzeugen. Warum tue ich das? Der Arduino ist kein Rechner mit Betriebssystem, sondern schlicht ein Mikrocontroller mit einem winzigen Stück Firmware und dem Bootloader. Deshalb läuft nur genau ein Service auf ihm und das ist das main mit dem setup und dem loop aus der Arduino-IDE. Möchtest Du mehr, musst Du simmulieren. :-)



Der Android-Client kann in Java oder Kotlin programmiert werden. Aufgrund Jahrzehnte langer Erfahrung gebe ich natürlich Java den Vorzug. Es ist schon klar, dass in der Entwicklung in Java der Fokus auf Software-Entwurf und Datenmodell liegt, wenn man skalierbar programmieren möchte. Also eine gute Vorarbeit erleichtert alle Erweiterungen und Änderungen in der Zukunft. Android-Endgeräte verfügen in der Regel über großzügige Resourcen, im Vergleich zum Arduino. Deshalb gehört hier die gesamte Anwendungslogik rein.


Elektrotechnische Kenntnisse werden nur sehr marginal benötigt. Wir brauchen einen Spannungsteiler, um die unterschiedlichen Betriebspannung zwischen dem Amtel und dem ESP8266 auszugleichen. Sie liegen bei 5V und 3.3V. Es ist schon klar, das ein Verständnis für Spannung, Strom und Widerstand erforderlich ist und die Beziehung dieser untereinander bekannt sind. Stelle Dir hierzu einfach die Frage: Wie unterschiedlich verhalten sich Ströme und Spannungen in Maschen und Knoten?


Da am Ausgang der Relais Ströme von 10 Ampere bei 250V geschaltet werden, darf die Montage nur von Elektro-Fachleuten durchgeführt werden. Wir arbeiten hier mit lebensbedrohlichen Strömen!


Damit sind die Voraussetzungen abgeklärt.






Der elektrotechnische Part ist sehr simple.





Der erste Kontakt


Das Arduino-Board ist Open-Source. Es hat in der Regel das gleiche Layout, egal ob man es in China oder in Europa kauft. Die grün eingekreisten Bauteile, oder Baugruppen sollte man kennen. Dazu kommen noch einige Begriffe wie: SPI, PWM, I²C und TWI ...,etc. Chinesische Varianten weichen gelegentlich bei diskreten Bauteilen und Chips ab. Dieser Umstand betrifft dann auch die USB-Baugruppe und den notwendigen Treibern dazu. Ist aber kein großer Umstand.  






Das ist er also - Der Mikrocontroller. Einige Bauteile solltest Du kennen:





Wie unschwer zu erkennen ist betrachten wir das UNO-Board - Die markierten Bauteile der Reihe nach:



  1. USB-Stecker - da drüber ist der Reset-Button zu sehen.

  2. Externe Stromversorgung - 5V bei 5-10 Watt reichen vollkommen aus.

  3. USB/Serial-Konverter-Chip. Hier der CH340G

  4. Der Prozessor. Hier der AMTEL Mega 328P

  5. Die I²C-Schnittstelle wird aus lizenzrechtlichen gründen auch TWI-Bus genannt.
    Sie ist ein 2-Leitungsbus zwischen I²C-fähigen Chips. Ein Einsatzbereich in der
    in der Arduino-Landschaft sind z.B.: Displays. Das klassische 1602-Display braucht ohne
    den I²C-Bus 11 statt 4 Leitungen inklusive der Stromversorgung.

  6. Digitale IO-Ports (~ -markierte sind PWM-fähig). PWM ist ein Puls-Modulationsverfahren,
    dass zur Informationsübertragung eingesetzt wird. Andere Einsatzbereiche sind z.B.
    für abtastträge Empfänger, das Erzeugen und Modulieren von Analog-Schwingungen.
    So ist es möglich Halbleiterbausteine augenscheinlich zu regeln.
    LEDs lassen sich so dem Anschein nach dimmen. 

  7. Spannungs- und Masse-Pins

  8. Analoge Eingänge



Verbleibt noch der Begriff SPI zu klären. Wir haben hier ein weiteres Bussystem mit 3 Leitungen. Es ist full-Duplex-fähig und gehorcht dem Master- and Slave-Model. Auf dem UNO Board sind die Pins 11, 12 und 13 eigentlich für diesen Bus vorgesehen(MOSI, MISO und SCK). All diese Systeme befinden sich voll integriert in unserem Mikrocontroller. 2 Begriffe sollten wir auch noch mal ansprechen: Steuern ist ein Stellgrößenverfahren und Regeln ist ein Nachstellverfahren. Steuer- und Regel-Technik ist schliesslich das Haupt-Thema aller Arduino-Entwickler. Stellgrößen geben wir über die digitalen IOs z.B.: an Relais weiter, um diese durchzuschalten. Regeln ist etwas komplizierter. Wir brauchen einen Ist-Wert, z.B.: über einen anlogen In-Port, der dann rechnerisch ausgewertet wird und über einen PWM-Port, oder mehrere digitale IO-Ports nachgeregelt wird. Das war jetzt alles sehr einfach ausgedrückt, aber ich gehe mal davon aus, dass die meißten Arduino-Entwickler diese Dinge sowieso auf dem Schirm haben. Die detaillierte Erklärung der benutzten Verfahren liefere ich dann in den einzelnen Entwicklungsstufen.





Die grün eingekreisten Pins repräsentieren die Bussysteme plus UART.
Quelle: Amtel: 7810A–AVR–11/09





Wer ein chinesisches Board erworben hat, wie dieses in der Abbildung, wird mit großer Wahrscheinlichkeit den CH340G USB/Serial-Chip haben. Um Kontakt mit dem Board aufzunehmen, ist dann für den PC natürlich der passenden Treiber nötig. Du findest ihn hier auf eigene Verantwortung, oder bei einem Hersteller dieses Chips. Die gezipte Datei entpacken und die exe ausführen. Das Board über den USB-Stecker mit einem USB-Port des PCs verbinden und die IDE Deiner Wahl öffnen. Öffnest Du jetzt mit der richtigen COM-Schnittstelle, (...es werden immer alle verfügbaren angezeigt) bei 115200baud und CR/LF-Auswahl den seriellen Monitor, siehst Du diese Ausgabe:


Connect to serial port COM5 at 115200


Siehst Du nichts, drücke einmal den Reset-Button bei geöffnetem Monitor. Siehst Du immer noch nichts, wähle eine andere COM-Schnittstelle. Wenn alles ok ist kannst Du jetzt aus der IDE Programme auf das Board übertragen und auch Debug-Ausgaben in den seriellen Monitor absetzen.


Der Rahmen sollte jetzt ausreichen, um zu Verstehen, warum wir wie programmieren müssen. Den Bootloader hatte ich bereits angesprochen. Seine Aufgabe ist es, ein
vorhandenes lauffähiges Programm im Binärformat auszuführen, oder auf
Anforderung ein neues Programm in den Flash-Speicher zu laden und dieses
dann auszuführen. Dabei belasse ich es jetzt ersmal und ich wechsel zum Thema Software-Entwicklung.


Software-Entwicklung auf einem Arduino-based Mikrocontroller


Die Essenz aus den bisherigen Betrachtungen ist: Der Arduino läßt sich in C programmieren und hat somit einen Hochsprachenzugang. Wir haben aber kein Betriebssystem und deshalb können wir auch keine Libraries aus diesem Bereich verwenden. So brauchbare Dinge, wie Signalverarbeitung, Threads, IPC, Socket ..., etc stehen uns so erstmal nicht zur Verfügung. Wir müssen diese Werkzeuge simmulieren. Für den Arduino-based Mikrocontroller gibt es bereits eine umfangreiche Sammlung von Open-Source-Bibliotheken, die dieses für uns tun. Wenn Du dieses in Anspruch nimmst, solltest Du aber Wissen, was sie tun, wie sie es machen und wie Du sie einsetzen kannst. 


Wir programmieren einen Mikrocontroller, weil wir die Zustände von Ein- und Ausgängen manipulieren, oder auswerten wollen. Hierbei berücksichtigen wir die besonderen Eigenschaften der IOs. Eine Eigenschaft, der ein besonderer Augenmerk gilt, ist die funktionale Vorbesetzung dieser IOs. Benutze ich sie, so muss ich auf diese Funtionen verzichten.


Der Arduino UNO erfüllt die Voraussetzungen für 3 spezifizierte Busverfahren: I²C, SPI und UART. Diese sind für uns die Kommunikationsschnittstellen, z.B.: Zu anderen Mikrocontroller-Boards. Auch hier muss ich beachten, dass es Vorbesetzungen gibt: RX/TX ist der allgemeine PC-Zugang für Upload und Debug. Mit Debug meine ich nicht in erster Linie die Ausgaben, die ich selbst im Code erzeuge, sondern vorrangig den Stack-Trace, der vom Arduino-System erzeugt wird.


Zum Schluss muss ich immer berücksichtigen, dass der flüchtige Speicher für Programm und Variablen sehr begrenzt ist. Hier ein Beispiel:



Executable segment sizes:
ICACHE : 32768           - flash instruction cache
IROM   : 256468          - code in flash         (default or ICACHE_FLASH_ATTR)
IRAM   : 27373   / 32768 - code in IRAM          (IRAM_ATTR, ISRs...)
DATA   : 1524  )         - initialized variables (global, static) in RAM/HEAP
RODATA : 1456  ) / 81920 - constants             (global, static) in RAM/HEAP
BSS    : 27272 )         - zeroed variables      (global, static) in RAM/HEAP
Der Sketch verwendet 286821 Bytes (27%) des Programmspeicherplatzes. Das Maximum sind 1044464 Bytes.
Globale Variablen verwenden 30252 Bytes (36%) des dynamischen Speichers, 51668 Bytes für lokale Variablen verbleiben. Das Maximum sind 81920 Bytes.






Auf geht 's



Ein einfaches C Programm sieht in der Regel so aus:




// Standard C99


#include "Arduino.h"


#include <stdio.h>


#include <stdlib.h>


void setup()
{


    // Initialisierungs Code 


}


void loop()


{


// Prozess Code 


}


int main(void) {


  setup();


  loop();



return EXIT_SUCCESS;

}

Alles was kursiv dargestellt ist verschwindet in der Arduino-IDE, denn es gibt hier nur eine main-function. Wir können natürlich weitere eigene functions programmieren und benutze. Es bleibt also:


// Standard C99


#include "Arduino.h"

void setup()

{


   // Initialisierungs Code  


}


void loop()


{


// Prozess Code 


}



... weiter im Text geht es dann in ein paar Tagen.


Nils Wehrmann