Programación e intercambio de datos con ARDUINO a través de WIFI a través de ESP8266 Segunda parte

Les ofrezco, queridos lectores de GeekTimes, el siguiente artículo del ciclo (espero que no sea el último) sobre el uso del chip ESP8266 como puente inalámbrico para microcontroladores AVR, utilizando la plataforma de hardware Arduino Uno (Nano) como ejemplo.

Después del primer artículo sobre este tema, recibí muchas respuestas amistosas, tales como: "¿Por qué demonios tomaste arduine si todo se podía hacer exclusivamente en ESP8266?" O "¿Por qué, tonto, no usaste esp-link "? "¿En serio por qué?" - Pensé, y ya salí de este artículo y actualicé varios de mis programas como nuevos argumentos.

Entonces, conozca al programador inalámbrico para microcontroladores AVR BABUINO versión 0.9



Detalles debajo del corte:

La versión original del programa se publicó en un artículo anterior y, en principio, hizo casi lo mismo que la nueva versión. Pero se distinguió por inconvenientes extremos en el trabajo. Como, sin embargo, y compitiendo esp-link. Por lo tanto, con un suspiro, atornillé la GUI a JAVA. Ahora puede seleccionar de forma segura el archivo que necesita descargar a través del administrador de ventanas, así como editar la dirección IP del dispositivo de destino. Todavía ingresé el número de puerto TCP estrictamente (solo se edita en el código), pero en teoría, solo debe cambiarse si este puerto se usa en otro lugar (pero también tendrá que cambiar su número en el firmware ESP8266).

El microcontrolador también se usa hasta ahora con uno con un tamaño de memoria FLASH de 32 KB, este, por ejemplo, es el conocido Mega328P. Como, como mencioné en un artículo anterior, en teoría, mi programador cose versiones en 16 kbytes, y tal vez incluso en 8 kbytes. Bueno, por supuesto, en las versiones de AVR de 64 kB y 128 kB, incluso puede flashear los primeros 32 kB de memoria. Pero no tengo esos microcontroladores en mis manos y no puedo decir cómo es realmente. El punto es que 16 bits de direcciones en los comandos de programación SPI estándar están tan inteligentemente divididos y cortados (bit aquí, bit there) que no es fácil entender cómo será todo con un tamaño de memoria diferente a 32 kbytes.

Sí, el programa no se verifica después de la grabación, los registros AVR especiales no son legibles, EEPROM tampoco escribe. Pero todo esto es teóricamente posible sin problemas (en contraste con las limitaciones fundamentales de descargar código a través de UART, como en esp-link). Puede agregar, no me importa, el producto no es comercial.

Aquí está el archivo ejecutable para Windows de 64 bits . Puede extraer el código Java de él. O tomar github

Entonces, comencemos.

Entonces todo es simple, abra el archivo HEX que necesita (sí, el programa aprendió a convertir el formato BIN a HEX, ¡salud!) Ingrese la dirección IP ESP8266 que necesita y haga clic en "Cargar" (cómo encontrar la dirección IP del módulo ESP es una historia aparte). Si el programador encuentra ESP8266, entonces rápidamente (mucho más rápido que esp-link) inserta su código en él y lo envía más al microcontrolador AVR a través de la interfaz SPI. El programador describe en detalle sus acciones en la ventana e incluso se puede confiar en él, excepto que el programa se grabó en AVR. Como ya dije, no hay verificación del registro, pero la interfaz SPI es puramente sincrónica, generalmente no le importa si hay alguien en el segundo extremo de la línea o no. Lanza datos, pero no espera una respuesta.

Después de cerrar el programa (mediante "Detener" o simplemente cerrar la ventana), los datos que ingresó (si presionó el botón Cargar antes) se almacenan en el archivo tcp_dat.txt en el directorio raíz de la unidad C, por lo que la próxima vez que lo abra, no tendrá que preocuparse mucho, nuevamente para reclutar. En general, la ventana del programa puede no estar cerrada. Por experiencia, no molesta a nadie.

Ahora pasemos al lado del módulo ESP y recordemos de nuevo, ahora en detalle, cómo conectarlo al AVR y de qué manera flashearlo, para poder usar el programador mencionado anteriormente, y también simplemente conducir datos a través de WI-FI de forma inalámbrica.

Entonces, lo primero es el diagrama de conexión. Tenga en cuenta que necesitamos ESP8266 en versiones con una cantidad suficiente de GPIO. Necesitaremos conclusiones gratuitas en RESET, MOSI y SLK para programar en la interfaz SPI, además del hecho de que para el intercambio de datos también usaremos el UART habitual con sus RX y TX. Para esto, el ESP8266-07 parecía el más conveniente por el precio y la calidad.

Lo tomamos e inmediatamente soldamos dos resistencias con un valor de 5-10 kOhm. El primero en EN (CH-PD) y potencia, el segundo en GPIO15 y tierra



Ahora puede conectarlo al adaptador, a través del cual cargaremos el firmware de NodeMCU y luego nuestro gestor de arranque LUA.



Un millón de adaptadores, toma cualquiera. Conectamos, como siempre, RX c TX y viceversa. Hacemos que la tierra sea común. Suministramos energía al ESP8266 por separado, y su adaptador del puerto USB es suficiente. Lanzamos cero en GPIO0 y completamos el último firmware de NodeMCU (puede obtenerlo aquí , o crear el suyo propio) a través del programa PyFlasher NODE MCU .



Todo esto, en principio, se describe en el artículo anterior y muchas veces en Internet. A continuación, eliminamos el cero de GPIO0 (puede dejarlo colgado, está bien) y abrimos el entorno ESPlorer para depurar y descargar programas en Lua. Es cierto que esta infección sin el entorno JAVA no funciona. Así que esto (¡ Descargue Java en su computadora de escritorio ahora! ) Tendrá que estar preinstalado de todos modos.

Después de conectarse a ESPlorer, formateará ligeramente el módulo ESP y le informará con los mensajes apropiados. (lo principal es no tocar nada en este momento), y luego ESP se reiniciará. Puede comenzar a trabajar en la descarga de programas LUA.



Y tendremos el siguiente programa:

Cargador de arranque para AVR en Lua en ESP8266
function InstrProgrammingEnable () -- instruction for MC "enable programming" p=0 while p<31 do p=p+1 pin=8 gpio.write(pin, gpio.LOW) spi.send(1, 0xAC,0x53) read = spi.recv( 1, 8) spi.send(1,0,0) gpio.write(pin, gpio.HIGH) if (string.byte(read)== 83) then --print("connection established") p=33 if(p==31) then --print("no connection") end end end end function ProgrammingDisable () pin=2--END OF RESET FOR MK GPIO4 gpio.mode(pin, gpio.INPUT) pin=8 gpio.mode(pin, gpio.INPUT) -- CE chip enable not used GPIO15 pin=5--CLK MASTER for SPI GPIO14 used gpio.mode(pin, gpio.INPUT) pin=6--MISO MASTER for SPI GPIO 12 may not used gpio.mode(pin, gpio.INPUT) pin=7--MOSI MASTER for SPI //GPIO13 used gpio.mode(pin, gpio.INPUT) end --PROGRAMMING ENABLE function ProgrammingEnable () pin=2-- RESET FOR MK gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.LOW) pin=2--POZITIV FOR 4MSEC RESET FOR MK gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.HIGH) tmr.delay(4) gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.LOW) tmr.delay(25000) end function InstrFlashErase() pin=8 gpio.write(pin, gpio.LOW) spi.send(1,0xAC,0x80,0,0) gpio.write(pin, gpio.HIGH) tmr.delay(15000) pin=2--RESET FOR MK gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.HIGH) tmr.delay(20000) gpio.write(pin, gpio.LOW) --print( "FLASH is erased") InstrProgrammingEnable () end function InstrStorePAGE(H, address, data) pin=8 gpio.write(pin, gpio.LOW) spi.send(1,H,0,address,data) gpio.write(pin, gpio.HIGH) tmr.delay(500) end function InstrWriteFLASH(page_address_low,page_address_high) pin=8 gpio.write(pin, gpio.LOW) spi.send(1,0x4C,page_address_high,page_address_low,0) gpio.write(pin, gpio.HIGH) tmr.delay(5000)--        end function Programming (payload) pin=8--CS MASTER for SPI gpio.mode(pin, gpio.OUTPUT, gpio.PULLUP) pin=4--LED LIGHTS ON LOW gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.LOW) --print(string.len(payload)) page_count = 7 --  1  for k =0 ,page_count ,1 do--quantity of pages for i=0 , 127, 2 do-- -1 address = i/2 data=payload:byte(i+1+128*k) if data == nil then data = 0xff end InstrStorePAGE(0x40,address,data) -- tmr.delay(100)-- otherwise not in time write data =payload:byte(i+1+1+128*k) if data == nil then data = 0xff end InstrStorePAGE(0x48,address,data) -- tmr.delay(100) end page_address_low=bit.band(k ,3)*64 -- 3   11 page_address_high=k/4+frame1024*2 tmr.delay(1000) InstrWriteFLASH(page_address_low,page_address_high) tmr.wdclr() end pin=4--LED gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.HIGH) end --MAIN BLOCK wifi.setmode(wifi.STATION) --wifi.sta.config("SSID","password ") -- set SSID and password of your access point station_cfg={} tmr.delay(30000) station_cfg.ssid="SSID" tmr.delay(30000) station_cfg.pwd="Password" tmr.delay(30000) wifi.sta.config(station_cfg) tmr.delay(30000) wifi.sta.connect() tmr.delay(1000000) --print(wifi.sta.status()) --print(wifi.sta.getip()) while ( wifi.sta.status()~=1 ) do if( wifi.sta.status()==5) then break end end prog_address=""; sv=net.createServer(net.TCP,30) tmr.delay(100) --print("SERVER READY") sv:listen(40000,function(c)-- ,   c:on("receive", function(c, payload) --print(payload) if (payload =="program\r\n") then c:send("ready\r\n") --print("ready for program\r\n") tmr.wdclr() spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8,80,spi.FULLDUPLEX) --  SPI 320  115 000  -- 80    1  ProgrammingEnable () tmr.delay(100) InstrProgrammingEnable () tmr.delay(100) InstrFlashErase() tmr.delay(100) frame1024=0--   st=net.createServer(net.TCP,30)--         AWR,   stop program st:listen(40001,function(c) c:on("receive", function(c, payload) tmr.wdclr() Programming (payload) frame1024=frame1024+1 end) end) end if (payload =="data\r\n") then tmr.wdclr() c:send("ready\r\n") -- print("ready for data\r\n") c:on("receive", function(c, prog_address_payload) prog_address=prog_address_payload-- IP  UDP       -- print(prog_address) c:send(prog_address) srv=net.createUDPSocket()--     ,   data stop srv:listen(50000) uart.setup(0,9600,8,0,1,0) srv:on("receive", function(srv, pl) --      UDP pl=pl*1 -- print(pl) uart.write(0,pl) --    UART  AVR end) uart.on("data", 1, function(data) --    UART  AVR srv:send(50000,prog_address,data) --    UDP   end, 0) tmr.wdclr() end) end if (payload =="stop data\r\n") --      then ready = false if(srv~=nil) then srv:close() -- print("stop data") end collectgarbage() end if (payload =="stop program\r\n") then if(st~=nil) then st:close() frame1024=0 ProgrammingDisable () -- print("stop program") end collectgarbage() end end) end) 


Es casi lo mismo que se describe en la primera parte, pero ahora no solo puede transmitir el flujo de datos desde la computadora al microcontrolador AVR, sino que ahora lo hace en la dirección opuesta.

En el proceso de escritura, tuve que resolver un inconveniente interesante. Cuando enviamos datos desde una computadora al ESP8266 usando UDP, no hay problemas. Se conoce la dirección IP del módulo ESP (la manejamos nosotros mismos al principio, si es así), se conoce el puerto, todo está bien. Pero cuando intentamos enviar datos en la dirección opuesta, no podemos hacer esto, ya que el módulo ESP no conoce la dirección IP de la computadora en la que se ejecuta el programador. Más bien, él lo conoce, porque antes de eso establecemos contacto a través del protocolo TCP para enviar comandos de control (programa, datos, detención). Y cuando se usa este protocolo, los dispositivos intercambian sus direcciones, porque es bidireccional. Pero aquí no se lo dirá. En cualquier caso, no encontré en las funciones API de NodeMCU para sacarlo. Por supuesto, puede conducir la IP de la computadora directamente al gestor de arranque en el ESP8266, pero esta no es una opción. De repente, ejecutamos un programa para intercambiar datos en otra computadora. O tiene más de una tarjeta de red.

Entonces hice una muleta. Transferimos la IP de la computadora en la que se ejecuta el programa explícitamente antes de comenzar el intercambio de datos. En la API de JAVA, afortunadamente, existe una función para determinar la dirección de red del host en el que se ejecuta el programa. ESP8266, después de haber recibido esta dirección, ahora puede enviar fácilmente datos no solo a AVR, sino también desde él. En cuanto al programa LUA, es muy simple, ingenuo y simple, y esto se debe al hecho de que en este idioma todavía estoy muy mal orientado.

Entonces, con la ayuda de ESPlorer, registramos el gestor de arranque actualizado en ESP8266. No olvide nombrar inicialmente el archivo como init.lua o renombrarlo a través de ESPlorer, de lo contrario no despegará . Bueno, por supuesto, martillee en el cuerpo (donde está el BLOQUE PRINCIPAL) del gestor de arranque su nombre de red y contraseña.

A continuación, debemos determinar y corregir la dirección IP del módulo ESP en nuestra red interna. Entramos en el enrutador local bajo derechos de administrador y vemos algo así.



Esta dirección sigue siendo dinámica (es decir, después de volver a conectarla se le puede asignar una diferente), por lo tanto, la asociamos con la dirección MAC ESP8266 en el mismo lugar en el enrutador.



Incluso puede escribirlo (últimos dígitos) en el propio módulo, si tiene esclerosis.



El módulo ESP está listo para funcionar, puede conectarlo con un microcontrolador AVR.



Lanzamos BABUINO, escribimos la dirección IP del módulo ESP, seleccionamos el archivo HEX (algunos PARPADEAMOS), presionamos “Cargar” y disfrutamos del parpadeo del LED. El programador escribirá en su ventana, algo como esto:



Pero a veces esto puede suceder si el módulo ESP está en silencio por alguna razón:



Ahora veamos cómo nuestro cargador de arranque conectado en ESP8266 puede intercambiar datos en ambas direcciones. Para hacer esto, controlaremos el carro robótico desde el teclado de la computadora, y nos enviará su camino recorrido. Mi primer carro robótico de cuatro ruedas murió al morir el valiente, recibiendo una señal del Cosmos y cayendo de la mesa (este hecho astral se explicará más adelante). Por lo tanto, hasta que un nuevo marco acrílico provenga de China, se realizarán experimentos en un carro robótico de dos ruedas, que, por cierto, he estado tratando de forzar el equilibrio sobre dos ruedas de año en año, pero hasta ahora sin éxito. De acuerdo con el esquema de conexión electrónica y el programa para AVR, estos carros no difieren, lo que utilizaremos.



El programa para el carrito está escrito en C y no debería causar grandes dificultades de comprensión. Constantemente estamos escribiendo un nuevo valor de velocidad en los registros PWM del controlador, y da señales a los motores. Hay un circuito de retroalimentación en el ADC interno del microcontrolador. Cuando el voltaje de la batería disminuye, la velocidad aumenta mediante programación. Debido a esto, hasta el descenso completo, el carro se desplaza a una velocidad constante. La conclusión es que cuanto más denso es el llenado de PWM, más rápido giran los motores, pero como el voltaje de la batería cae con el tiempo, giran más lentamente. Luego, el llenado de PWM aumenta y giran nuevamente más rápido. Y así, hasta que el llenado PWM sea del 100%, es decir, la salida será constantemente lógica "1". No hay nada que puedas hacer al respecto. Para cargar!

Programa C para el microcontrolador AVRmega328P
 /* * TWO_WEELS_ROBOT_NEW.c * * Created: 22.09.2017 23:48:49 * Author : User */ #define F_CPU 16000000 #include <avr/io.h> #include <stdint.h>//    #include <avr/interrupt.h> #include <math.h> //  #include <stdio.h> // - #include <setjmp.h> #include <stdlib.h> //  volatile uint8_t Speed_of_ADC_conversion=0; volatile uint8_t U_BATTERY; //        volatile uint8_t avr_speed=30;//  ,        //  8      - 110 //  ,  53.  10   volatile uint8_t komanda_s_kompa = 0; volatile uint8_t transmition_ready = 0; volatile uint8_t wheel_counter=0; #define Left_Speed OCR0A //    #define Right_Speed OCR0B //    void time_delay(long dell)//     //     { long i; cli(); sei(); dell=dell*1500; for(i=0;i<dell;i++){;;}; } ISR(USART_RX_vect) //    UART { komanda_s_kompa=UDR0; } ISR(PCINT1_vect )//PC2 int 10 //    { transmition_ready=1; wheel_counter++; } ISR(TIMER0_OVF_vect)//      30 , //     ,       90  { Speed_of_ADC_conversion++; if (Speed_of_ADC_conversion<2) {ADCSRA |=(1<<ADSC);}//   if(Speed_of_ADC_conversion>2)//    { ADCSRA &=~(1<<ADSC); Speed_of_ADC_conversion=0; U_BATTERY = ADCH;////    //      ,   1/3  //         //.  U = 8  (2   - LN298 1 ) = 7  / 2 //  3,5 ..      ,      1  if(U_BATTERY<=avr_speed)//   {Right_Speed++;//   -  ,    Left_Speed++;} else {Right_Speed--;//  ,   Left_Speed--;} } } void stop() { PORTD|=(1<<PORTD3); PORTD|=(1<<PORTD2); PORTD|=(1<<PORTD4); PORTD|=(1<<PORTD7); } void go_left() { PORTD|=(1<<PORTD3);//   PORTD&=~(1<<PORTD2); PORTD|=(1<<PORTD4);//   PORTD&=~(1<<PORTD7); } void go_right() { PORTD|=(1<<PORTD2);//   PORTD&=~(1<<PORTD3); PORTD|=(1<<PORTD7);//  PORTD&=~(1<<PORTD4); } void go_ahead()//   { PORTD|=(1<<PORTD3);//  PORTD&=~(1<<PORTD2); PORTD|=(1<<PORTD7);// PORTD&=~(1<<PORTD4); } void go_back()//   { PORTD|=(1<<PORTD2);//   PORTD&=~(1<<PORTD3); PORTD|=(1<<PORTD4);//   PORTD&=~(1<<PORTD7); } int main(void) { cli(); // UART  9600 UCSR0A=0; UCSR0B=0b10011000; UCSR0C=0b00000110; UBRR0L=103; UBRR0H=0; //   INT0   2   10 PCICR|=(1<<PCIE1);//   14-8 PCMSK1|=(1<<PCINT10);//    INT10 DDRC&=~(1<<PORTC2); //        PORTC|=(1<<PORTC2); //      ADC1, ADMUX= 0b01100001; // V ref  5 ,   ADC1     ,  2 ADCSRA=0b10010110;//       ADCSRB=0; DDRC&=~(1<<PORTC1);// / //   0       ,  B  TCCR0A |=(1<<COM0A1)|(1<<COM0B1);//   TCCR0A &=~(1<<COM0A0)&~(1<<COM0B0); TCCR0A |=(1<<WGM00); TCCR0B &=~(1<<WGM02)&~(1<<WGM01);//   c   TCCR0B|=0b00000101; //   30  // CS02 CS01 CS00 - 000 - ; 001  ; 010 c  8; // 011 -64; 100 -256; 101 -1024 TIMSK0|=(1<<TOIE0);//    0   DDRB|=(1<<5);//    DDRD=0b11111110; //       , RX   PORTD&=~(1<<PORTD5)&~(1<<PORTD6); //     Left_Speed=10;//        Right_Speed=10;//      ( 8-12 ) sei(); PORTB |=(1<<5);//   time_delay(500); PORTB &=~(1<<5); time_delay(500); PORTB |=(1<<5); time_delay(500); PORTB &=~(1<<5); time_delay(500); PORTB |=(1<<5); while (1) { if( (UDRE0)){ if(transmition_ready==1)//      { UDR0=wheel_counter; transmition_ready=0; } } switch (komanda_s_kompa) { case 2: go_right(); break; case 1: go_left(); break; case 3: go_ahead(); break; case 4: go_back(); break; case 5: avr_speed++; if (avr_speed>100) { avr_speed=100; } time_delay(200); //  break; case 6: avr_speed--; if (avr_speed<0) { avr_speed=0; } time_delay(200);//  break; case 0: stop(); break; } } } 


La ruta atravesada se considera un interruptor de láminas, que lanza una interrupción externa INT10. Tan pronto como se incrementa la ruta, los datos se vierten inmediatamente en el UART. En consecuencia, las señales de control (adelante, atrás, izquierda, derecha, gas, freno, parada) provienen del UART en la dirección opuesta.

Tenga en cuenta que los motores chinos son ruidosos con una potencia terrible, por lo que no ayudan los condensadores de potencia. En el circuito de láminas, se induce tal interferencia que parece que su carro está participando en la Fórmula 1 en términos de velocidad de la ruta. Ahorra, solo un condensador de 22 nF en la entrada de una interrupción externa se traga esta interferencia.

El programa de dirección del carro en sí fue tomado de un artículo anterior, donde anteriormente había operado con un brazo mecánico. Solo se hicieron pequeñas adiciones: dos cuadros de texto, donde puede ver en tiempo real, los datos recibidos y enviados (1,2,3,4,5,6,0 - adelante, derecha, izquierda, atrás, gas, freno, parada) , así como la capacidad de editar y guardar la dirección IP del módulo ESP a través de la GUI y el botón "Conectar". Controlamos el carrito con las flechas desde el teclado o con el mouse en la ventana. Es cierto, dado que todos los botones están en un ciclo, cambiar la velocidad y la dirección al mismo tiempo no funcionará, solo uno a la vez. Pero, por supuesto, esto es solo porque el programa es una demostración.



El archivo ejecutable para Windows de 64 bits . Puede extraer el código Java de él. O enfréntate al github .

Ahora que el programador y el intercambio de datos han sido probados (en general, probablemente, he flasheado AVR a través de WI-FI al menos cien veces de esta manera), entonces podemos volver a la pregunta de por qué elegí este camino por mí mismo, y no esp-link.

Entonces, comencemos con la instalación.

Parpadear el módulo ESP es un poco más complicado que el de un competidor. Primero cosimos NodeMCU, luego llenamos el gestor de arranque en el LUA. En esp-link cosimos solo un firmware. Pero el tiempo que pasamos aquí es de una sola vez. En el futuro, no tocamos el módulo ESP. Por otro lado, en nuestro caso, podemos terminar mi programa de roble en LUA, como queramos, agregar nuestros propios módulos, etc. etc. Con esp-link es más difícil. Allí, el conocimiento de los conceptos básicos de LUA y la API NodeMCU ya no funcionará.

En el lado de la computadora, todos los beneficios de BABUINO. Simplemente ejecute el ejecutable y trabaje. Incluso un entorno JAVA no es necesario si tiene una versión de Windows de 64 bits (pero luego necesita un disco de 200 MB). Y si tiene Linux o Mac OS, puede consultar el eslogan de Oracle sobre su Java, "Está escrito en un lugar, funciona en todas partes", porque la máquina virtual Java y el código de bytes son los mismos. Pero, para ser sincero, no lo comprobé, no lo sé.

Con esp-link encontrarás bailes nobles con panderetas, según la instalación del gerente de Tibbo (lo sé por experiencia). Este es un programa para soportar el puerto COM virtual. Requiere ajustar un montón de parámetros y una presencia constante en el sistema. Inmediatamente improbable que funcione, prepárate. Luego, a través del navegador, debe configurar el módulo ESP en sí. Es importante en todas partes, incluso en Tibbo, establecer las tasas de intercambio de datos correctas y cualquier bit de parada y paridad.

Después de eso, ya a través del Arduino Uploader estándar (desde el que duermo ... tomé el diseño) o a través del Arduino IDE (nuevamente configurando COM), comenzamos a cargar el programa muy AVO. No, realmente, realmente se carga para siempre. Incluso si es pequeño. Puedes ir a hacer té durante este tiempo. El signo negativo se cae periódicamente, dejándolo completamente perdido en cuanto a por qué no se realizó la descarga. Y luego solo hay una salida: reiniciar, reiniciar, reiniciar, reiniciar ...

Y BABUINO lanza mucho más rápido, como un programador SPI normal (y los archivos que caben en un paquete de 1024 bytes son generalmente instantáneos). Es cierto que no se verifica. Pero esto es reparable y de todos modos no tomará mucho tiempo, ya que se llevará a cabo simultáneamente con el firmware (una buena característica del protocolo SPI). Además, tenemos acceso a todos los comandos de programación SPI: fusibles y bits de bloqueo, firmware EEPROM, etc. Y si la grabación falla, entonces verá todas las razones en el cuadro de texto. Nota Los comandos están disponibles, pero aún no hay implementación. Ups

Esto es para programación inalámbrica. Ahora pasemos a la transferencia de datos. En este sentido, no utilicé esp-link, por lo que mi razonamiento será puramente teórico.

Entonces, esp-link usa hasta donde yo sé el protocolo MQTT. En esencia, esto es solo una abstracción del siguiente nivel sobre TCP.



Sin entrar en sutilezas, veamos por qué es necesario.

Bueno, por ejemplo, cuando tienes muchos dispositivos en algún tipo de hogar inteligente que funcionan con este protocolo. Cuando tienes algo, va a la nube y regresa. Cuando se integra en algún tipo de red que se ejecuta en MQTT. Cuando tiene un proyecto conjunto, para no inventar algo propio, sino utilizar algo ya conocido y colegas conocidos.

Y si solo necesita enviar el flujo de bytes de vuelta allí sin cables, entonces, ¿para usted qué dificultades tiene? ¿Por qué apilar otro protocolo desde arriba?

Aunque, por supuesto, no niego la utilidad de los protocolos MQTT en general e incluso trato de integrar su soporte en mi cargador de arranque-intercambiador en los siguientes desarrollos y artículos. Pero aunque no lo necesito, buscaremos más. Y si lo necesitas, decide por ti mismo.

Mientras tanto, mi carrito gira obedientemente las ruedas en la dirección correcta y envía telemetría de la distancia recorrida a la computadora (tenga en cuenta que el firewall de la computadora puede no permitir paquetes con ESP). La próxima vez intentaremos controlarlo desde un teléfono móvil. Traté de equilibrarlo sobre dos ruedas desde el teclado, pero la experiencia no tuvo éxito. Existe la idea de utilizar los acelerómetros de un teléfono inteligente para esto (intenté usar una placa separada con un giroscopio y un acelerómetro, pero no despegó).

Volvamos a la segunda pregunta, que se planteó repetidamente durante la discusión del artículo en los comentarios. “¿Por qué no hacer todo en ESP? Ella puede! Y dejemos que AVR sea como un expansor de puerto y suficiente de él ”.

¡Por supuesto que puede! Aunque todo es lo mismo, como puede ver, AVR es indispensable.

Sí, ella puede si:

1. Usted es un programador hereditario orientado a objetos al que le encanta envolverse en todo tipo de envoltorios, hacer devoluciones de llamada y no imaginar la vida sin tablas meta.

2. Conoces bien los detalles del trabajo de diferentes sistemas operativos. Y solo escupe para aprender que el nuevo sistema operativo ahora es RT (en tiempo real), sus llamadas al sistema y bibliotecas escritas por los chinos para un plato de arroz.

3. En la universidad, su conocimiento de los microcontroladores se limitaba a uno o dos trabajos de laboratorio, y ni siquiera desea conocer los bits y periféricos allí. Y, en general, para PWM, por ejemplo, es más fácil para usted tomar una biblioteca de software que usar algo de hardware allí.

4. No necesita una respuesta del dispositivo en microsegundos. No, por supuesto, RTOS puede intentar proporcionarlo, ya que es un sistema operativo en tiempo real. Pero no el hecho de que proporcionará.

5. No tiene cientos de kilobytes de código ya escrito y, lo que es más importante, ya funciona sin fallas en AVR y no necesita portarlo y depurarlo en consecuencia, pero es más fácil escribir en el SDK nativo (que también necesita aprender a escupir usando fuentes en inglés) desde cero.

Entonces si. No leas este artículo. Y lo más importante, no escriba comentarios.

Pero si:

1. Has estado jugando con microcontroladores durante muchos años y conoces su arquitectura de memoria.

2. No necesita errores de origen chino incomprensible.

3. Ha escrito y depurado megabytes de código para su larga vida como desarrollador, y no desea volver a escribir y depurar todo nuevamente.

4. No tiene el tiempo o el deseo de aprender en el idioma de un posible adversario el SDK y RTOS nativos de una compañía no muy conocida en el mundo (todavía no es Microsoft), y también esperar y creer en sus parches y actualizaciones.

5. Al programar, no ha salido especialmente para "comenzar si luego hacer mientras cambia al final", y considera que las palabras función lambda y corutina son latinas obscenas.

6. De hecho, para su dispositivo que ya funciona, pero de acuerdo con las tendencias de los nuevos tiempos, solo necesita un puente inalámbrico para identificación, programación e intercambio de datos.

Bueno, usa el ESP8266 para esto. Como un puente inalámbrico. Ellos, ya sabes, usan AVR como un expansor de puertos para ESP. ¡Y haremos lo contrario!



De hecho, no tome mis últimas declaraciones demasiado en serio. Esto es esencialmente solo una broma. Cualquier desarrollador con suficiente experiencia toma su decisión en función de muchos factores, como la velocidad y los parámetros de consumo de energía, el ciclo de vida del dispositivo, la continuidad con los logros pasados, el costo del producto en sí y el costo de la transferencia a una nueva plataforma, confiabilidad, el tiempo requerido para estudiar nuevas arquitecturas, SDK, sistemas operativos, la presencia de empleados con tal experiencia en un proyecto conjunto, etc.

Por lo tanto, es mejor cuando:



Me gustaría que te gustara el artículo. No doy bibliografías, es lo mismo que en el artículo anterior.

PS

Y finalmente, sobre las señales del espacio. Todo el secreto es que al módulo ESP con firmware NodeMCU realmente le gusta enviar todo tipo de información a la consola. Por ejemplo, después de un reinicio de emergencia (y sucede a veces en ESP, créanme, la glucosa sigue siendo la misma). O, por ejemplo, si olvidó eliminar print ("algo allí") del programa en Lu después de la depuración. O cuando aparece la API en desuso (en desuso) (usted cambió el firmware y ahora debería usar una nueva ortografía, por ejemplo, al iniciar el servidor UDP) y ESP siempre le recordará esto. Hasta que reescribas el código.

Y el problema es que todo esto se envía de manera precisa y metódica a la consola, es decir, al puerto UART. Bueno, ¿qué pasa si su puerto UART está esperando un comando o datos en este momento para decirle a su carro que continúe? Entonces su carro puede caerse de la mesa.
Entonces, este punto también vale la pena considerar.

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


All Articles