
Todo comenzó con la adquisición por parte del autor en el mercado secundario de un dispositivo interesante: Smart Response XE (
breve descripción ). Está destinado a las escuelas: cada alumno de la clase recibe un dispositivo similar a un cuaderno electrónico o traductor de los años noventa, el profesor hace una pregunta y los alumnos escriben en los teclados de los dispositivos las respuestas recibidas a través del canal de radio (802.15.4) al receptor conectado a la PC del profesor.
El soporte para estos dispositivos se suspendió hace varios años, y el hecho de que las escuelas compraron a $ 100-200 cada uno, ahora aparece en eBay por 10 o menos. El hierro allí es muy adecuado para experimentos geek:
- Teclado de 60 teclas
- pantalla con una resolución de 384x136, 2 bits por píxel, similar a BK, CGA, pero 4 no son colores, sino gradaciones de brillo
- Microcontrolador ATmega128RFA1 (memoria flash de 128 kB, ROM de 4 kB, RAM de 16 kB, transceptor estándar 802.15.4)
- Memoria flash externa (con respecto al microcontrolador y no a todo el dispositivo) de 1 megabyte (128 kilobytes) con SPI
- Compartimento para 4 elementos AAA.
Por el nombre del microcontrolador, está claro que pertenece a la familia AVR, lo que significa que hacer un dispositivo compatible con Arduino es una tarea más que trivial ...
A partir de las noticias sobre
Hackaday, el autor descubrió que
ya lo habían hecho (el mismo enlace dice a qué conectarse), teniendo la oportunidad de ejecutar juegos para Arduboy:
Pero el autor está más interesado en la oportunidad de no jugar en el dispositivo, sino de estudiar:
- flash serie SPI
- descargadores para AVR
- estándar 802.15.4
El autor comenzó escribiendo una
biblioteca (GPL v3) que le permite inicializar la pantalla, mostrar texto y rectángulos, y también acceder a la memoria flash con la interfaz SPI. Luego comenzó a proponer ideas para el uso práctico del dispositivo: un terminal de bolsillo compatible con VT-100, juegos para múltiples jugadores. Habiendo rehecho los tres dispositivos, decidió "enseñarles" cómo obtener bocetos "por el aire". Lo que no solo sería interesante, sino también muy conveniente: es difícil abrir la carcasa del dispositivo cada vez, y debajo de la cubierta de la batería solo hay agujeros que le permiten conectar un programador JTAG a la placa.

Esto es suficiente para llenar el gestor de arranque Arduino, pero no es un boceto: el puerto serie no se emite allí, aún no puede hacerlo sin abrir la carcasa. Además, las líneas TX0 y RX0 del primer puerto serie están alineadas con las líneas de sondeo de la matriz del teclado, es decir, aquellas a lo largo de las cuales se sondean las teclas de función a los lados de la pantalla. Pero qué hacer: el autor construyó esto:

Allí sacó las líneas JTAG, y ahora no es necesario abrir el compartimento de la batería. Y para poder completar los bocetos, traje ambos puertos seriales al mismo conector, agregando también un interruptor, porque cuando las baterías están instaladas, el dispositivo no puede apagarse físicamente de manera diferente.
Me llevó bastante tiempo trabajar con un soldador, un cuchillo de oficina y una pistola de pegamento. En general, los bocetos de vertido "por aire" son mucho más convenientes, es urgente inventar algo para esto.
Arduino IDE usa
avrdude para completar bocetos. Interactúa con el microcontrolador a través del protocolo
STK500 , que le permite transferir archivos en ambas direcciones. Es poco compatible con los canales donde son posibles retrasos variables, distorsión y pérdida de datos. Si algo se dispara o cruje en el canal serie, puede volverse loco en busca de una causa. Una vez, el autor atormentó durante medio día hasta que se dio cuenta de que el problema estaba en el cable defectuoso, así como en el convertidor caprichoso de la interfaz CP2102. Incluso un microcontrolador con un convertidor de interfaz incorporado, por ejemplo, ATmega32u4, a veces puede ser tan travieso. Cada usuario de Arduino ha notado que los errores al cargar bocetos no son tan raros. A veces, la grabación funciona bien y se detecta un error durante la lectura de verificación. Esto no significa que hubo un error al escribir, el error fue al leer. Ahora imagine que cuando trabaja "por aire" sucederá lo mismo, pero con mucha más frecuencia.
Después de haber intentado diferentes formas de superar este problema, el autor propuso lo siguiente. El dispositivo tiene una memoria flash de 128 kilobytes con interfaz SPI: recibimos datos a través de cables (recuerde que el autor ya tiene un dispositivo con un conector en el lateral), usamos esta memoria como un búfer y enviamos datos a otro dispositivo a través de un canal de radio. Un saludo de Cybiko.
Después de escribir el código para trabajar con el canal de radio, así como la fuente, el gestor de arranque se hizo más largo que 4 kilobytes. Por lo tanto, el valor HFUSE tuvo que cambiarse de 0xDA a 0xD8. Ahora el gestor de arranque puede tener hasta 8 kilobytes de longitud, y la dirección inicial se ha convertido en 0x1E000. Esto se refleja en el Makefile, pero debe tenerse en cuenta al llenar el
gestor de arranque con avrdude.
El transceptor estándar 802.15.4 en el ATmega128RFA1 fue originalmente diseñado para operar en el protocolo
ZigBee , lo cual es bastante complicado, por lo que el autor decidió simplemente transmitir paquetes. Este es un hardware implementado en el ATmega128RFA1, por lo que se requiere un poco de código. Además, por simplicidad, el autor decidió usar un canal fijo, evitando que lo eligiera incluso manualmente. El estándar 802.15.4 admite 16 canales con números del 11 al 26. Están bastante obstruidos, algunos también se superponen a los canales WiFi (rojo indica canales ZigBee, azul, verde y amarillo - WiFi).

Resultó que los canales 15 y 26 son los menos susceptibles a la interferencia de WiFi. El autor eligió el segundo de ellos. Descargo de responsabilidad: el traductor no sabe si ZigBee está tan simplificado. ¿Quizás valga un poco más de programación y su implementación completa?
En el primero de los dispositivos, es necesario implementar una máquina de estado que transmita datos utilizando el protocolo STK500. En su mayor parte, los mensajes enviados y recibidos son autosuficientes, pero algunos están vinculados a los que han pasado por el canal anteriormente.
Aquí se da una descripción del diálogo.
Un componente importante de este diálogo es la transferencia de paquetes destinados a la escritura en la memoria flash del dispositivo de destino. Los microcontroladores simples de la familia AVR tienen un tamaño de página de 128 bytes, pero ATmega128RFA1 tiene un tamaño de 256. Y la memoria flash que se conecta a través del protocolo SPI tiene el mismo tamaño. El programa en el primer dispositivo al verter el boceto no lo transfiere inmediatamente al segundo, sino que lo escribe en esta memoria. Cuando el IDE de Arduino verifica la corrección de la grabación, le envían lo que está escrito allí. Ahora debe transferir los datos recibidos por aire al segundo dispositivo. Al mismo tiempo, el cambio de recepción a transmisión y viceversa ocurre con bastante frecuencia. El protocolo STK500 es indiferente a los retrasos, pero no tolera la pérdida de datos (extraño, pero se dice anteriormente que los retrasos en la transmisión de datos también afectan). Y las pérdidas en la transmisión inalámbrica son inevitables. ATmega128RFA1 tiene una implementación de hardware incorporada de solicitudes repetidas con dudas sobre la transmisión correcta, pero el autor decidió implementar la misma mediante programación por su cuenta. Desarrolló un protocolo en el que pasan muchos más datos en una dirección que en la otra.
Es imperfecto, pero todo funciona. Una página de 256 bytes se divide en cuatro segmentos, cada uno de los cuales se transmite por el aire como un paquete. Un paquete contiene hasta 125 bytes de datos más un byte de longitud y dos CRC. Entonces, los fragmentos de 64 bytes de longitud junto con los números de página y segmento (de 0 a 3) se colocan allí. En el dispositivo receptor, se proporciona una variable que le permite rastrear cuántos segmentos se reciben, y cuando llegan los cuatro, se envía una confirmación al dispositivo emisor de que se ha recibido toda la página. Sin confirmación (CRC no coincide): envíe de nuevo toda la página. La velocidad al mismo tiempo resulta incluso más que cuando se transmite por cable. Ver:
Pero en realidad, sería necesario proporcionar una forma conveniente de conectar el cable a los dispositivos para cargar bocetos y en él. Por ejemplo, coloque dentro de dicho convertidor de interfaz en CP2102, como en la foto, y péguelo a la placa para que pueda soportar la fuerza al conectar y desconectar el cable Micro USB.

También tiene un estabilizador de 3.3 voltios (y cómo usarlo en un dispositivo con fuente de alimentación de 6 voltios, si solo hay el mismo estabilizador, y puede agregar dos diodos para elegir automáticamente desde cuál se alimentará el dispositivo). Los tres LED deben retirarse de la placa del convertidor de interfaz, de lo contrario cargarán adicionalmente las baterías cuando trabajen desde ellos, y también interferirán con el sondeo del teclado y trabajarán con la memoria flash con la interfaz SPI.
La consecución del objetivo resultó ser aún más interesante que su logro (y no necesitas esa broma sobre el autobús). El autor aprendió mucho sobre cargadores de arranque para AVR, memoria flash con SPI, protocolo STK500 y estándar 802.15.4.
El resto del código además de la biblioteca descrita anteriormente está
aquí , y también está bajo GPL v3. El twitter del autor está
aquí .