Al igual que muchos otros productos caseros, utilizo regularmente microcontroladores AVR para todo tipo de manualidades de aficionados. Y gracias al concepto Arduino, estas artesanías ahora también adquieren un aspecto elegante. De hecho, por unos 300-400 rublos, obtenemos una placa multicapa en miniatura con una máscara, serigrafía y con los periféricos para el microcontrolador completamente reproducidos (¡además, en la versión SMD!). No estoy hablando de todo tipo de complementos de la misma serie "Arduino": sensores, controladores, pantallas y conjuntos completos, los periféricos adicionales que tanto necesitamos. Y de nuevo, todo también es económico y tiene un excelente rendimiento. Prácticamente ya no es necesario criar algo y soldar en la "rodilla".
Pero todas estas diversas manualidades de aficionados, naturalmente, requieren
una programación preliminar. Y más adelante, con varias mejoras, constantemente tengo que actualizar estas manualidades. Está claro que es más conveniente hacer esto de forma remota que arrastrarlos constantemente a un programador regular. En general, gracias a la misma plataforma Arduino, hay muchas opciones aquí: Bluetooth, ZigBee, un canal de radio con su protocolo personal, IR e incluso Wi-Fi. Todos ellos le permiten establecer contacto inalámbrico con su microcontrolador. Pero nos detendremos en la última opción. Hay cuatro razones principales:
1: moderno, el Internet de las cosas!
2: hay un enrutador inalámbrico en cada apartamento, registre sus dispositivos en la red doméstica y ¡listo!
3: tus artesanías dan un salto revolucionario en su desarrollo; no solo se pueden programar a distancia, sino que también se pueden comunicar con el mundo que los rodea: el reloj electrónico toma independientemente la hora exacta de los relojes del servidor NTP, los dispositivos ejecutivos se controlan desde el otro extremo de la ciudad o el país, los dispositivos de registro almacenan los datos acumulados en nube, etc. etc.
4: hay una maravillosa serie de chips ESP8266 en los que
no es muy fácil implementar todo esto.
Además, en este artículo, se desmontará y demostrará el uso de un brazo mecánico en servos, programación remota e intercambio de datos con una PC (o lo que sea) con dispositivos basados en microcontroladores AVR. Quiero señalar de inmediato que todos los programas enumerados a continuación son puramente demostrativos y no tienen valor comercial. Por lo tanto, no se aceptan reclamos, como por qué el programador está tan castrado y mal funcional o por qué no hay servicios adicionales en todas partes. Como los códigos están abiertos, cualquiera puede terminarlos a su discreción, pero todavía tengo suficiente para trabajar.
Se supone que el lector ya está familiarizado con los módulos Arduino (escudos) y la conexión y el firmware del ESP8266. De hecho, se ha publicado una gran cantidad de material en la Web que explica los conceptos básicos del trabajo con estos dispositivos y no quisiera repetir aquí. Para los principiantes, al final del artículo hay una lista de enlaces útiles sobre estos temas, donde puedes encontrar mucha información
, por qué no funciona todo para ti . Desde mi experiencia como ex ingeniero electrónico, puedo declarar responsablemente que el 99% de los problemas son los siguientes:
1. Malos contactos. Dado que los escudos "Arduino" implican cambiar entre sí a través de cables del tipo "padre-madre", y no a través de la soldadura, muy a menudo algo, en algún lugar, desaparece. Compruébalo Y de hecho, como dicen, la electrónica es la ciencia de los contactos.
2. Problemas de energía. No suministre 5 voltios de potencia donde se requiere 3.3. A veces, el humo proviene del ESP8266. Aunque, por otro lado, digiere señales lógicas de dispositivos de cinco voltios sin problemas.
3. Problemas con suficiente potencia. ESP8266 tiene una naturaleza vil y a veces puede consumir casi trescientos miliamperios, aunque antes de eso podría satisfacerse con treinta. En consecuencia, el estabilizador frágil de 3,3 voltios de la placa "Arduino", al que no puede sumar nada, está conectado, inmediatamente se hunde a valores microscópicos. Y no puedes entender por qué está funcionando, entonces no.
4. Confusión con conclusiones. Siempre verifique qué señales van a dónde. El receptor RXD debe conectarse al transmisor TXD, así como el TXD a RXD, pero MOSI debe conectarse a MOSI y MISO a MISO, y así sucesivamente.
5. No confíe en las resistencias pull-up en circuito en el ESP8266, siempre lleve los cables a cero o potencia, a través de resistencias externas de 5-10 kilo-ohmios, y no solo un puente. De lo contrario, puede, en el mejor de los casos, obtener un consumo de corriente sin precedentes y luego oler el desagradable olor a plástico quemado.
6. Bajíos de software. Dado que el software para usuarios individuales está escrito por los mismos entusiastas, las fallas del firmware en sí y los errores aparecen periódicamente al actualizar las versiones del mismo firmware. Se trata arrastrándose en los foros relevantes, a veces incluso en inglés. Algunos compañeros incluso afirmaron que el chip ESP en sí estaba húmedo como el clima en San Petersburgo, pero por otro lado también existía la opinión de que desde 2014 (el año en que se lanzó por primera vez), la situación con esto ha mejorado dramáticamente (a diferencia del clima).
7. Fallas misteriosas. Este es un fenómeno raro, pero que consume nervios. Por ejemplo, no tenía un dispositivo remoto "Arduino". Más bien, sucedió pero con errores. Pero funcionó sin errores si un cable del programador colgaba de él (pero sin el programador mismo). "AHA", me dije, y solde un condensador de 15 pF entre el pin de transferencia de datos y el pin de sincronización. Todo funcionó. Pero el día mató.
Entonces, comencemos con el más simple. Tenemos un brazo mecánico MechArm (pero no el que Howard Volovits ensambló) fabricado en China y una computadora personal con Windows. La tarea es flashear remotamente el programa y administrarlo desde la computadora.

Para el controlador de control, tomamos una linda bufanda en miniatura Arduino Nano con una piedra ATmega328P. Esta placa está perfectamente insertada en el brazo mecánico.

Ahora decidimos cómo lo programaremos. Hay tres métodos principales que son más adecuados para el firmware remoto: a través de la interfaz SPI, a través del cargador de arranque incorporado, a través del puerto JTAG.
La opción más fácil es, por supuesto, el gestor de arranque incorporado (gestor de arranque). Esta es una memoria prerregistrada en FLASH, un programa que recibe un código de acuerdo con cierto protocolo (por ejemplo, usando el UART más simple) y lo escribe en la ubicación del programa cargado con comandos especiales. Esto funciona, por ejemplo, el gestor de arranque ARDUINO IDE. Después de un reinicio o inicio, el gestor de arranque espera un tiempo para recibir datos y, si no espera, comienza la ejecución del programa desde la dirección cero. Si llegan los datos, los escribe en la sección del programa. Después del siguiente reinicio, el programa descargado comienza a ejecutarse. En detalle, tal vez lo describí incorrectamente, pero la esencia es solo eso. Como resultado, solo necesitamos tres salidas para la programación: receptor RTD, reinicio RESET y tierra GND. En general, el transmisor TRD también se usa para verificar el programa grabado, pero para aplicaciones de demostración simples (no para una planta de energía nuclear), se puede omitir la verificación.
El cargador en sí está escrito en lenguaje ensamblador, hay ejemplos de cargadores simples en hojas de datos en AVR. Puede excavar un gestor de arranque existente si está en el dominio público y simplemente usarlo de forma preparada si se conoce el protocolo por el cual funciona. La única advertencia es que debe configurar el AVR en un modo especial mediante el parpadeo de los bits de fusibles especiales, que es realizado por un programador normal, y luego también puede coser el cargador de arranque en la memoria del microcontrolador (es decir, no puede hacerlo sin un programador una vez).
La segunda opción es programar a través de la interfaz serial SPI. Aquí no hay un gestor de arranque interno, pero programamos enviando comandos especiales y luego datos a través de la interfaz mencionada anteriormente. Aquí tenemos un gestor de arranque externo, pero aún necesita escribirlo. Además de RESET y GND, se utilizan cuatro salidas MOSI adicionales para la transmisión, datos MISO, sincronización SLK, selección de chips CS. Pero en general, también puede eliminar MISO y CS. Solo se aceptarán datos (entonces no habrá verificación del programa), y solo tenemos un cristal.
Cada enfoque tiene sus pros y sus contras (y no consideré JTAG en absoluto, ya que la vida humana es corta). Pero al final, me incliné hacia SPI porque era demasiado flojo para escribir en ensamblador, pero no encontré cargadores de arranque listos para usar (simplemente no me veía bien).
Para construir un canal inalámbrico, yo, como ya se mencionó, elegí el chip ESP8266 actualmente ampliamente conocido: un microcontrolador, o más bien, un SoC (System-on-Chip) completo del fabricante chino Espressif con una interfaz Wi-Fi. Además de Wi-Fi, se distingue por la capacidad de ejecutar programas desde una memoria flash externa. Y específicamente para mi proyecto, tomé el ESP8266-07 con 512 KB de memoria a bordo.

En general, cualquier ESP8266 es adecuado cuando hay patas adicionales para implementar SPI. Por lo tanto, el ESP8266-01 más simple no nos conviene, ya que tiene muy pocas patas para puertos de entrada / salida. Pero, por otro lado, la diferencia de precio es inferior a cien rublos, y están disponibles por igual. Bueno, las grandes placas de depuración con ESP, donde un montón de periféricos son convenientes, tampoco son adecuados para nosotros, ya que no entran donde queremos empujarlos en nuestro brazo mecánico.
La esencia global de la idea en general fue la siguiente. El cuerpo del programa cargado en el microcontrolador se transfiere de la computadora al ESP de forma inalámbrica a través de WI-FI (dentro de su red doméstica). Y ESP ya por cable utilizando la interfaz SPI escribe este programa directamente en la memoria FLASH del microcontrolador. Luego, naturalmente, lo restablece y permite que se ejecute el programa cargado. Además, el ESP debe tener una unidad independiente, que también gestiona el intercambio de datos con el microcontrolador, ya que queremos no solo programar, sino también intercambiar datos con él. En particular, para un proyecto con MechArm, después de grabar el programa, todavía transmitimos señales de servocontrol para poner esta mano en movimiento. Por lo tanto, en el ESP en sí, es aconsejable que creemos un servidor TCP para la transferencia de programas y un servidor UDP para controlar MechArm. En consecuencia, estos servidores se unen a la red doméstica y escuchan atentamente si hay alguien que quiera cargar un nuevo código en MechaArm o enviarlo a alguien.
Entonces, encontré en la Web que el firmware ya le permite programar AVR a través del aire, pero el problema principal es que para qué más este firmware ya no se puede usar. Después de la programación, nos gustaría comunicarnos con AVR también de forma remota.
Qué software usaremos:
Para PC, escribí todo en JAVA,
IntelliJ IDEA . Pero básicamente, puede hacer cualquier cosa, lo principal para nosotros es escribir un cliente que enviará el programa para flashear AVR a ESP8266.
Yo mismo escribo programas para AVR en
ATMEL STUDIO , en lenguaje C, rara vez en ensamblador. No utilizo bocetos de Arduino en principio, casi cualquier biblioteca necesaria está escrita en una o dos horas, con una comprensión completa de su trabajo. Probé bocetos, pero siempre que no tenga un sistema operativo en el AVR, los bocetos le quitarán periféricos a un amigo y fallarán regularmente. Sí, el IDE Arduino en sí mismo, en comparación con ATMEL STUDIO, es, por supuesto, algo muy primitivo. Pero aquí la pregunta es, por supuesto, controvertida, para las humanidades y los escolares será más divertido y más fácil, probablemente, con bocetos.
Para programar el ESP8266, utilicé el firmware NodeMCU y escribí programas en Lua. No, me encantaría escribir en Java y C, pero no hay ninguno en ESP. El lenguaje Lu aplicado a nuestra tarea no es difícil, dominar un par de trivialidades. Y en realidad, para descargar programas y depurarlos en ESP, tomé el
IDE ESPlorer . Un producto doméstico gratuito (pero puede donarlo al autor), que por supuesto no se puede comparar con los medios mencionados anteriormente, pero como dice el caballo de regalo ... Pero para usar ESPlorer y escribir en LUA, primero tenemos que cambiar el firmware base (suministrado por el fabricante) en el chip ESP8266 a uno nuevo El programa PyFlasher NODE MCU nos ayudará en esta empresa. Quiero decir, ayudará a volver a actualizarlo. Y crearemos el firmware nosotros mismos y lo pondremos en manos del sitio web de los creadores:
NodeMCU . Y puede leer más sobre este proceso
aquí:Todo es muy accesible y comprensible. Agregamos soporte SPI y operaciones de bit a las bibliotecas base (en LUA, en nuestro caso, las operaciones de bit están sobrecargadas e inútiles). Muchas bibliotecas no deben introducirse en el firmware de las bibliotecas, porque debido a la presencia de cualquier software en el ESP8266, queda muy poca memoria, algún tipo de patético 20 kB.
Por supuesto, puede tomar el firmware terminado, del cual muchos ya están pasando el rato en Internet, pero no lo recomiendo. Al menos porque algunos de ellos no tienen soporte para operaciones de bits (y los necesitamos) y no hay regulación de la velocidad de transferencia de datos a través de SPI.
En consecuencia, se transmiten por defecto a una velocidad de 40 MHz dividida por algún coeficiente pequeño y, por lo tanto, el AVR no tiene tiempo para digerirlos.
Quién es demasiado vago para crear firmware, puede descargar el mío desde la
nube .
Ahora tenemos el firmware y necesitamos cargarlo en el ESP8266 en lugar del base. Para hacer esto, necesitamos un adaptador USB simple: UART.
Conectamos las patas TXD a RXD, y RXD a TXD, hacemos la conexión a tierra común, pero no utilizamos, como parecía, una salida de alimentación de 3,3 V conveniente en el adaptador. En la mayoría de los casos, el ESP8266 lo drenará por completo. Por lo tanto, lo alimentamos por separado. Luego ponemos el ESP en modo de programación (GP0 en el suelo, si alguien lo olvidó) y ejecutamos el
NODE MCU PyFlasher .

Es importante destacar que no olvide borrar la memoria flash (sí, borra todos los datos), de lo contrario, dependiendo de la versión del firmware, después de la programación, puede quedar basura innecesaria en la memoria, que a su vez arrojará basura en la consola durante el trabajo posterior. Antes de eso, usaba software, donde no había opción de borrar la memoria de antemano, estaba terriblemente atormentado, ya que nada funcionaba. Y el ataúd se acaba de abrir, solo la verdad en el foro en inglés de los creadores de NODE MCU.
Habiendo adquirido el firmware necesario, ahora podemos escribir y depurar programas LUA (también hay MicroPython, pero no lo usé) usando API muy convenientes de NODE MCU. Lanzamos el ya mencionado ESPlorer.

También lo configuramos para que funcione con ESP8266, establecemos los parámetros de la conexión en serie. Todo es bastante simple y se menciona repetidamente en Internet.
Ahora escribimos el programa en LUA, que luego cargamos en ESP8266:
Lua bootloader para AVR escrito en ESP8266<b>function InstrProgrammingEnable ()
Donde las funciones relevantes realizan las siguientes acciones:
function InstrProgrammingEnable () : pone el microcontrolador en modo de programación con un comando especial enviado a través de SPI.
function ProgrammingEnable () : solo reinicie AVR durante 25 ms antes de comenzar la programación
function ProgrammingDisable () : después del final de la programación, traducimos las salidas SPI en ESP8266 a un estado inactivo para que no interfieran con nosotros al ejecutar el código en el microcontrolador (de repente se usan allí)
función InstrFlashErase () :
borramos la memoria flash del microcontrolador antes de programar. Por qué esto necesita ser explicado no es necesario.
función InstrStorePAGE (H, dirección, datos) : este comando escribe el byte del programa en el búfer interno del microcontrolador. Pero este no es el registro flash en sí, ya que el flash se escribe aquí página por página a 128 bytes.
función InstrWriteFLASH (page_address_low, page_address_high) - pero este es un registro flash y toma tiempo, preste atención al retraso de 5,000 μs.
Programación de la función (carga útil) : la función más grande e importante que utiliza las funciones anteriores. Toma el programa transmitido en fragmentos de 1024 bytes, los divide en bytes y forma las direcciones para ellos, luego lo envía al microcontrolador en el búfer interno e inicializa el registro flash cada 128 bytes. Luego toma el siguiente kilobyte de código y repite la operación, naturalmente con un desplazamiento en las direcciones, para escribir más y no sobrescribir el grabado. Al principio, intenté reenviar todo el programa, pero cuando supero los 6 kilobytes en ESP8266, la memoria disponible simplemente termina y se bloquea. Un kilobyte resultó ser la unidad más conveniente, ya que se divide cuidadosamente en partes y se transmite convenientemente a través de TCP (aún necesitamos obtenerlo de la computadora). Tampoco se necesita un tamaño mayor, TCP, ya sabes, en la versión actual limita el paquete transmitido a 1500 o bytes (pero por alguna razón me transmitieron 1440, más o menos).
Como si nada complicado, pero algunas trampas tuvieron que ser superadas.
El siguiente es el BLOQUE PRINCIPAL. En ella nosotros:
Estamos registrados en una red inalámbrica.
Primero creamos un servidor TCP que escucha tres comandos:
1. "programa" (programaremos)
2. "datos" (cambiaremos los datos),
3. "parar" (paramos todo).
Si programamos, primero inicializamos el SPI y creamos otro servidor TCP que toma los datos (código de firmware) por kilobyte y llama a las funciones de programación del microcontrolador para ellos. Entiendo que parece tonto crear un segundo servidor, pero esto es una necesidad, porque la API local admite la creación de un solo socket, y necesitamos separar los comandos "programa" y "datos" con los datos transmitidos, porque a simple vista no difieren, hay bytes y Aquí hay bytes.
Si no queremos programar, sino intercambiar datos, enviándolos en nuestro caso al microcontrolador, primero enviamos la cadena "datos" a través de TCP. En respuesta a esto, ya se creará un servidor UDP (le recuerdo que no gestionamos dinámicamente con una mano mecánica y que no necesitamos retrasos con la formación de paquetes TCP, y de hecho enviamos un byte como un sobretono de trama TCP completo). Y los datagramas UDP serán pequeños y se formarán rápidamente.
Después de que se inicializa UART, y cada byte recibido de forma inalámbrica ya se envía a través del cable TXD al microcontrolador, que está obligado a aceptarlo si el programa correspondiente se actualiza allí. El intercambio de datos en otra dirección tampoco es difícil de organizar, pero aún no lo he implementado.
Bueno, con el comando "detener", los servidores mencionados anteriormente (excepto el primero) cierran las conexiones y el servidor principal vuelve al estado de espera de los comandos "programa" y "datos".
Dado que la interfaz SPI se emula mediante programación en ESP8266, puertos de E / S para señales CS, CLK, MISO, MOSI, RESET (para AVR), puede usar cualquiera de los disponibles, y no los indicados en mi gestor de arranque. Además, resultó que CS y MISO, en principio, también se pueden interrumpir en este caso, funcionará sin ellos. Bueno, se usa un pin en el LED incorporado en la placa ESP8266 para que a veces parpadee e indique que el programa aún está activo.
No se realizan comprobaciones de errores de grabación (con la excepción de la primera solicitud a AVR, pero esta información simplemente se muestra en la consola), EEPROM no está programado, no se cosen más de 32 KB; en resumen, aún queda trabajo por hacer. La velocidad de intercambio SPI es de aproximadamente 115 Kbit, en unos segundos todo se muestra, aproximadamente, como con un programador en serie regular como ISP500).
Tome el código, ingrese sus redes y contraseñas, compílelo en ESplorer, llámelo "init" (para que comience en el reinicio) y envíelo a ESP8266. Debería funcionar En el sentido de trabajar como programador inalámbrico, al menos.
Ahora nos ocuparemos de la parte administradora: una computadora personal.
De hecho, necesitamos tomar el archivo HEX en el que se convierten sus programas escritos en el entorno ATMEL STUDIO y enviarlo a través de WI-FI al puerto de socket que conocemos (en este caso 4000). El pequeño inconveniente es que necesitamos un archivo BIN binario para la transferencia, y ATMEL STUDIO solo nos complace con un HEX. Hay dos salidas; o conviértalo a formato BIN con un convertidor de programa especial, como WinHex, o hágalo usted mismo en su programa. Todavía no lo he hecho, pero parece que no es difícil, allí debes cortar el título y hacer otra cosa.
Como resultado, escribí el programa del gestor de arranque en JAVA (principalmente porque no sé cómo hacer nada más), trabajando en el entorno IntelliJ IDEA simplemente hermoso y gratuito. Crea un cliente TCP que busca un servidor que se ejecuta en ESP8266. Si lo encuentra, lo contacta y le envía un archivo ubicado en dicha dirección. El código está abajo.
Descargador de archivos JAVA basado en PC import java.io.*; import java.net.*; import java.util.ArrayList; import java.util.List; public class Net { <b> public static void main(String args[]) { new Http_client(4000); }</b> } class Http_client extends Thread { int port; String s; String Greetings_from_S; Http_client(int port){ this.port = port; start(); } public void run() {
Aquí, por supuesto, se hirió demasiado, no se necesitan todo tipo de preparados, en principio. Si se establece la conexión TCP, entonces se establece. El único problema era que el archivo no quería enviarse en partes iguales de 1024 bytes de ninguna manera, como realmente lo necesitaba, aunque indiqué explícitamente el tamaño. Aparentemente, hay algún tipo de búfer final inaccesible desde JAVA, y envía paquetes del tamaño que desea, lo cual es completamente inaceptable para el lado receptor. Al principio traté de retrasarme para que el búfer se cansara de esperar las siguientes piezas y enviarlo como está. Pero el retraso comenzó a funcionar cuando llegó a 10 segundos, lo que de alguna manera parecía demasiado para un kilobyte transferido.
Pero luego me di cuenta de que, por alguna razón, la primera pieza siempre es suave, cuál fue ordenada, y ya a partir de la segunda comienza una bacanal impredecible. Por lo tanto, hice que el cliente abra la conexión, envíe una porción del código en 1024 bytes y cierre la conexión. Y así sucesivamente hasta que se envíe todo el archivo. Todo funcionó bien.
Lo único para comenzar es instalar el tiempo de ejecución JAVA en la computadora. Pero generalmente empiezo de inmediato con IntelliJ IDEA porque allí siempre puedes ver lo que está sucediendo en la consola (pero aquí necesitas un entorno JAVA). Aunque, por supuesto, de manera inteligente necesita hacer una GUI. Es decir, la ventana donde cae la ruta al archivo, la capacidad de cambiar los números de puerto en la ventana y, bueno, otras cosas necesarias. Y para recopilar todo esto en forma de un archivo ejecutable.
Y tapericha, como solía decir Koroviev, volvamos a los ciudadanos, de hecho, a la extremidad mecánica MechArm, que se mencionó al principio. Ahora tenemos la oportunidad de programarlo de forma remota y luego administrarlo. Pasemos al programa de control al costado del microcontrolador.
En este caso, necesitamos controlar cuatro servos. Aquí están esos.
Tal accionamiento está controlado por pulsos rectangulares de un período de 20 ms (50 Hz) con un factor de trabajo del 2 al 4 por ciento. Es decir, 2% es un giro completo en una dirección, 4% en la otra. La tarea es solo para el PWM integrado en el AVR.

Un servoaccionamiento se usa para moverse hacia la izquierda y hacia la derecha; el segundo sobre uno mismo - de uno mismo; tercero arriba y abajo; el cuarto es la propia garra, que debe comprimirse y expandirse. Todo está escrito en C y compilado en un archivo HEX en ATMEL STUDIO. Un tipo de programa un poco extraño se debe al hecho de que inicialmente la mano se controlaba desde el teclado atado con cables al microcontrolador. Pero los cables de ayer, debemos evolucionar más.
Por supuesto, puede usar bocetos para servos de "ARDUINO", pero no me gustaron. Es más interesante escribirte tú mismo. Además, los cuatro servos deberían funcionar simultáneamente, y no en modo multiplexado, cuando el PWM cambia a cada servo por turno. Porque nadie ha cancelado la gravedad, y una extremidad elevada descenderá inmediatamente si los impulsos de control dejan de llegar al servoaccionamiento correspondiente. No estoy seguro de que el boceto "ARDUINO" proporcione operación simultánea para cuatro servos. Pero nosotros mismos podemos escribir un programa que cumpla con los requisitos necesarios. En general, en ausencia de un sistema operativo que separe a los corderos de las cabras, el uso de bocetos que compiten por los dispositivos periféricos del microcontrolador (y ni siquiera sabemos cuáles de antemano) es demasiado defectuoso.
Aquí está el código en sí que escribimos al Arduino Nano usando el ESP8266-07.
Programa para controlar MechArm para microcontrolador AVRmega328P #define F_CPU 16000000 #include <avr/io.h> #include <stdint.h>// #include <avr/interrupt.h> #include <math.h> // #include <stdio.h> // - #include <avr/eeprom.h> #include <setjmp.h> #include <stdlib.h> // #define UART_BAUD_RATE 115200 // 1 20 #define COUNTER1_OFF TCCR1B=0b00000000 // CS02 CS01 CS00 - 000 - ; 001 ; 010 c 8; 011 -64; 100 -256; 101 -1024 #define COUNTER1_ON TCCR1B=0b00000011 // 0 0 1 #define COUNTER0_OFF TCCR0B=0b00000000 // CS02 CS01 CS00 - 000 - ; 001 ; 010 c 8; 011 -64; 100 -256; 101 -1024 #define COUNTER0_ON TCCR0B=0b00000100 // 2 B2(PD6) 3(PD7) #define COUNTER2_OFF TCCR2B=0b00000000 // CS02 CS01 CS00 - 000 - ; 001 ; 010 c 8; 011 -64; 100 -256; 101 -1024 #define COUNTER2_ON TCCR2B=0b00000110 volatile uint16_t period_20ms; volatile uint8_t State_of_keyboard; volatile uint8_t start_position [6]; volatile int8_t number_servo; ISR(USART_RX_vect)// UART { State_of_keyboard=UDR0; return; } ISR(TIMER0_COMPA_vect)// 0 { PORTB &=~(1<<0); TIMSK0&=~(1<<OCIE0A); TIFR0 |=(1<<OCF0A); return; } ISR(TIMER0_COMPB_vect) // 1 { PORTB &=~(1<<1); TIFR0 |=(1<<OCF0B); TIMSK0 &=~(1<<OCIE0B); return; } ISR(TIMER2_COMPA_vect)// 2(PD6) { PORTD &=~(1<<6); TIFR2 |=(1<<OCF2A); TIMSK2 &=~(1<<OCIE2A); return; } ISR(TIMER2_COMPB_vect)// 3(PD7) { PORTD &=~(1<<7); TIFR2 |=(1<<OCF2B); TIMSK2 &=~(1<<OCIE2B); return; } ISR(TIMER1_OVF_vect){// 20 COUNTER1_OFF; COUNTER0_OFF; COUNTER2_OFF; TIFR0 |=(1<<OCF0A); TIFR0 |=(1<<OCF0B); TIFR2 |=(1<<OCF2A); TIFR2 |=(1<<OCF2B); TIFR1 |=(1<<TOV1); PORTB |=(1<<0)|(1<<1); PORTD |=(1<<6)|(1<<7); TCNT1 = period_20ms; // 20 TCNT0 = 0; TCNT2 = 0; TIMSK0|=(1<<OCIE0A)|(1<<OCIE0B); TIMSK2|=(1<<OCIE2A)|(1<<OCIE2B); OCR0A=start_position[1];// 0 0 OCR0B=start_position[2];// 0 1 OCR2A=start_position[3];// 0 2 OCR2B=start_position[4];// 0 3 COUNTER1_ON; COUNTER2_ON; COUNTER0_ON; return; } void time_delay(long i) { cli();sei(); long k; i*=2000; for(k=0;k<i;k++){;;}; } void timer_counter0_1_2_INIT()// 0,1,2 { // 1 TCCR1A &=~(1<<COM1A0)|~(1<<COM1A1)|~(1<<COM1B0)|~(1<<COM1B1);// TCCR1A &=~(1<<WGM10)|~(1<<WGM11); TCCR1B &=~(1<<WGM12)|~(1<<WGM13);// period_20ms=60575; TCNT1 = period_20ms; TIMSK1|=(1<<TOIE1);//| //TIFR0 TOV0 // 0 TCCR0A &=~(1<<COM0A0)|~(1<<COM0A1)|~(1<<COM0B0)|~(1<<COM0B1);// TCCR0A &=~(1<<WGM00)|~(1<<WGM01); TCCR0B &=~(1<<WGM02);// // 2 TCCR2A &=~(1<<COM2A0)|~(1<<COM2A1)|~(1<<COM2B0)|~(1<<COM2B1);// TCCR2A &=~(1<<WGM20)|~(1<<WGM21); TCCR2B &=~(1<<WGM22);// COUNTER1_ON; } void servo_reset() { start_position[1]=97;// 0 0 start_position[2]=70;// 0 1 start_position[3]=92;// 0 2 start_position[4]=124; // 0 3 COUNTER1_ON; time_delay(100); } void servo_go( int8_t moven, uint8_t servo_position_max, uint8_t servo_position_min)// { switch (moven){ case 1: start_position[number_servo]++; if(start_position[number_servo]==servo_position_max){start_position[number_servo]--;};// +90 break; case 2: start_position[number_servo]--; if(start_position[number_servo]==servo_position_min){start_position[number_servo]++;};//6 -90 break; }; time_delay(20); return; } //PORTB-0,1, PORTD - 6,7 - , 8- COUNTER 0 int main(void) { uint8_t servo_positionmin=0, servo_positionmax=0; int8_t const servo_position1max = 122, servo_position1min=58; // int8_t const servo_position2max = 120, servo_position2min=36;// int8_t const servo_position3max = 125, servo_position3min=68;// int8_t const servo_position4max = 129, servo_position4min=108;// 128 108 sei(); DDRD = 0B11000010; // D2-D5 , D0 RX, D1 TX, D6 D7 3 4 PORTD = 0B00111110; // DDRB |=(1<<0)|(1<<1);// PORTB &=(~1<<0)|(~1<<1); UCSR0A=0;// UART UCSR0B=0b10010000; UCSR0C=0b00000110; UBRR0L=103;// 115200 UBRR0H=0; timer_counter0_1_2_INIT(); servo_reset(); PORTB |=(1<<5); while (1) { switch (State_of_keyboard) { case 1:// 1 PD0(PB0) number_servo=1; servo_positionmin=servo_position1min; servo_positionmax=servo_position1max; break; case 2: // 1 PD0(PB0) number_servo=1; servo_positionmin=servo_position1min; servo_positionmax=servo_position1max; break; case 5: number_servo=2; // 2 PD1(PB1) servo_positionmin=servo_position2min; servo_positionmax=servo_position2max; break; case 6: number_servo=2; // 2 PD1(PB1) servo_positionmin=servo_position2min; servo_positionmax=servo_position2max; break; case 7: number_servo=3;// 3 PD6 servo_positionmin=servo_position3min; servo_positionmax=servo_position3max; break; case 8: number_servo=3;// 3 PD6 servo_positionmin=servo_position3min; servo_positionmax=servo_position3max; break; case 3: number_servo=4; // 4 PD7 servo_positionmin=servo_position4min; servo_positionmax=servo_position4max; break;// case 4: number_servo=4; // 4 PD7 servo_positionmin=servo_position4min; servo_positionmax=servo_position4max; break;// // c - , 4- // , } if(State_of_keyboard==1||State_of_keyboard==3||State_of_keyboard==5||State_of_keyboard==7) { servo_go(1,servo_positionmax,servo_positionmin);// } if(State_of_keyboard==2||State_of_keyboard==4||State_of_keyboard==6||State_of_keyboard==8) // { servo_go(2,servo_positionmax,servo_positionmin);// } time_delay(20); } }
La esencia del programa es clara por el texto y los comentarios. Usamos un contador T1 durante un período ejemplar de 20 ms y T0, contadores T2 para emitir señales PWM a cuatro líneas del puerto de E / S, ya que cada uno de estos dos contadores puede funcionar en dos dispositivos.
El programa establece las posiciones iniciales de los servos mediante la carga de los registros de conteo OCR0A, OCR0B, OCR2A, OCR2B. También se introducen constantes de restricción, ya que no siempre necesitamos un intervalo de 180 grados. Bueno y más, por interrupción de UART, el programa capta el número enviado por ESP8266 (del 1 al 8) y lo traduce en un comando para el servo correspondiente. Hay cuatro unidades, cada una trabajando en dos direcciones, por lo que los enteros del uno al ocho son suficientes. Una vez que se selecciona el número, el contenido de los registros de contador anteriores se incrementa o disminuye, cambiando respectivamente el ciclo de trabajo del pulso de control y el ángulo de rotación del servoaccionamiento seleccionado. Esas unidades que no seleccionamos conservan el valor anterior del ángulo de rotación (ya que el contenido de los registros correspondientes, aunque se actualizaron, no cambiaron) y continúan manteniendo el brazo mecánico en la misma posición.
Ahora solo tenemos que escribir un programa de control, perdón por la tautalogía, para controlar una mano mecánica directamente desde la computadora a través de WI-FI.
El código también está escrito en JAVA, pero un poco ennoblecido. Había una GUI y la capacidad de editar los números de puerto y la dirección de red del ESP8266.

Lo que sucede allí está claro desde la ventana. No
proporciono el texto del programa aquí (está disponible en
Github ), por la siguiente razón: aproximadamente el 95% de su volumen es la creación de ventanas y el procesamiento de señales desde el teclado. Pero la esencia es la misma que el programa anterior en JAVA. Se crea un cliente, solo UDP, que, dependiendo de la tecla presionada, envía un número del 1 al 8, a la dirección especificada en el puerto especificado.
O puede obtener inmediatamente el ejecutable
desde aquí . Para máquinas de 64 bits con Windows. Incluso un entorno JAVA instalado no es necesario. Todo ya se ha metido en 178 MB.
Entonces, la pluma mecánica fue ensamblada, depurada y presentada a su hermano para su aniversario. Puede recoger pilas de plástico con vodka, en Skype desde otra ciudad. Aunque para el brazo mecánico de Howard Volovitsa de la serie "The Big Bang Theory", ella todavía está lejos.
Pero luego, en los siguientes artículos (si alguien está interesado) podremos administrarlo desde un teléfono móvil, hacer lo mismo con un carro robótico de cuatro ruedas y actualizar la hora en relojes electrónicos desde servidores de reloj en Internet. Luego colocamos el viejo teléfono inteligente en el carrito y llevamos el video desde él a la red neuronal con reconocimiento de patrones, y luego las señales de control a los motores,
oh, algo ya me lleva ...Y todo esto con la hermosa ESP8266.
Me alegraría si alguien encontrara el artículo interesante.
[1]
Pinout y especificaciones de ESP8266[2]
Conectando el ESP8266. Inicio rápido[3]
Actualización de firmware de NodeMCU a través de la nube[4]
NODE MCU PyFlasher[5]
ESPlorer - IDE para ESP8266[6]
Programación en C para AVR[7] Revisión de artículos: “Programación de microcontroladores en lenguaje C”[8] Descripción de la API de NodeMCU[9] Referencia de Lua[10] Guiones y módulos de Lua[11] IntelliJ IDEA[12] ¡ Descarga Java a tu computadora de escritorio ahora![13] Estudio Atmel