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:
- Consideraciones teóricas sobre la selección del medio más simple para el desarrollo de un interruptor de paso,
- Lanzamiento práctico del firmware básico seleccionado en el equipo seleccionado, dificultades,
- 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:
- Si establecemos el modo de salida (OUT), el tramo produce GND o Vcc.
- Si establecemos el modo de entrada (IN), entonces la pata "cuelga en el aire", en cuyo caso el microcontrolador puede emitir cualquier cosa
- 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)
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.