Como muitos outros produtos caseiros, uso regularmente microcontroladores AVR para todos os tipos de artesanato amador. E graças ao conceito do Arduino, esses artesanatos agora também têm uma aparência elegante. De fato, para cerca de 300-400 rublos, obtemos uma placa miniatura de várias camadas com uma máscara, serigrafia e com os periféricos do microcontrolador completamente divorciados (além disso, na versão SMD!). Não estou falando de todos os tipos de plug-ins da mesma série "Arduino": sensores, controladores, displays e conjuntos inteiros, os periféricos adicionais de que precisamos tanto. E, novamente, tudo também é barato e tem excelente desempenho. Praticamente não precisa mais criar algo e soldar no "joelho".
Mas todos esses vários ofícios amadores exigem naturalmente
programação preliminar. E mais tarde, com várias melhorias, eu constantemente tenho que atualizar esses ofícios. É claro que é mais conveniente fazer isso remotamente do que arrastá-los constantemente para um programador regular. Em geral, graças à mesma plataforma Arduino, existem muitas opções aqui: Bluetooth, ZigBee, um canal de rádio com seu protocolo pessoal, IR e até Wi-Fi. Todos eles permitem que você estabeleça contato sem fio com seu microcontrolador. Mas vamos parar na última opção. Existem quatro razões principais:
1: moderna, a Internet das coisas!
2: existe um roteador sem fio em todos os apartamentos, registre seus dispositivos na rede doméstica e pronto!
3: seus ofícios dão um salto revolucionário em seu desenvolvimento; além de poderem ser programados à distância, eles também podem se comunicar com o mundo a sua volta: o relógio eletrônico leva independentemente o tempo exato dos relógios do servidor NTP, os dispositivos executivos são controlados do outro lado da cidade ou do país, os dispositivos de registro armazenam os dados acumulados em nuvem etc. etc.
4: existe uma maravilhosa série de chips ESP8266 nos quais
não é muito fácil implementar tudo isso.
Além disso, neste artigo, usar o exemplo de um braço mecânico em servos, programação remota e troca de dados com um PC (ou qualquer outro) com dispositivos baseados em microcontroladores AVR será desmontado e demonstrado. Quero observar imediatamente que todos os programas listados a seguir são puramente demonstrativos e não têm valor comercial. Portanto, declarações, como por que o programador é tão castrado e mal funcional ou por que não há serviços adicionais por toda parte, não são aceitas. Como os códigos estão abertos, qualquer pessoa pode finalizá-los a seu critério, mas ainda tenho o suficiente para trabalhar.
Supõe-se que o leitor já esteja familiarizado com os módulos do Arduino (blindagens) e com a conexão e o firmware do ESP8266. De fato, uma enorme quantidade de material foi postada na Web explicando o básico do trabalho com esses dispositivos e eu não gostaria de repetir aqui. Para iniciantes, no final do artigo, há uma lista de links úteis sobre essas questões, onde você pode encontrar muitas informações
, por que tudo isso não funciona para você . Pela minha experiência como ex-engenheiro eletrônico, posso declarar com responsabilidade que 99% dos problemas são os seguintes:
1. Contatos ruins. Como os escudos do "Arduino" implicam alternar entre si através de fios do tipo "pai-mãe", e não através da solda, muitas vezes algo, em algum lugar, desaparece. Confira. E, de fato, como se costuma dizer, a eletrônica é a ciência dos contatos.
2. Problemas de energia. Não forneça 5 volts de energia onde 3.3 é necessário. Às vezes, a fumaça vem do ESP8266. Por outro lado, ele digere sinais lógicos de dispositivos de cinco volts sem problemas.
3. Problemas com energia suficiente. O ESP8266 tem uma natureza vil e às vezes pode consumir quase trezentos miliamperes, embora antes isso pudesse ser satisfeito com trinta. Assim, o estabilizador frágil de 3,3 volts da placa "Arduino", ao qual você pode adicionar até nada, está conectado, afunda imediatamente para valores microscópicos. E você não consegue entender por que está funcionando, então não.
4. Confusão com conclusões. Sempre verifique quais sinais vão para onde. O receptor RXD deve se conectar ao transmissor TXD, assim como o TXD ao RXD, mas o MOSI deve se conectar ao MOSI e o MISO ao MISO, e assim por diante.
5. Não confie nos resistores de pull-up no circuito no ESP8266, puxe sempre os fios para zero ou energia, através de resistores externos de 5 a 10 kilo-ohm, e não apenas de um jumper. Caso contrário, você poderá, na melhor das hipóteses, obter um consumo atual sem precedentes e sentir o cheiro desagradável de plástico queimado.
6. Cardumes de software. Como o software para usuários individuais é escrito pelos mesmos entusiastas, falhas do próprio firmware e erros aparecem periodicamente ao atualizar versões do mesmo firmware. Isso é tratado rastreando-se nos fóruns relevantes, às vezes até em inglês. Alguns camaradas chegaram a afirmar que o chip ESP estava úmido como o clima em São Petersburgo, mas por outro lado, havia também a opinião de que desde 2014 (o ano em que foi lançado pela primeira vez), a situação com isso melhorou drasticamente (ao contrário do tempo).
7. Falhas misteriosas. Este é um fenômeno raro, mas que consome nervos. Por exemplo, eu não tinha um dispositivo "Arduino" remoto. Pelo contrário, aconteceu mas com erros. Mas não houve erros se um cabo do programador estivesse pendurado nele (mas sem o próprio programador). "AHA", disse a mim mesmo, e soldou um capacitor de 15 pF entre o pino de transferência de dados e o pino de sincronização. Tudo funcionou. Mas o dia matou.
Então, vamos começar com o mais simples. Temos um MechArm mecânico (mas não o que Howard Volovits montou) fabricado na China e um computador pessoal com Windows. A tarefa é atualizar o programa remotamente e gerenciá-lo a partir do computador.

Para o controlador de controle, usamos um lindo cachecol em miniatura do Arduino Nano com uma pedra ATmega328P. Esta placa é perfeitamente empurrada para o braço mecânico.

Agora decidimos como vamos programá-lo. Existem três métodos principais mais adequados para firmware remoto: através da interface SPI, através do gerenciador de inicialização incorporado, através da porta JTAG.
A opção mais fácil é, obviamente, o carregador de inicialização embutido (carregador de inicialização). É uma memória pré-registrada no FLASH, um programa que recebe um código de acordo com um determinado protocolo (por exemplo, usando o UART mais simples) e grava-o no local do programa carregado com comandos especiais. Isso funciona, por exemplo, no carregador de inicialização ARDUINO IDE. Após uma redefinição ou início, o carregador de inicialização aguarda algum tempo para receber dados e, se não esperar, inicia a execução do programa a partir do endereço zero. Se os dados chegarem, ele os grava na seção do programa. Após a próxima redefinição, o programa baixado começa a ser executado. Em detalhes, talvez eu tenha descrito incorretamente, mas a essência é exatamente isso. Como resultado, precisamos apenas de três saídas para programação: receptor RTD, reset RESET e terra GND. Em geral, o transmissor TRD também é usado para verificar o programa gravado, mas para aplicações simples de demonstração (não para uma usina nuclear), a verificação pode ser omitida.
O carregador em si é escrito em linguagem assembly, existem exemplos de carregadores simples em folhas de dados no AVR. Você pode cavar um gerenciador de inicialização existente, se estiver no domínio público, e simplesmente usá-lo de forma pronta, se o protocolo pelo qual ele funciona for conhecido. A única ressalva é que você precisa configurar o AVR em um modo especial, exibindo bits de fusível especiais, o que é feito por um programador normal, e você também pode costurar o gerenciador de inicialização na memória do microcontrolador (ou seja, não pode ficar sem um programador uma vez).
A segunda opção é programar através da interface SPI serial. Não há carregador de inicialização interno aqui, mas programamos enviando comandos especiais e dados através da interface mencionada acima. Aqui temos um gerenciador de inicialização externo, mas você ainda precisa escrevê-lo. Além de RESET e GND, quatro saídas MOSI adicionais são usadas para transmissão, dados MISO, sincronização SLK, seleção de chips CS. Mas, em geral, você também pode remover o MISO e o CS. Os dados serão aceitos apenas (então não haverá verificação do programa) e só temos um cristal.
Cada abordagem tem seus prós e contras (e eu não considerei o JTAG, pois a vida humana é curta). Mas no final, eu me inclinei para o SPI porque estava com preguiça de escrever no assembler, mas não encontrei gerenciadores de inicialização abertos (eu simplesmente não parecia bem).
Para construir um canal sem fio, eu, como já mencionado, escolhi o chip ESP8266 atualmente conhecido - um microcontrolador, ou melhor, um SoC (System-on-Chip) inteiro do fabricante chinês Espressif, com uma interface Wi-Fi. Além do Wi-Fi, destaca-se pela capacidade de executar programas da memória flash externa. E especificamente para o meu projeto, peguei o ESP8266-07 com 512 KB de memória a bordo.

Em geral, qualquer ESP8266 é adequado onde existem pernas extras para a implementação do SPI. Portanto, o ESP8266-01 mais simples não nos convém, pois possui muito poucas pernas para portas de entrada / saída. Mas, por outro lado, a diferença de preço é inferior a cem rublos, e eles estão disponíveis igualmente. Bem, grandes placas de depuração com ESP, onde vários periféricos são convenientes, também não são adequadas para nós, porque não entram onde queremos empurrá-las para o nosso braço mecânico.
A essência global da ideia em geral era a seguinte. O corpo do programa carregado no microcontrolador é transferido do computador para o ESP sem fio via WI-FI (na sua rede doméstica). E o ESP já por cabo, usando a interface SPI, grava esse programa diretamente na memória FLASH do microcontrolador. Em seguida, ele é redefinido naturalmente e permite que o programa carregado seja executado. Além disso, o ESP deve ter uma unidade independente, que também gerencia a troca de dados com o microcontrolador, pois queremos não apenas programar, mas também trocar dados com ele. Em particular, para um projeto com o MechArm, após a gravação do programa, ainda transmitimos sinais de servo controle para colocar essa mão em movimento. Portanto, no próprio ESP, é aconselhável criar um servidor TCP para transferência de programa e um servidor UDP para controlar o MechArm. Consequentemente, esses servidores ingressam na rede doméstica e ouvem atentamente se há alguém que deseja fazer upload de novo código no MechaArm ou acenar para alguém.
Então, descobri na Web que o firmware já permite programar o AVR pelo ar, mas o principal problema é que, para o que mais esse firmware não pode mais ser usado. Após a programação, gostaríamos de nos comunicar com o AVR também remotamente.
Que software vamos usar:
Para PC, escrevi tudo em JAVA,
IntelliJ IDEA . Mas, basicamente, você pode fazer qualquer coisa, a principal coisa para nós é escrever um cliente que enviará o programa para atualizar o AVR para o ESP8266.
Eu mesmo escrevo programas para AVR no
ATMEL STUDIO , na linguagem C, raramente em assembler. Eu não uso esboços do Arduino em princípio, quase qualquer biblioteca necessária é escrita em uma ou duas horas, com uma compreensão completa de seu trabalho. Tentei esboços, mas contanto que você não tenha um sistema operacional no AVR, os esboços removerão os periféricos de um amigo e falharão regularmente. Sim, o próprio Arduino IDE, comparado ao ATMEL STUDIO, é obviamente uma coisa muito primitiva. Mas aqui a questão é, obviamente, polêmica, para humanidades e crianças em idade escolar será mais divertido e fácil, provavelmente, com esboços.
Para programar o ESP8266, usei o firmware do NodeMCU e escrevi programas em Lua. Não, eu adoraria escrever em Java e C, mas não há nenhum no ESP. A linguagem Lu aplicada à nossa tarefa não é difícil, para dominar algumas trivialidades. Na verdade, para baixar programas e depurá-los no ESP, peguei o
IDE ESPlorer . Um produto doméstico gratuito (mas você pode doá-lo ao autor), que obviamente não pode ser comparado com os ambientes mencionados acima, mas como o cavalo presente diz ... Mas, para usar o ESPlorer e escrever no LUA, primeiro precisamos alterar o firmware base (fornecido pelo fabricante) no chip ESP8266 para novo. O programa NODE MCU PyFlasher nos ajudará nesse empreendimento. Quero dizer, ajudará a refleti-lo. E nós mesmos criaremos o firmware e o
colocaremos nas mãos do site dos criadores:
NodeMCU E você pode ler mais sobre esse processo
aqui:Tudo é muito acessível e compreensível. Adicionamos suporte a SPI e operações de bit às bibliotecas base (em LUA, no nosso caso, as operações de bit são sobrecarregadas e inúteis a partir delas). Muitas bibliotecas não devem ser inseridas no firmware das bibliotecas, porque, devido à presença de qualquer software no ESP8266, resta muito pouca memória, algum tipo patético de 20 kB.
Obviamente, você pode apenas pegar o firmware finalizado, dos quais muitos já estão na Internet, mas eu não o recomendo. Pelo menos porque alguns deles não têm suporte para operações de bits (e precisamos deles) e não há regulamentação da taxa de transferência de dados via SPI.
Assim, eles são transmitidos por padrão a uma velocidade de 40 MHz dividida por algum pequeno coeficiente e, portanto, o AVR não tem tempo para digeri-los.
Quem tem preguiça de criar firmware, pode baixar o meu da
nuvem .
Agora temos o firmware e precisamos carregá-lo no ESP8266 em vez do básico. Para fazer isso, precisamos de um simples adaptador USB - UART.
Conectamos as pernas TXD ao RXD e RXD ao TXD, estabelecemos o terreno comum, mas não usamos, como parecia, uma conveniente saída de energia de 3,3 V no adaptador. Na maioria dos casos, o ESP8266 o drena completamente. Portanto, nós o alimentamos separadamente. Em seguida, colocamos o ESP no modo de programação (GP0, se alguém se esqueceu) e executamos o
PyFlasher NODE MCU .

É importante ressaltar que não se esqueça de apagar a memória flash (sim, limpa todos os dados); caso contrário, dependendo da versão do firmware, após a programação, um lixo desnecessário poderá permanecer na memória, que por sua vez despejará o lixo no console durante trabalhos futuros. Antes disso, eu usava software, onde não havia opção para apagar a memória de antemão, fiquei terrivelmente atormentado, pois nada funcionava. E o caixão acabou de abrir, apenas a verdade no fórum em inglês dos criadores do NODE MCU.
Tendo adquirido o firmware necessário, agora podemos escrever e depurar programas LUA (também existe o MicroPython, mas eu não o usei) usando APIs muito convenientes do NODE MCU. Lançamos o já mencionado ESPlorer.

Também o configuramos para funcionar com o ESP8266, definimos os parâmetros da conexão serial. Tudo é bastante simples e afirmado repetidamente na Internet.
Agora, escrevemos o programa em LUA, que enviamos para o ESP8266:
Carregador de lua para AVR gravado em ESP8266<b>function InstrProgrammingEnable ()
Onde as funções relevantes executam as seguintes ações:
function InstrProgrammingEnable () - coloca o microcontrolador no modo de programação com um comando especial enviado via SPI.
função ProgrammingEnable () - basta redefinir o AVR por 25 ms antes de iniciar a programação
função ProgrammingDisable () - após o final da programação, convertemos as saídas SPI no ESP8266 para um estado inativo para que elas não interfiram conosco ao executar o código no microcontrolador (de repente elas são usadas lá)
função InstrFlashErase () - apagamos a memória flash no microcontrolador antes da programação. Por que isso precisa ser explicado não é necessário.
função InstrStorePAGE (H, endereço, dados) - este comando grava o byte do programa no buffer interno do microcontrolador. Mas este não é o próprio registro do flash, pois o flash é escrito aqui página por página em 128 bytes.
função InstrWriteFLASH (page_address_low, page_address_high) - mas esse é um registro flash e leva tempo, preste atenção ao atraso de 5.000 μs.
função Programação (carga) - a função maior e mais importante usando as funções acima. Ele pega o programa transmitido em pedaços de 1024 bytes, os divide em bytes e forma os endereços para eles, depois o envia para o microcontrolador no buffer interno e inicializa o registro flash a cada 128 bytes. Em seguida, ele pega o próximo kilobyte de código e repete a operação, naturalmente com um deslocamento nos endereços, para escrever mais e não substituir o gravado. No começo, tentei encaminhar o programa inteiro, mas quando excedi 6 kilobytes no ESP8266, a memória disponível acabou e acabou. Um kilobyte acabou por ser a unidade mais conveniente, porque é perfeitamente dividido em partes e transmitido de forma conveniente por TCP (ainda precisamos obtê-lo do computador). Um tamanho maior também não é necessário, o TCP, na versão atual, limita o pacote transmitido a 1500 ou bytes (mas, por algum motivo, 1440 foi transmitido para mim, mais ou menos).
Como se nada fosse complicado, mas algumas armadilhas precisavam ser superadas.
Em seguida é o bloco principal. Nele nós:
Estamos registrados em uma rede sem fio.
Primeiro, criamos um servidor TCP que escuta três comandos:
1. "programa" (vamos programar)
2. "dados" (vamos mudar os dados),
3. "parar" (paramos tudo).
Se programarmos, primeiro inicializaremos o SPI e criaremos outro servidor TCP que captura os dados (código de firmware) por kilobyte e chama as funções de programação do microcontrolador para eles. Entendo que parece bobagem criar um segundo servidor, mas isso é uma necessidade, porque a API local suporta a criação de apenas um soquete, e precisamos separar os comandos "program" e "data" pelos dados transmitidos, porque, a olho, eles não diferem, existem bytes e aqui estão bytes.
Se não queremos programar, mas trocar dados, enviando-os no nosso caso para o microcontrolador, primeiro enviamos a string "data" via TCP. Em resposta a isso, um servidor UDP será criado (lembro que não gerenciamos dinamicamente com uma mão mecânica e que não precisamos de atrasos na formação de pacotes TCP e, de fato, enviamos um byte como um quadro TCP inteiro no balcão). E os datagramas UDP serão pequenos e se formarão rapidamente.
Depois que o UART é inicializado, e cada byte recebido sem fio já é enviado via fio TXD para o microcontrolador, que é obrigado a aceitá-lo se o programa correspondente for atualizado lá. A troca de dados em outra direção também não é difícil de organizar, mas ainda não a implementei.
Bem, com o comando "stop", os servidores mencionados acima (exceto o primeiro) fecham as conexões e o servidor principal entra novamente no estado de espera dos comandos "program" e "data".
Como a interface SPI é emulada de forma programática no ESP8266, portas de E / S para sinais CS, CLK, MISO, MOSI, RESET (para AVR), você pode usar qualquer um disponível, e não os indicados no meu gerenciador de inicialização. Além disso, verificou-se que CS e MISO, em princípio, também podem ser interrompidos neste caso, funcionará sem eles. Bem, um pino é usado no LED embutido na placa ESP8266, para que às vezes pisque e indique que o programa ainda está ativo.
As verificações de erros de gravação não são feitas (com exceção da primeira solicitação ao AVR, mas essas informações são simplesmente exibidas no console), a EEPROM não está programada, mais de 32 KB não é costurado - em suma, ainda há trabalho a ser feito. A velocidade de troca do SPI é de aproximadamente 115 Kbit, em alguns segundos tudo pisca, aproximadamente, como em um programador serial comum como o ISP500).
Pegue o código, insira suas redes e senhas, compile no ESplorer, chame-o de “init” (para que inicie na reinicialização) e envie-o para o ESP8266. Deveria funcionar. No sentido de trabalhar como programador sem fio, pelo menos.
Agora vamos lidar com a parte gerenciadora - um computador pessoal.
De fato, precisamos pegar o arquivo HEX no qual seus programas escritos no ambiente ATMEL STUDIO se transformam e enviá-lo via WI-FI para a porta do soquete que conhecemos (neste caso, 4000). O pequeno problema é que precisamos de um arquivo BIN binário para transferência, e o ATMEL STUDIO nos agrada apenas com um HEX. Existem duas saídas; ou converta-o para o formato BIN com um conversor de programa especial, como o WinHex, ou faça você mesmo em seu programa. Ainda não o fiz, mas parece não ser difícil, é preciso cortar o título e fazer outra coisa.
Como resultado, escrevi o programa gerenciador de inicialização em JAVA (principalmente porque não sei fazer mais nada), trabalhando no ambiente simplesmente bonito e gratuito do IntelliJ IDEA. Ele cria um cliente TCP que procura um servidor em execução no ESP8266. Se encontrar, entra em contato com ele e envia um arquivo localizado em um endereço desse tipo. O código está abaixo.
Downloader de arquivo JAVA baseado em 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() {
Aqui, é claro, muita coisa foi ferida, todo tipo de preparação, em princípio, não é necessária. Se a conexão TCP for estabelecida, ela será estabelecida. O único problema era que o arquivo não queria ser enviado nem mesmo em partes de 1024 bytes, como eu realmente precisava, embora tenha indicado explicitamente o tamanho. Aparentemente, existe algum tipo de buffer final inacessível pelo JAVA, e ele envia pacotes do tamanho que ele deseja, o que é completamente inaceitável para o lado receptor. No começo, tentei atrasar para que o buffer se cansasse de esperar pelas próximas peças e enviá-las como estão. Mas o atraso começou a funcionar quando chegou a 10 segundos, o que de alguma forma parecia demais para um kilobyte transferido.
Mas então notei que, por algum motivo, a primeira peça sempre é lisa, qual foi encomendada, e já a partir da segunda começa uma bacanal imprevisível. Portanto, fiz o cliente abrir a conexão, enviar uma parte do código em 1024 bytes e fechar a conexão. E assim por diante até que todo o arquivo seja enviado. Tudo funcionou bem.
A única coisa a começar é instalar o tempo de execução JAVA no computador. Mas normalmente começo imediatamente do IntelliJ IDEA, porque sempre é possível ver o que está acontecendo no console (mas aqui você precisa de um ambiente JAVA). Embora, é claro, de uma maneira inteligente, você precise criar uma GUI. Ou seja, a janela em que o caminho para o arquivo cai, a capacidade de alterar os números de porta na janela e, bem, outras coisas necessárias. E para coletar tudo isso na forma de um arquivo executável.
E tapericha, como costumava dizer Koroviev, voltemos aos cidadãos, de fato, ao membro mecânico MechArm, mencionado no começo. Agora temos a oportunidade de programá-lo remotamente e depois gerenciá-lo. Vamos para o programa de controle na lateral do microcontrolador.
Nesse caso, precisamos controlar quatro servos. Aqui estão aqueles.
Esse inversor é controlado por pulsos retangulares de um período de 20 ms (50 Hz) com um fator de serviço de 2 a 4%. Ou seja, 2% é uma volta completa em uma direção, 4% na outra. A tarefa é apenas para o PWM integrado no AVR.

Um servoconversor é usado para mover para a esquerda e direita; o segundo em si mesmo - de si mesmo; terceiro para cima e para baixo; a quarta é a própria garra, que deve ser comprimida e expandida. Tudo é escrito em C e compilado em um arquivo HEX no ATMEL STUDIO. Um tipo de programa um pouco estranho se deve ao fato de que inicialmente a mão era controlada do teclado amarrado com fios ao microcontrolador. Mas os fios de ontem, precisamos evoluir ainda mais.
É claro que você pode usar esboços para servos de "ARDUINO", mas eu não gostei deles. É mais interessante escrever você mesmo. Além disso, todos os quatro servos devem funcionar simultaneamente, e não no modo multiplexado, quando o PWM alternar para cada servo por vez. Pois ninguém cancelou a gravidade e um membro levantado descerá imediatamente se os impulsos de controle deixarem de chegar ao servoconversor correspondente. Não tenho certeza de que o esboço "ARDUINO" forneça operação simultânea para quatro servos. Mas nós mesmos podemos escrever um programa que atenda aos requisitos necessários. Em geral, na ausência de um sistema operacional que separa os cordeiros das cabras, o uso de esboços competindo pelos dispositivos periféricos do microcontrolador (e nem sabemos com antecedência quais) é muito complicado.
Aqui está o código em si que escrevemos no Arduino Nano usando o ESP8266-07.
Programa para controlar o MechArm para o 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); } }
A essência do programa é clara no texto e nos comentários. Utilizamos um contador T1 por um período exemplar de 20 ms e contadores T0, T2 para emitir sinais PWM para quatro linhas da porta de E / S, uma vez que cada um desses dois contadores pode funcionar em dois dispositivos.
O programa define as posições iniciais dos servos através do carregamento dos registros de contagem OCR0A, OCR0B, OCR2A, OCR2B. Constantes de restrição também são introduzidas, pois nem sempre precisamos de um intervalo de 180 graus. Além disso, com a interrupção do UART, o programa captura o número enviado pelo ESP8266 (de 1 a 8) e o converte em um comando para o servo correspondente. Existem quatro unidades, cada uma trabalhando em duas direções, portanto, números inteiros de um a oito são suficientes. Depois que o número é selecionado, o conteúdo dos registros do contador acima é aumentado ou diminuído, alterando respectivamente o ciclo de trabalho do pulso de controle e o ângulo de rotação do servoconversor selecionado. Os acionamentos que não selecionamos mantêm o valor antigo do ângulo de rotação (uma vez que o conteúdo dos registros correspondentes, apesar de atualizados, não foram alterados) e continuam mantendo o braço mecânico na mesma posição.
Agora só precisamos escrever um programa de controle, desculpe a tautalogia, para controlar uma mão mecânica diretamente do computador via WI-FI.
O código também está escrito em JAVA, mas um pouco enobrecido. Havia uma GUI e a capacidade de editar os números de porta e o endereço de rede do ESP8266.

O que acontece é claro a partir da janela. Não
forneço o texto do programa aqui (está disponível no
Github ), pelo seguinte motivo: aproximadamente 95% de seu volume é criação de janelas e processamento de sinais no teclado. Mas a essência é a mesma do programa anterior em JAVA. Um cliente é criado, apenas o UDP, que, dependendo da tecla pressionada, envia um número de 1 a 8, no endereço especificado na porta especificada.
Ou você pode obter imediatamente o executável a
partir daqui . Para máquinas de 64 bits com Windows. Mesmo um ambiente JAVA instalado não é necessário. Tudo já foi colocado em 178 MB.
Assim, a caneta mecânica foi montada, depurada e apresentada a seu irmão em seu aniversário. Pode pegar pilhas de plástico com vodka, no Skype, de outra cidade. Embora para o braço mecânico de Howard Volovitsa da série "The Big Bang Theory", ela ainda esteja longe.
Porém, nos artigos a seguir (se houver alguém interessado), poderemos gerenciá-lo a partir de um telefone celular, fazer o mesmo com um carrinho robótico de quatro rodas e atualizar o tempo em relógios eletrônicos de servidores de relógio na Internet. Em seguida, colocamos o smartphone antigo no carrinho e direcionamos o vídeo para a rede neural com reconhecimento de padrões e, em seguida, os sinais de controle para os motores,
oh, algo já me carrega ...E tudo isso com a linda ESP8266.
Ficaria feliz se alguém achasse o artigo interessante.
[1]
Pinagem e especificações de ESP8266[2]
Conectando o ESP8266. Início rápido.[3]
Atualização de firmware do NodeMCU via nuvem[4]
NOF MCU PyFlasher[5]
ESPlorer - IDE para ESP8266[6]
Programação C para AVR[7] Revisão de artigos - “Programando microcontroladores na linguagem C”[8] Descrição da API do NodeMCU[9] Referência da Lua[10] Scripts e módulos da Lua[11] IntelliJ IDEA[12] Faça o download do Java agora no seu computador desktop![13] Atmel Studio