Programamos el cambio a través del pasaje. MicroPython en esp8266 (sonoff) con OTA. Parte 1

Hola a todos


En el proceso de reparación, surgió la tarea de hacer un cambio de paso. Por supuesto, quería hacerlo de la manera más simple y conveniente, agregando funciones básicas de control desde el teléfono. Elegí la tecnología más simple y conveniente para esto (por supuesto, en mi opinión) - MicroPython, y comencé a hacerlo. Tomé el tablero terminado en esp8266 y asigné una hora de tiempo libre para esto. Pero, como sucede con proyectos no muy populares y sin ejecución, la tarea se prolongó un poco.


Result√≥ que el dise√Īo que me pareci√≥ m√°s conveniente resulta que no funciona en absoluto. Tuve que pasar alg√ļn tiempo analizando esto, adem√°s decid√≠ describir todo el proceso con suficiente detalle. El volumen del art√≠culo comenz√≥ a aumentar a un ritmo r√°pido, as√≠ que decid√≠ dividirlo en partes y descartar todos los detalles que son innecesarios en mi opini√≥n.


La primera parte consta de tres partes:


  1. Consideraciones teóricas sobre la selección del medio más simple para el desarrollo de un interruptor de paso,
  2. Lanzamiento pr√°ctico del firmware b√°sico seleccionado en el equipo seleccionado, dificultades,
  3. Desarrollo de firmware

Elegir el entorno de desarrollo m√°s f√°cil


Para una casa inteligente como "h√°galo usted mismo si tiene un minuto de tiempo libre", adem√°s de los elementos cl√°sicos (por ejemplo, estabilidad), la lista de requisitos obligatorios del equipo tambi√©n agrega facilidad de desarrollo, instalaci√≥n y soporte. Se requiere que los dispositivos conecten f√°cilmente los sensores o dispositivos de control necesarios. Que hab√≠a formas convenientes y f√°ciles de comunicarse con todo el sistema. Es necesario garantizar la facilidad de escribir firmware en este dispositivo, teniendo en cuenta que el dispositivo puede ubicarse donde sea dif√≠cil acceder a √©l. Y, por supuesto, la facilidad de desarrollo, esto es especialmente cr√≠tico para el bricolaje, cuando, por ejemplo, 2 a√Īos despu√©s de trabajar sin fallas de todo el sistema
De repente quiero agregar algunos ajustes al firmware. Para realizar estas correcciones, debe recordar cómo funciona este sistema, que a veces puede llevar más tiempo que el ajuste en sí.


Considere un ejemplo banal: necesita hacer un interruptor de paso simple con la capacidad de controlarlo, incluso desde una PC. En los √ļltimos tiempos, esta tarea era bastante complicada, era necesario tomar alg√ļn tipo de microcontrolador (los m√°s populares eran avr o pic), y para escribir el firmware, por regla general, debe leer la documentaci√≥n correspondiente. Si desea hacer todo fuera de la caja, debe separar la placa, d√≥nde colocar AC / DC, un microcontrolador y una interfaz de comunicaci√≥n. Despu√©s de LUT (o de ordenar placas de circuito impreso), suelde todo, compre un programador y actualice el firmware. Y luego, despu√©s de 2-3 a√Īos, si es necesario, para arreglar algo, busque todo el equipo y aprenda todo desde cero ...


Para simplificar este proceso, comenzaron a aparecer soluciones preparadas en el mercado. La solución más exitosa es Arduino. Esta solución es proporcionada por el IDE, el gestor de arranque con la función de actualización, que le permite trabajar con el dispositivo exclusivamente a través de la interfaz estándar sin el uso de programadores. Permite hacer firmware, teniendo solo
Una comprensi√≥n muy superficial de c√≥mo todo est√° organizado all√≠. Un conjunto de m√≥dulos externos permite conectar dispositivos sin soldador. Pero de todos modos, para realizar ediciones, debe instalar el software Arduino, almacenar el firmware en alg√ļn lugar.


Nuestro interruptor de paso resultará ser lo suficientemente grande, contendrá una placa Arduino + módulo de relé AC / DC +. Y si necesita hacer ajustes, tendrá que recordar dolorosamente dónde se encuentra el código e instalar nuevamente el software Arduino.


Para ahorrarse la necesidad de compilar el c√≥digo fuente (es decir, instalar software adicional y almacenarlo), la soluci√≥n m√°s l√≥gica parece ser usar int√©rpretes o compilar directamente el c√≥digo en el microcontrolador. Afortunadamente, ahora han aparecido proyectos que permiten que esto se haga. Por ejemplo, NodeMCU, el int√©rprete de lenguaje lua para el microcontrolador esp8266: el firmware en s√≠ tiene soporte incorporado para el sistema de archivos, que le permite descargar / leer scripts en / desde el dispositivo. Otro proyecto bastante serio es Micropython, una versi√≥n simplificada de python dise√Īada espec√≠ficamente para microcontroladores. Ser√° discutido


MicroPython es una implementación de uno de los lenguajes de programación python más populares en la actualidad. Admite una gran cantidad de arquitecturas y SoC (bare-arm, CC3200, esp8266, esp32, nRF, pic16bit, stm32). El proyecto se está desarrollando activamente y tiene una gran cantidad de módulos adicionales.


El microprocesador esp8266 es muy adecuado como parte del hardware, debido al hecho de que los m√≥dulos de conmutador wifi de presupuesto incorporados se venden en el mercado. Contienen todo lo que necesitamos: AC / DC, un microcontrolador con una interfaz de comunicaci√≥n integrada (wifi). Disponible bajo la marca Sonoff. Los microprocesadores esp8266 no contienen memoria, se sueldan por separado y pueden tener un tama√Īo diferente. Para Sonoff Basic pusieron m√≥dulos de 1Mb.


Iniciando firmware b√°sico en esp8266. Sonoff Basic.


En ausencia de dificultades, ser√≠a posible proceder inmediatamente a la programaci√≥n en python. Pero, desafortunadamente, hay una serie de problemas que deben resolverse, para programar y modificar el firmware fue muy f√°cil y simple. Por supuesto, estamos interesados ‚Äč‚Äčen hacerlo a trav√©s de wifi, sin usar ning√ļn dispositivo adicional, excepto una computadora port√°til.


El primer escollo, por supuesto, es el firmware básico que está grabado en su placa. Si compró una placa de depuración, lo más probable es que encuentre NodeMCU en ella, si Sonoff Basic, entonces el firmware propietario. Para preparar esta placa para usted, debe escribir el firmware necesario allí. En algunos microcontroladores, es necesario comprar
un programador especial, en nuestro caso tuvimos suerte, solo necesita obtener un convertidor USB <-> UART. Si trabaja con microcontroladores, ser√° √ļtil m√°s de una vez, y su precio generalmente est√° en el rango de $ 3.


No hay un peine para Sonoff Basic que le permita conectarse a través de UART, y necesitamos esto para programar el dispositivo. Para programar simplemente el dispositivo, no es necesario tomar el soldador en sus manos, es suficiente inclinar los contactos y escribir el firmware. Teniendo en cuenta que el trabajo adicional se realizará a través de wifi, ya no necesitaremos estos contactos. Pero implementamos un interruptor a través del pasaje, lo que significa que necesitamos soldadura,
Al menos tres patas.


Para Sonoff Basic, solo hay 1 conector GPIO libre y 2 conectores RX, TX. Teniendo en cuenta que necesitamos RX, TX nosotros mismos una vez (para actualizar el firmware), en el futuro pueden reprogramarse para GPIO, gracias a esp8266, esto se puede hacer. Pero en este caso, debemos abandonar la depuración a través de UART, afortunadamente ya planeamos hacerlo, ya que la depuración a través de wifi, desde el punto de vista de la conveniencia, es mucho más simple.


Dado que la versi√≥n de MicroPython puede cambiar en el proceso, estamos interesados ‚Äč‚Äčen depurar el m√©todo de actualizaci√≥n a trav√©s de wifi. OTA viene al rescate. OTA es un firmware que le permite reprogramar un dispositivo. Funciona de manera bastante simple. Despu√©s de encender el dispositivo, el firmware determina si es necesario reprogramarlo, si es necesario, inicia un dispositivo especial
El actualizador wifi, si no, inicia el firmware del usuario. La implementación puede ser diferente, el firmware puede sobrescribirse o escribir en un área libre de memoria. También puede determinar si ejecutar el programa de doblaje de diferentes maneras. Por ejemplo, considere la cxumma del firmware personalizado si no converge,
luego ve por la fuerza al parpadeo. Puede leer datos del GPIO o escribir información sobre la necesidad de iniciar la actualización en otro lugar.


Como actualizador, el proyecto MicroPython se refiere al proyecto yaota8266. Yaota8266 afirma estar flasheando el dispositivo y firmando cada paquete. Cabe se√Īalar que la clave p√ļblica est√° incrustada en el firmware en s√≠, por lo que no tiene sentido cargar el firmware ya ensamblado, ya que es necesario coser la clave all√≠.
No hay ninguna función para modificar la clave privada en la imagen ensamblada, por lo que en nuestro caso es más fácil ensamblar el firmware usted mismo. Una característica interesante es que la función de verificación de firma es, pero está comentada en el código, es decir de hecho, tenemos dificultades sin ninguna ganancia de seguridad. La versión básica de yaota8266 no va a,
Afortunadamente, hay horquillas en github que resuelven este problema, además de que agregan la capacidad de determinar si el flasheo se debe realizar en función de la escritura en el área RTC, lo que hace posible cambiar MicroPython al modo de cargador de arranque.


Incluso después de incluir todas las correcciones, nuestro firmware OTA escribirá con errores, pero funcionará con éxito en las placas de depuración de NodeMCU. Esto se debe a los tiempos de espera. Cuando se actualiza desde la máquina host, se envían paquetes UDP y se espera una respuesta si la grabación en flash tarda más de lo habitual, se agota el tiempo de espera y se vuelve a enviar el paquete. El beneficio es fácil de arreglar,
solo aumentando los tiempos de espera en el código ota-client.


El paquete OTA + MicroPython en Sonoff tambi√©n tiene rarezas interesantes. Uno de ellos est√° relacionado con el hecho de que las funciones est√°ndar para trabajar con SPI Flash en esp-sdk operan en bloques de 4k, y este tama√Īo de bloque fue elegido para implementar el sistema de archivos FAT. A su vez, debido a que SPI Flash es de solo 1Mb, de los cuales ~ 300Kb es firmware OTA, ~ 500Kb es firmware MicroPython, quedan menos de 200Kb para el sistema de archivos, es decir Menos de 50 cuadras. Sin embargo, la biblioteca seleccionada que implementa fatfs no puede crear un FS donde haya menos de 50 bloques. Hay varias maneras de resolver el problema: reduzca el tama√Īo del bloque (FAT le permite configurar 512), arregle la biblioteca FatFs, use SPI FS (con la esperanza de que no haya tales rarezas). Tom√© el camino de reducir el bloqueo a 512.


Los microcontroladores usan SPI Flash, esto es memoria NOR y / o NAND. Lo notable de esta memoria es que no existe el concepto de "escribir ning√ļn dato". Solo puede restablecer el valor (a 0xff) o establecer los bits deseados en "0". SPI Flash generalmente es memoria NOR, tiene la funci√≥n de restablecer cualquier byte a 0xff, mientras que NAND solo se puede restablecer por bloques. Es decir si el tama√Īo m√≠nimo del bloque de reinicio es 4k, para escribir
1 byte de memoria, es necesario leer todo el bloque, restablecerlo a 0xFF y luego escribir el bloque configurando el byte deseado al valor deseado. Los fabricantes de SPI Flash tienen aproximadamente el mismo conjunto de API para el trabajo, pero, como lo ha demostrado la pr√°ctica, el comando para escribir un byte de SPI Flash puede diferir. En alg√ļn lugar se restablecer√° autom√°ticamente antes de escribir en 0xFF, en otro lugar no.


Si cambia la secci√≥n FAT a 512 bytes, existe la posibilidad de obtener un sistema da√Īado si un SPI Flash espec√≠fico no admite el restablecimiento autom√°tico de bytes durante la grabaci√≥n. Y fue solo un recuerdo que encontr√© en Sonoff Basic. Se rumorea que sol√≠an instalar Winbond 25q80bv all√≠, pero ahora PUYA 25q80h, que tiene un bloque de limpieza m√≠nimo de 256 bytes. La soluci√≥n parecer√≠a
simple, solo necesita borrar dos páginas donde se escribirá antes de escribir el bloque FAT, pero la implementación es complicada por el hecho de que sdk-esp solo admite la eliminación en bloques 4k. Dado que escribir en el FAT será muy raro para nuestro switch,
solo al actualizar los scripts de firmware, puede ir por el mal camino y actualizar el bloque de 512 bytes en bloques de 4k. La documentación de esta memoria dice que la memoria puede soportar 100,000 ciclos de reescritura, es decir. una elusión similar del problema nos reducirá este valor en 4 veces, es decir hasta 25,000.


MicroPython tiene una consola por defecto, se llama REPL y funciona a través del puerto COM. No estamos muy contentos con este estado de cosas, ya que queremos comunicarnos con el dispositivo a través de wifi. Afortunadamente en MicroPython, WebRepl también viene de serie, pero no se inicia automáticamente. Puede registrar la ejecución automática en boot.py, pero decidí ejecutarlo directamente desde _boot.py, el archivo del sistema, está cosido en el archivo de firmware.


Después del primer inicio, nuestro firmware creará un sistema de archivos, iniciará webrepl y creará un punto de acceso. Puede conectarse a él y prescribir los parámetros para conectarse a su red local o, como lo hice, configurar la red usando el puerto com, después de lo cual solo se debe usar wifi.


Para el trabajo de prueba, puede usar el cliente webrepl escrito en javascript. El cliente se puede iniciar en un navegador en la página correspondiente del proyecto. Otra opción es usar el proyecto mpfshell, que proporciona funciones más convenientes para trabajar con el dispositivo.


Entonces, después de superar todos estos escollos, puede ir directamente a programar el cambio.


Desarrollo de firmware


Para desarrollar el firmware, necesitamos tener una idea aproximada de cómo funciona GPIO. En general, esto puede entenderse de manera puramente intuitiva:


  1. Si establecemos el modo de salida (OUT), el tramo produce GND o Vcc.
  2. Si establecemos el modo de entrada (IN), entonces la pata "cuelga en el aire", en cuyo caso el microcontrolador puede emitir cualquier cosa
  3. Para que el microcontrolador no entregue nada, la pata se puede tirar al valor deseado usando el microcontrolador incorporado
    resistencias pull-up PULL_UP o PULL_DOWN.

Tambi√©n debe tener una idea de qu√© son las interrupciones: en nuestro caso, este es el c√≥digo que debe ejecutarse si ocurre alg√ļn tipo de evento: se presion√≥ / ‚Äč‚Äčsolt√≥ un bot√≥n o lleg√≥ un mensaje de la red local de que el dispositivo deber√≠a estar apagado / encendido.


Para comenzar, escriba un programa simple de cambio (no de paso) en Python.


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) 

Llam√© a este archivo switch.py ‚Äč‚Äčy orden√© que se ejecutara en boot.py:


 from switch import sw 

Después de iniciar el firmware, obtuve un objeto sw, si ejecuto sw.change (), se producirá un cambio de programa
cambiar a otra posición. Cuando un pin libre está en cortocircuito a Vcc en el microcontrolador
el relé se enciende o apaga, respectivamente.


El siguiente paso será el lanzamiento del cliente MQTT y la capacidad de cambiar el interruptor desde el teléfono.

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


All Articles