Wir programmieren den Schalter durch Passage. MicroPython auf esp8266 (sonoff) mit OTA. Teil 1

Hallo an alle.


Während des Reparaturprozesses entstand die Aufgabe, einen Durchgangsschalter herzustellen. Natürlich wollte ich es auf einfachste und bequemste Weise tun und grundlegende Steuerfunktionen vom Telefon aus hinzufügen. Ich entschied mich für die einfachste und bequemste Technologie (natürlich meiner Meinung nach) - MicroPython - und begann damit. Ich habe das fertige Board auf esp8266 genommen und dafür eine Stunde Freizeit eingeplant. Da dies jedoch bei nicht sehr beliebten und nicht eingeführten Projekten der Fall ist, zog sich die Aufgabe etwas hin.


Wie sich herausstellte, funktioniert das Design, das ich am bequemsten fand, überhaupt nicht. Ich musste einige Zeit damit verbringen, dies zu analysieren, außerdem beschloss ich, den gesamten Prozess ausreichend detailliert zu beschreiben. Das Volumen des Artikels nahm rasant zu, und so beschloss ich, ihn in Teile zu teilen und alle Details zu verwerfen, die meiner Meinung nach unnötig sind.


Der erste Teil besteht aus drei Teilen:


  1. Theoretische Überlegungen zur Auswahl des einfachsten Mediums für die Entwicklung eines Durchgangsschalters,
  2. Praktischer Start der ausgewählten Basis-Firmware auf den ausgewählten Geräten, Fallstricke,
  3. Firmware-Entwicklung

Auswahl der einfachsten Entwicklungsumgebung


Für ein Smart Home wie „Machen Sie es sich selbst, wenn Sie eine Minute Freizeit haben“ bietet die Liste der obligatorischen Ausrüstungsanforderungen neben den klassischen Elementen (z. B. Stabilität) auch eine einfache Entwicklung, Installation und Unterstützung. Die Geräte müssen die erforderlichen Sensoren oder Steuergeräte problemlos an sie anschließen können. Dass es bequeme und einfache Möglichkeiten gab, mit dem gesamten System zu kommunizieren. Es muss sichergestellt werden, dass das Schreiben von Firmware auf dieses Gerät einfach ist, wobei zu berücksichtigen ist, dass sich das Gerät dort befindet, wo es schwer zu erreichen ist. Und natürlich ist die einfache Entwicklung besonders für Heimwerker von entscheidender Bedeutung, wenn beispielsweise 2 Jahre nach dem Arbeiten ohne Ausfälle des gesamten Systems gearbeitet wird
plötzlich möchte ich einige Anpassungen an der Firmware hinzufügen. Um diese Korrekturen vornehmen zu können, müssen Sie sich daran erinnern, wie dieses System funktioniert. Dies kann manchmal länger dauern als die Anpassung selbst.


Stellen Sie sich ein banales Beispiel vor: Sie müssen einen einfachen Durchgangsschalter mit der Möglichkeit erstellen, ihn zu steuern, auch von einem PC aus. In letzter Zeit war diese Aufgabe ziemlich kompliziert, es war notwendig, eine Art Mikrocontroller zu nehmen (die beliebtesten waren avr oder pic), und um Firmware zu schreiben, muss man in der Regel die Dokumentation dazu lesen. Wenn Sie alles sofort erledigen möchten, müssen Sie die Karte trennen, auf der sich AC / DC, ein Mikrocontroller und eine Kommunikationsschnittstelle befinden. Löten Sie nach der LUT (oder Bestellung von Leiterplatten) alles, kaufen Sie einen Programmierer und eine Flash-Firmware. Und dann, nach 2-3 Jahren, wenn nötig, um etwas zu reparieren, suchen Sie nach allen Geräten und lernen Sie alles von Grund auf neu ...


Um diesen Prozess zu vereinfachen, wurden vorgefertigte Lösungen auf den Markt gebracht. Die erfolgreichste Lösung ist Arduino. Diese Lösung wird von der IDE bereitgestellt, dem Bootloader mit der Update-Funktion, mit der Sie ohne Programmierer ausschließlich über die Standardschnittstelle mit dem Gerät arbeiten können. Es macht es möglich, Firmware nur mit zu machen
ein sehr oberflächliches Verständnis dafür, wie dort alles angeordnet ist. Ein Satz externer Module ermöglicht den Anschluss von Geräten ohne Lötkolben. Um Änderungen vornehmen zu können, müssen Sie die Arduino-Software installieren und die Firmware irgendwo speichern.


Unser Durchgangsschalter wird groß genug sein und ein Arduino-Board + AC / DC + Relaismodul enthalten. Und wenn Sie Anpassungen vornehmen müssen, müssen Sie sich schmerzhaft merken, wo der Code liegt, und die Arduino-Software erneut installieren.


Um sich die Notwendigkeit zu ersparen, den Quellcode zu kompilieren (d. H. Zusätzliche Software zu installieren und zu speichern), scheint die logischste Lösung darin zu bestehen, Interpreter zu verwenden oder den Code direkt auf dem Mikrocontroller selbst zu kompilieren. Glücklicherweise sind jetzt Projekte erschienen, die dies ermöglichen. Zum Beispiel NodeMCU, der Lua-Sprachinterpreter für den esp8266-Mikrocontroller: Die Firmware selbst unterstützt das Dateisystem, mit dem Sie Skripte auf das / vom Gerät laden / lesen können. Ein weiteres ziemlich ernstes Projekt ist Micropython, eine abgespeckte Version von Python, die speziell auf Mikrocontroller zugeschnitten ist. Es wird diskutiert.


MicroPython ist eine Implementierung einer der beliebtesten Python-Programmiersprachen. Es unterstützt eine große Anzahl von Architekturen und SoC (Bare-Arm, CC3200, esp8266, esp32, nRF, pic16bit, stm32). Das Projekt entwickelt sich aktiv und verfügt über eine Vielzahl zusätzlicher Module.


Der Mikroprozessor esp8266 eignet sich sehr gut als Hardware-Teil, da auf ihm aufgebaute preisgünstige WLAN-Switch-Module auf dem Markt verkauft werden. Sie enthalten alles, was wir brauchen: AC / DC, einen Mikrocontroller mit integrierter Kommunikationsschnittstelle (WLAN). Erhältlich unter dem Markennamen Sonoff. Die esp8266-Mikroprozessoren enthalten keinen Speicher, sie sind separat verlötet und können eine andere Größe haben. Für Sonoff Basic setzen sie 1Mb Module.


Starten der Basis-Firmware auf esp8266. Sonoff Basic.


Ohne Fallstricke wäre es möglich, sofort mit der Programmierung in Python fortzufahren. Leider gibt es eine Reihe von Problemen, die gelöst werden müssen. Um die Firmware zu programmieren und zu ändern, war dies sehr einfach und unkompliziert. Natürlich sind wir daran interessiert, dies über WLAN zu tun, ohne zusätzliche Geräte außer einem Laptop zu verwenden.


Die erste Gefahr ist natürlich die grundlegende Firmware, die auf Ihrem Board aufgezeichnet ist. Wenn Sie ein Debug-Board gekauft haben, finden Sie höchstwahrscheinlich NodeMCU darauf, wenn Sonoff Basic, dann proprietäre Firmware. Um dieses Board für sich selbst vorzubereiten, müssen Sie dort die erforderliche Firmware notieren. Bei einigen Mikrocontrollern ist der Kauf erforderlich
Als spezieller Programmierer, in unserem Fall hatten wir Glück, brauchen Sie nur einen USB <-> UART-Konverter. Wenn Sie mit Mikrocontrollern arbeiten, ist dies mehr als einmal nützlich, und der Preis liegt normalerweise im Bereich von 3 US-Dollar.


Es gibt keinen Kamm für Sonoff Basic, mit dem Sie eine Verbindung über UART herstellen können, und wir benötigen diesen, um das Gerät zu programmieren. Um das Gerät einfach zu programmieren, ist es nicht erforderlich, den Lötkolben in die Hand zu nehmen. Es reicht aus, die Kontakte zu lehnen und die Firmware aufzuschreiben. Da die weitere Arbeit über WLAN erfolgen wird, werden wir diese Kontakte nicht mehr benötigen. Aber wir implementieren einen Schalter durch Passage, was bedeutet, dass wir gelötet werden müssen,
mindestens drei Beine.


Für Sonoff Basic gibt es nur 1 freien GPIO-Anschluss und 2 RX, TX-Anschlüsse. In Anbetracht der Tatsache, dass wir RX, TX selbst einmal benötigen (um die Firmware zu flashen), können sie in Zukunft dank esp8266 auf GPIO umprogrammiert werden. In diesem Fall müssen wir das Debuggen über UART abbrechen. Glücklicherweise haben wir dies bereits geplant, da das Debuggen über WLAN aus praktischen Gründen viel einfacher ist.


Da sich die Version von MicroPython dabei ändern kann, möchten wir die Update-Methode über WLAN debuggen. OTA kommt zur Rettung. OTA ist eine Firmware, mit der Sie ein Gerät neu programmieren können. Es funktioniert ganz einfach. Nach dem Einschalten des Gerätes bestimmt die Firmware, ob es neu programmiert werden muss, startet ggf. ein Special
Wenn nicht, startet der WLAN-Updater die Benutzer-Firmware. Die Implementierung kann unterschiedlich sein, die Firmware kann sich selbst überschreiben oder in einen freien Speicherbereich schreiben. Sie können auch festlegen, ob das Überspielprogramm überhaupt auf unterschiedliche Weise ausgeführt werden soll. Betrachten Sie beispielsweise das cxumma der benutzerdefinierten Firmware, wenn diese nicht konvergiert.
dann gewaltsam zum blinken gehen. Sie können Daten vom GPIO lesen oder Informationen über die Notwendigkeit schreiben, das Update an einer anderen Stelle zu starten.


Als Updater verweist das MicroPython-Projekt auf das yaota8266-Projekt. Yaota8266 behauptet, das Gerät zu flashen und jedes Paket zu signieren. Es ist zu beachten, dass der öffentliche Schlüssel in die Firmware selbst eingebettet ist, weshalb es keinen Sinn macht, die bereits zusammengestellte Firmware hochzuladen, da Sie Ihren Schlüssel dort nähen müssen.
Es gibt keine Funktion zum Ändern des privaten Schlüssels im zusammengestellten Image. In unserem Fall ist es daher einfacher, die Firmware selbst zusammenzustellen. Ein interessantes Merkmal ist, dass die Signaturüberprüfungsfunktion im Code auskommentiert ist, d. H. Tatsächlich bekommen wir Schwierigkeiten ohne Sicherheitsgewinne. Die Basisversion von yaota8266 wird nicht,
Glücklicherweise gibt es Gabeln auf Github, die dieses Problem lösen, und sie bieten die Möglichkeit, anhand des Schreibens in den RTC-Bereich zu bestimmen, ob das Flashen durchgeführt werden soll, wodurch MicroPython in den Bootloader-Modus geschaltet werden kann.


Auch nach Einbeziehung aller Korrekturen schreibt unsere OTA-Firmware fehlerhaft, funktioniert jedoch erfolgreich auf NodeMCU-Debug-Boards. Dies ist auf Zeitüberschreitungen zurückzuführen. Beim Aktualisieren vom Host-Computer werden UDP-Pakete gesendet und eine Antwort wird erwartet, wenn die Aufzeichnung in Flash länger als gewöhnlich dauert, eine Zeitüberschreitung auftritt und das Paket erneut gesendet wird. Der Vorteil ist leicht zu beheben,
Erhöhen Sie einfach die Zeitüberschreitungen im ota-Client-Code.


Das OTA + MicroPython-Bundle auf Sonoff weist ebenfalls interessante Kuriositäten auf. Eine davon hängt mit der Tatsache zusammen, dass die Standardfunktionen für die Arbeit mit SPI Flash in esp-sdk mit 4k-Blöcken arbeiten und diese Blockgröße für die Implementierung des FAT-Dateisystems ausgewählt wurde. Aufgrund der Tatsache, dass SPI Flash nur 1 MB groß ist, von denen ~ 300 KB OTA-Firmware und ~ 500 KB MicroPython-Firmware sind, verbleiben weniger als 200 KB für das Dateisystem, d. H. weniger als 50 Blöcke. Die ausgewählte Bibliothek, die fatfs implementiert, kann jedoch keine FS erstellen, wenn weniger als 50 Blöcke vorhanden sind. Es gibt verschiedene Möglichkeiten, das Problem zu lösen: Reduzieren Sie die Blockgröße (mit FAT können Sie 512 festlegen), korrigieren Sie die FatFs-Bibliothek, verwenden Sie SPI FS (in der Hoffnung, dass es keine solchen Kuriositäten gibt). Ich ging den Weg, den Block auf 512 zu reduzieren.


Mikrocontroller verwenden SPI-Flash - dies ist NOR- und / oder NAND-Speicher. Das Bemerkenswerte an diesem Speicher ist, dass es kein Konzept gibt, "irgendwelche Daten zu schreiben". Sie können nur den Wert zurücksetzen (bei 0xff) oder die gewünschten Bits auf "0" setzen. SPI Flash ist normalerweise ein NOR-Speicher. Es hat die Funktion, jedes Byte auf 0xff zurückzusetzen, während NAND nur durch Blöcke zurückgesetzt werden kann. Das heißt, Wenn die Mindestgröße des Rücksetzblocks 4 KB beträgt, um zu schreiben
1 Byte Speicher, es ist notwendig, den gesamten Block zu lesen, ihn auf 0xFF zurückzusetzen und dann den Block zu schreiben, indem das gewünschte Byte auf den gewünschten Wert gesetzt wird. Hersteller von SPI Flash haben ungefähr die gleichen APIs für die Arbeit, aber wie die Praxis gezeigt hat, kann der Befehl zum Schreiben eines Bytes SPI Flash unterschiedlich sein. Irgendwo wird es automatisch zurückgesetzt, bevor in 0xFF geschrieben wird, irgendwo nicht.


Wenn Sie den FAT-Abschnitt auf 512 Byte ändern, besteht die Möglichkeit, dass ein System defekt ist, wenn ein bestimmter SPI-Flash das automatische Zurücksetzen von Bytes bei der Aufnahme nicht unterstützt. Und es war eine solche Erinnerung, die mir in Sonoff Basic begegnet ist. Gerüchten zufolge haben sie dort früher Winbond 25q80bv installiert, jetzt jedoch PUYA 25q80h mit einem Mindestreinigungsblock von 256 Bytes. Lösung scheint
Einfach, Sie müssen nur zwei Seiten löschen, auf denen es geschrieben wird, bevor Sie den FAT-Block schreiben. Die Implementierung wird jedoch durch die Tatsache erschwert, dass sdk-esp nur das Löschen in 4k-Blöcken unterstützt. Da das Schreiben an die FAT für unseren Wechsel sehr selten sein wird,
Nur wenn Sie die Firmware-Skripte aktualisieren, können Sie den 512-Byte-Block in 4-KB-Blöcken aktualisieren. Die Dokumentation für diesen Speicher besagt, dass der Speicher 100.000 Umschreibzyklen standhalten kann, d.h. Eine ähnliche Umgehung des Problems verringert diesen Wert um das Vierfache, d.h. bis zu 25.000.


MicroPython verfügt standardmäßig über eine Konsole, die REPL heißt und über den COM-Port funktioniert. Wir sind mit diesem Zustand nicht sehr zufrieden, da wir über WLAN mit dem Gerät kommunizieren möchten. Glücklicherweise ist WebRepl in MicroPython ebenfalls Standard, startet jedoch nicht automatisch. Sie können autorun in boot.py registrieren, aber ich habe beschlossen, es direkt von _boot.py, der Systemdatei, auszuführen. Es ist in die Firmware-Datei selbst eingenäht.


Nach dem ersten Start erstellt unsere Firmware ein Dateisystem, startet webrepl und erstellt einen Zugriffspunkt. Sie können eine Verbindung herstellen und die Parameter für die Verbindung mit Ihrem lokalen Netzwerk vorschreiben oder wie ich das Netzwerk über den COM-Port konfigurieren. Danach sollte nur noch WLAN verwendet werden.


Für Testarbeiten können Sie den in Javascript geschriebenen Webrepl-Client verwenden. Der Client kann in einem Browser auf der entsprechenden Seite des Projekts gestartet werden. Eine weitere Option ist die Verwendung des mpfshell-Projekts. Es bietet bequemere Funktionen für die Arbeit mit dem Gerät.


Nachdem Sie alle diese Fallstricke überwunden haben, können Sie direkt mit der Programmierung des Schalters fortfahren.


Firmware-Entwicklung


Um die Firmware zu entwickeln, müssen wir eine ungefähre Vorstellung davon haben, wie GPIO funktioniert. Im Allgemeinen kann dies rein intuitiv verstanden werden:


  1. Wenn wir den Ausgabemodus (OUT) einstellen, erzeugt das Bein entweder GND oder Vcc.
  2. Wenn wir den Eingabemodus (IN) einstellen, baumelt das Bein "in der Luft". In diesem Fall kann der Mikrocontroller alles ausgeben
  3. Damit der Mikrocontroller nichts abgibt, kann das Bein mit dem eingebauten Mikrocontroller auf den gewünschten Wert gezogen werden
    Pull-up-Widerstände PULL_UP oder PULL_DOWN.

Sie müssen auch eine Vorstellung davon haben, was Interrupts sind: In unserem Fall ist dies der Code, der ausgeführt werden muss, wenn ein Ereignis auftritt: Eine Taste wurde gedrückt / losgelassen oder es kam eine Nachricht vom lokalen Netzwerk, dass das Gerät aus- / eingeschaltet werden soll.


Lassen Sie uns zunächst ein einfaches Switch-Programm (kein Pass-Through-Programm) in Python schreiben.


from machine import Pin class SW: def __init__(self, portin, portout): self.pin = Pin(portin , Pin.PULL_UP) #  self.pout = Pin(portout, Pin.OUT) #  #  self._auto(),       self.pin.irq(trigger=Pin.IRQ_RISING|Pin.IRQ_FALLING, handler=self._auto) self.value = 0 def _auto(self, _=0): if self.value: res = self.pin.value() else: res = not self.pin.value() self.pout.value(res) def change(self, val=2): """   0, ,  1, ,  2  """ if val == 2: self.value = not self.value else: self.value = val self._auto() sw = SW(14, 12) 

Ich habe diese switch.py-Datei benannt und befohlen, sie in boot.py auszuführen:


 from switch import sw 

Nach dem Starten der Firmware habe ich ein sw-Objekt erhalten. Wenn ich sw.change () ausführe, erfolgt ein Programmwechsel
in eine andere Position wechseln. Wenn ein freier Pin im Mikrocontroller mit Vcc kurzgeschlossen ist
Das Relais schaltet sich ein bzw. aus.


Der nächste Schritt ist der Start des MQTT-Clients und die Möglichkeit, den Switch vom Telefon aus zu wechseln.

Source: https://habr.com/ru/post/de438624/


All Articles