Kit Robô Avançado Quadrúpede Aranha Tutoriais Wifi App QD020 RB2055 - Curso Completo

Escolha a Versão do Curso
Este curso completo conta com duas abordagens didáticas desenvolvidas pela RoboBuilders e ACEBOTT. Selecione a metodologia ideal para o seu perfil ou de sua turma:
Versão ACECode
Programação Visual em Blocos (Scratch 3.0)
Ideal para iniciantes, crianças a partir de 8 anos, estudantes do Fundamental e educadores. Construa a lógica de marcha sem barreiras de digitação ou erros de sintaxe.
- 8 Lições práticas completas em blocos gráficos
- Calibração de ponto zero e alinhamento
- Danças rítmicas, passo de caranguejo e aceno
- Conexão Wi-Fi SoftAP com aplicativo ACEBOTT
Versão Arduino C/C++
Linguagem C/C++ na Arduino IDE com `text.h`
Ideal para alunos do Ensino Médio Técnico, universitários e makers que desejam dominar código em baixo nível, matrizes cinemáticas e sockets TCP.
- Códigos C/C++ 100% comentados linha a linha
- Biblioteca `text.h` e cinemática multieixo
- Transmissão de pacotes binários por rede
- Servidor TCP embarcado na porta 100
Introdução
Este curso apresenta o Kit Robô Avançado Quadrúpede Aranha Tutoriais Wifi App QD020 RB2055, desenvolvido pelo fabricante ACEBOTT e comercializado com suporte e garantia integral pela RoboBuilders. Trata-se de uma plataforma robótica bioinspirada de alta precisão com 8 graus de liberdade (8 DOF), acionada por 8 micro servomotores, controlada pela poderosa placa microcontrolada ESP8266 integrada a uma placa de expansão dedicada de servomotores com gerenciamento de energia e comunicação sem fio Wi-Fi 802.11 b/g/n em 2.4 GHz, proporcionando controle autônomo e teleguiado via aplicativo móvel dedicado para Android e iOS através de conexões de soquete TCP de baixa latência.
É um material educacional robusto estruturado tanto para estudantes, hobistas, makers e engenheiros que buscam dominar os fundamentos físicos da locomoção quadrupedal, cinemática direta e inversa, decomposição de marchas, controle multieixo de servomotores e conectividade IoT em sistemas embarcados de tempo real utilizando a linguagem C/C++ nativa na Arduino IDE. A jornada pedagógica foi meticulosamente desenhada para cobrir desde a conferência física dos componentes, testes preliminares de comunicação serial e calibração de ponto zero, passando pela montagem mecânica passo a passo em 12 etapas, desenvolvimento de algoritmos de marcha trotante, curvas sobre o próprio eixo, translação holonômica lateral (passo de caranguejo), rotinas de interação gestual (aceno) e coreografias musicais dinâmicas, culminando no firmware mestre com servidor TCP e páginas de comando integradas ao ecossistema de controle via smartphone.
⚠️ Atenção: O que você vai aprender:
⚠️ Atenção: - Compreender a arquitetura de silício do processador Tensilica L106 de 32 bits do SoC ESP8266 e seu mapeamento de registradores GPIO
⚠️ Atenção: - Analisar o circuito de potência da placa de expansão de servos, barramentos de desacoplamento e dimensionamento de corrente transitória para 8 atuadores
⚠️ Atenção: - Executar a montagem mecânica estrutural do chassi em acrílico cortado a laser e acoplamento dos braços oscilantes sem folgas ou tensões de fadiga
⚠️ Atenção: - Calibrar com exatidão matemática o ponto neutro de 90° de todos os servomotores antes do travamento mecânico definitivo
⚠️ Atenção: - Programar matrizes bidimensionais de estados cinemáticos em C/C++ para marcha de avanço, recuo, curvas de raio zero e translação lateral
⚠️ Atenção: - Desenvolver rotinas de aceno dinâmico com sustentação estática em tripé e compensação do centro de massa do robô
⚠️ Atenção: - Implementar coreografias de dança rítmica com controle de tempo e interpolação angular contínua sem jitter mecânico
⚠️ Atenção: - Configurar o ESP8266 em modo Ponto de Acesso (SoftAP) e programar um servidor TCP na porta 100 para decodificação de pacotes de controle em tempo real
⚠️ Atenção: - Diagnosticar falhas de reset por subtensão (brownout), ruído elétrico induzido, emperramento mecânico e perda de pacotes de rede com metodologia científica
⚠️ Atenção: Material utilizado: Kit Robô Avançado Quadrúpede Aranha Tutoriais Wifi App QD020 RB2055 disponível na loja RoboBuilders em https://robobuilders.com.br.
Visão Geral do Kit e Arquitetura de Hardware
O robô aranha biônica QD020 RB2055 é um robô quadrúpede articulado projetado com base no princípio biomecânico de sustentação estática e dinâmica de artrópodes. Diferente de plataformas com rodas ou esteiras, a locomoção por pernas oferece versatilidade superior na transposição de terrenos acidentados, degraus e superfícies não homogêneas. Cada perna do robô é composta por dois elos cinemáticos acionados independentemente por servomotores: o elo proximal (coxa ou ombro), responsável pela rotação angular horizontal em torno do eixo vertical (movimento de guinada ou yaw), e o elo distal (fêmur/pata), encarregado da elevação e abaixamento vertical (movimento de arfagem ou pitch). Essa configuração cinemática fornece 2 graus de liberdade por membro, totalizando 8 eixos atuados em todo o chassi.
Arquitetura do Controlador ESP8266 e Placa de Expansão
O cérebro do sistema é o microcontrolador ESP8266, equipado com um núcleo de processamento Tensilica Xtensa Dual-Core L106 de 32 bits operando a uma frequência de clock ajustável de 80 MHz a 160 MHz. Esse chip integra nativamente a pilha de protocolos TCP/IP completa sobre um transceptor de rádio frequência Wi-Fi 802.11 b/g/n, alcançando taxas de transmissão de até 72.2 Mbps em modulação MCS7. A placa conta com 4 MB de memória Flash SPI para armazenamento de firmware e sistema de arquivos SPIFFS/LittleFS, além de um conversor USB-Serial Silicon Labs CP2102 de alta estabilidade alimentado por um conector moderno USB Type-C.
O gerenciamento de alta corrente exigido por 8 servomotores simultâneos é o aspecto mais crítico no projeto elétrico de robôs quadrúpedes. Um micro servomotor SG90 em vazio consome aproximadamente 100 mA a 150 mA. Contudo, durante o início do movimento de arrancada ou em condição de torque sustentado (stall torque) ao levantar o chassi contra a gravidade, a corrente de pico por motor atinge entre 600 mA e 800 mA. Se todos os 8 motores demandarem torque máximo ao mesmo tempo, a corrente transitória total pode superar 5.0 A.
Para evitar que essa queda de tensão induzida pelo consumo dos atuadores cause o disparo do circuito detector de subtensão (brownout reset) do ESP8266, a placa de expansão da ACEBOTT emprega uma topologia de barramento dividido: o regulador de baixa queda de tensão (LDO) alimenta exclusivamente o núcleo lógico e o rádio Wi-Fi com 3.3V imune a ruídos, enquanto o trilho de potência dos servomotores (Servo VCC) é suprido diretamente da bateria através de capacitores eletrolíticos de tântalo e alumínio de baixa resistência em série equivalente (ESR), responsáveis por absorver as variações rápidas de .


Princípios Físicos e Cinemática de Marcha Quadrupedal
A locomoção do robô aranha obedece às leis da mecânica clássica e cinemática vetorial de corpos rígidos. Para que o robô mantenha o equilíbrio estático durante a caminhada, a projeção vertical do seu Centro de Massa (CoM - Center of Mass) sobre o solo deve obrigatoriamente residir dentro do Polígono de Suporte formado pelos pontos de contato das patas com o chão.
Sejam as posições horizontais dos pontos de contato de cada pata dadas por para , onde é o número de patas apoiadas no solo. O centro de massa horizontal é calculado por:
Quando o robô desloca-se em marcha trotante (trot gait), as pernas movem-se em pares diagonais cruzados:
- Fase 1: Pata Dianteira Direita (RF) e Pata Traseira Esquerda (LH) elevam-se e avançam no ar (fase de balanço ou swing phase), enquanto a Pata Dianteira Esquerda (LF) e Pata Traseira Direita (RH) permanecem apoiadas (fase de suporte ou stance phase).
- Fase 2: As quatro patas tocam brevemente o solo para transferência do vetor de momento linear e estabilização do chassi.
- Fase 3: O par diagonal oposto (LF e RH) eleva-se e avança no ar, enquanto RF e LH empurram o solo para trás gerando tração para a frente.
Para garantir a estabilidade sem tombamento, o algoritmo implementa a técnica de marcha estática de quatro tempos (wave gait ou crawl gait) quando em baixa velocidade e alta carga, garantindo que em qualquer instante haja pelo menos 3 patas em contato com o solo (), formando um triângulo de suporte rígido. A margem de estabilidade estática é a menor distância ortogonal entre a projeção do CoM e as arestas do polígono de suporte:
O robô somente é incondicionalmente estável se . Quando , ocorre o tombamento gravitacional.
Funcionamento e Modulação PWM dos Servomotores
Os 8 servomotores micro SG90 são transdutores eletromecânicos de posição em malha fechada. No interior de cada motor, há um pequeno motor elétrico de corrente contínua, um trem de engrenagens redutoras, um potenciômetro solidário ao eixo de saída (sensor de posição angular) e uma placa de controle analógica.
O sinal de controle enviado pelos pinos GPIO do ESP8266 é um sinal PWM (Pulse Width Modulation) com período fixo de 20 milissegundos, equivalente a uma frequência fundamental de 50 Hz. A informação da posição angular desejada é codificada unicamente pela duração do nível lógico alto (pulso ):
Onde () corresponde a , () corresponde à posição neutra central de , e () corresponde ao limite angular de . A razão cíclica (duty cycle) em é dada por:
Inventário do kit
A conferência prévia de todos os componentes mecânicos, eletroeletrônicos e fixadores é indispensável antes de iniciar o processo de montagem. Abaixo está a lista técnica oficial exaustiva de todas as peças fornecidas no kit QD020 RB2055:
- 1 Placa controladora principal com microcontrolador ESP8266 NodeMCU, transceptor Wi-Fi e porta USB Type-C — processador central de comandos e geração de sinais PWM
- 1 Placa de expansão de servomotores ACEBOTT Servo Shield com trilhas de alta corrente, barramento dedicado de 3 pinos para servos e conectores de alimentação
- 8 Micro servomotores 9g com rotação de 180 graus, engrenagens de nylon reforçado e cabos de conexão padrão triplo (marrom=GND, vermelho=VCC, laranja=Sinal)
- 8 Conjuntos de braços oscilantes plásticos (servo horns cruzados, simples e duplos) e parafusos de retenção de eixo originais dos motores
- 1 Suporte para bateria recarregável padrão 18650 com fios estanhados e conector compatível com a entrada da placa
- 1 Cabo de conexão e programação USB Type-C de alta velocidade com condutores de dados blindados
- 1 Placa estrutural de acrílico cortada a laser para o chassi inferior (Body-Bottom) com furações para expansão e montagem dos servos
- 1 Placa estrutural de acrílico cortada a laser para a tampa superior do chassi (Body-Top) com furações para o suporte de bateria
- 4 Peças estruturais em acrílico para as articulações proximais (Coxas / Thigh Plates)
- 4 Peças estruturais em acrílico para os elos intermediários (Fêmures / Femur Plates)
- 4 Peças estruturais em acrílico para as extremidades inferiores das pernas (Tíbias / Patas / Lower Leg Plates)
- 1 Chave Philips de precisão ergonômica com ponta magnética para fixação dos parafusos de máquina e auto-atarraxantes
- 16 Parafusos de máquina M3x6mm em aço zincado para fixação dos servomotores nas bases de acrílico
- 8 Parafusos de máquina M3x8mm para fixação da placa de expansão e placa controladora
- 8 Parafusos de máquina M3x10mm com porcas auto-travantes para articulações móveis
- 8 Parafusos auto-atarraxantes curtos de fixação central dos servo horns nos eixos dos motores
- 16 Parafusos auto-atarraxantes finos para ancoragem dos horns plásticos nas peças de acrílico
- 16 Porcas sextavadas M3 em aço zincado com rosca padrão métrico
- 4 Espaçadores plásticos cilíndricos em nylon para isolamento mecânico e sustentação entre os andares inferior e superior
Somando todos os itens listados entre componentes semicondutores, módulos atuadores, chapas cortadas em acrílico, cabos de conexão, ferramentas manuais e elementos de fixação mecânica (parafusos e porcas), o conjunto reúne 102 peças físicas individuais rigorosamente inspecionadas e calibradas para garantir o perfeito alinhamento estrutural do robô aranha quadrúpede.
Mapa de pinos e conexões dos servomotores
A tabela a seguir consolida o mapa mestre de conexões elétricas de todos os 8 atuadores do robô aranha. A correta identificação dos pinos GPIO do ESP8266 em relação à numeração serigrafada na placa (D0 a D8) é crucial para que os algoritmos de marcha atuem sobre o membro correto:
| Posição da Perna | Articulação do Membro | Identificador do Servo | Pino GPIO ESP8266 | Serigrafia na Placa | Sinal PWM (Ponto Neutro) | Ângulo de Calibração Zero |
|---|---|---|---|---|---|---|
| Superior Direita (Front-Right) | Pata / Distal (Pitch) | servo_14 | GPIO 14 | D5 | 1500 µs (7.5% duty) | 135° |
| Superior Direita (Front-Right) | Braço / Coxa (Yaw) | servo_12 | GPIO 12 | D6 | 1500 µs (7.5% duty) | 45° |
| Inferior Direita (Rear-Right) | Braço / Coxa (Yaw) | servo_13 | GPIO 13 | D7 | 1500 µs (7.5% duty) | 135° |
| Inferior Direita (Rear-Right) | Pata / Distal (Pitch) | servo_15 | GPIO 15 | D8 | 1500 µs (7.5% duty) | 45° |
| Superior Esquerda (Front-Left) | Pata / Distal (Pitch) | servo_16 | GPIO 16 | D0 | 1500 µs (7.5% duty) | 45° |
| Superior Esquerda (Front-Left) | Braço / Coxa (Yaw) | servo_5 | GPIO 5 | D1 | 1500 µs (7.5% duty) | 135° |
| Inferior Esquerda (Rear-Left) | Braço / Coxa (Yaw) | servo_4 | GPIO 4 | D2 | 1500 µs (7.5% duty) | 45° |
| Inferior Esquerda (Rear-Left) | Pata / Distal (Pitch) | servo_2 | GPIO 2 | D4 | 1500 µs (7.5% duty) | 135° |
⚠️ Atenção: [!IMPORTANT]
⚠️ Atenção: Observe rigorosamente a convenção de cores do chicote de 3 vias dos servomotores: o fio Marrom deve ser ligado no pino GND (trilha preta da placa de expansão), o fio Vermelho no pino VCC (trilha vermelha central de 5V) e o fio Laranja no pino de Sinal (trilha amarela/branca externa conectada aos GPIOs). Inverter o conector pode danificar o circuito de controle interno do servomotor.
Montagem Mecânica (Assembly Guide)
A montagem estrutural do robô aranha quadrúpede QD020 RB2055 exige precisão, método e paciência. As peças foram usinadas por corte a laser de alta repetibilidade dimensional em acrílico de grau estrutural. Antes de aplicar aperto com chaves, certifique-se de que os componentes estejam perfeitamente assentados em suas cavidades para evitar tensões residuais de flexão que poderiam causar trincas microscópicas no material acrílico.
Passo 1 — Descascar as películas protetoras das peças em acrílico
Todas as peças de acrílico saem de fábrica revestidas com uma fina película adesiva de papel kraft ou filme plástico protetor para evitar riscos durante o transporte. Utilizando a ponta da unha ou uma espátula plástica em um dos cantos de cada chapa, remova completamente o filme de ambas as faces de todas as peças (chassi superior, chassi inferior, 4 coxas, 4 fêmures e 4 patas). Deixe as peças sobre uma superfície limpa e livre de resíduos abrasivos.

Passo 2 — Montar a placa de expansão de servos na placa base inferior
Posicione a placa de expansão ACEBOTT Servo Shield sobre o chassi inferior de acrílico (Body-Bottom), alinhando os quatro furos de fixação das extremidades da placa com as furações do acrílico. Insira quatro parafusos de máquina M3x8mm a partir da face superior e rosqueie por baixo quatro porcas M3 sextavadas. Aperte com a chave Philips fornecida até que a placa fique firmemente imobilizada, tomando o cuidado de não forçar excessivamente para não esmagar a placa de circuito impresso.

Passo 3 — Fixar os 4 servomotores de rotação do corpo (ombros/coxas)
Instale os 4 primeiros servomotores nas quatro reentrâncias retangulares dispostas nas extremidades do chassi inferior. O eixo rotativo estriado de cada servomotor deve ficar voltado para fora e para a parte superior do chassi. Encaixe cada motor em seu respectivo alojamento e transpasse dois parafusos M3x6mm pelos flanges do motor e furos do acrílico, fixando-os com porcas M3 pelo lado oposto. Estes quatro motores serão responsáveis pelo movimento horizontal de abertura e fechamento das pernas do robô.

Passo 4 — Fixar a placa controladora ESP8266 no chassi inferior
Posicione a placa controladora ESP8266 NodeMCU encaixando seus pinos machos diretamente nos barramentos fêmeas correspondentes da placa de expansão de servomotores montada no Passo 2. Pressione de forma uniforme em ambas as laterais até que os pinos estejam completamente inseridos e a placa esteja perfeitamente nivelada. O conector USB Type-C deve ficar apontado para a parte traseira do robô para facilitar o acesso de programação sem necessidade de desmontagem.

Passo 5 — Montar os braços oscilantes de servo (servo horns) nas peças das pernas
Pegue os braços plásticos tipo cruzeta ou braço duplo fornecidos com os servomotores. Alinhe cada braço plástico com os furos de ancoragem pré-furados nas peças de acrílico das pernas (coxas e patas). Fixe cada braço utilizando dois parafusos auto-atarraxantes finos inclusos no kit de acessórios dos servos, parafusando-os pela parte plástica até que a cabeça do parafuso assente suavemente sobre o acrílico. Repita a operação para os 8 conjuntos de peças articuladas.

Passo 6 — Acoplar os servos de elevação às articulações do fêmur
Insira um servomotor em cada uma das quatro estruturas de fêmur das pernas. Estes servomotores serão responsáveis pelo levantamento e abaixamento vertical de cada pata. Prenda cada servo à respectiva chapa de fêmur utilizando dois parafusos de máquina M3x6mm e porcas sextavadas, assegurando que o eixo dentado do motor fique orientado em direção à extremidade de fixação da pata distal.


Passo 7 — Conectar os cabos dos servos de rotação do corpo à placa de expansão
Antes de fechar a estrutura central, encaminhe os chicotes elétricos dos quatro servomotores montados no chassi inferior (Passo 3) e conecte-os nos seus respectivos pinos do barramento de sinal da placa de expansão:
- Pata Superior Direita (D5 / GPIO 14)
- Braço Superior Direito (D6 / GPIO 12)
- Braço Inferior Direito (D7 / GPIO 13)
- Pata Inferior Direita (D8 / GPIO 15) Certifique-se de que os conectores estejam com a via de terra (marrom) alinhada com os pinos de GND.

Passo 8 — Montar as patas inferiores (tíbias) nas cruzetas dos servos de elevação
Encaixe as quatro peças de acrílico das patas inferiores sobre os eixos dentados dos servomotores montados nos fêmures (Passo 6).


⚠️ Atenção: [!CAUTION]
⚠️ Atenção: Não parafuse o parafuso central de retenção do eixo do servomotor neste momento! As pernas precisam ser posicionadas no ângulo neutro exato após a execução do programa de calibração eletrônica
1.3zero_0.ino, conforme detalhado na Lição 3 deste curso. Forçar o giro manual das engrenagens com as mãos desenergizadas pode danificar os dentes de nylon dos redutores.
Passo 9 — Acoplar as pernas completas aos eixos dos servos do corpo
Encaixe os braços plásticos montados nas coxas (Passo 5) sobre os eixos dos quatro servomotores do corpo montados no Passo 3. Mantenha cada perna orientada em um ângulo de aproximadamente 45° em relação ao eixo longitudinal do chassi, simulando a postura natural aberta de uma aranha.


Passo 10 — Fixar e travar os parafusos centrais das cruzetas dos servomotores
Após energizar o sistema e carregar o firmware de calibração neutra (que coloca todos os eixos no ângulo mestre de 90° e nas posições zero calculadas), insira o parafuso auto-atarraxante curto original do servo no orifício central de cada um dos 8 braços plásticos, apertando-o firmemente com a chave Philips contra o eixo dentado do motor. Isso elimina folgas mecânicas (backlash) e garante transmissão de torque integral.

Passo 11 — Instalar a placa de acrílico superior do corpo e o suporte de bateria
Monte os quatro espaçadores cilíndricos de nylon sobre as furações perimetrais do chassi inferior utilizando parafusos M3x10mm. Posicione a tampa de acrílico superior (Body-Top) sobre os espaçadores e fixe o suporte para bateria recarregável 18650 no centro da tampa superior utilizando dois parafusos M3 curtos e porcas. Conecte os terminais do suporte de bateria na chave liga-desliga geral e ao conector de alimentação da placa de expansão.

Passo 12 — Verificação mecânica, alinhamento simétrico e gerenciamento de cabos
Com o robô totalmente montado sobre uma bancada plana, faça uma checagem visual de simetria:
- As quatro pernas devem tocar o solo de forma coplanar, sem que nenhuma pata fique no ar.
- Os chicotes elétricos dos 8 servos devem estar agrupados e acomodados no interior do chassi, sem cruzar por cima das articulações móveis para evitar que sejam prensados durante as caminhadas.
- Ligue e desligue a chave de bateria rapidamente para verificar se o LED de alimentação do shield acende com brilho estável.


Preparação do Ambiente (Programming Preparation)
O desenvolvimento de firmware para o Kit Robô Aranha Quadrúpede no ecossistema Arduino requer a instalação da versão apropriada do ambiente de desenvolvimento integrado (Arduino IDE), a instalação do driver de comunicação serial para o conversor CP2102 e a configuração do pacote de suporte às placas ESP8266 (ESP8266 Core).



Instalação da IDE do Arduino e Driver CP210x
Recomenda-se a utilização do Arduino IDE 2.2.1 para assegurar total estabilidade dos compiladores e ferramentas de upload:
- Faça o download do instalador oficial no repositório GitHub do projeto (
https://github.com/arduino/arduino-ide/releases/tag/2.2.1). - Execute o instalador seguindo os passos padrão do assistente para o sistema operacional Windows.
- Instale o driver USB para UART CP210x da Silicon Labs, disponível na pasta
3.Instalaçao do driverdo pacote do fabricante ou no site oficial da Silicon Labs. Conecte a placa ESP8266 via cabo USB Type-C ao computador; abra o Gerenciador de Dispositivos do Windows e certifique-se de que um dispositivo denominado Silicon Labs CP210x USB to UART Bridge (COMx) esteja listado sob a categoria Portas (COM e LPT) sem exclamações amarelas.
Adição da URL do Gerenciador de Placas ESP8266
Para que a IDE reconheça as placas da família ESP8266, adicione o repositório oficial da comunidade:
- Na IDE do Arduino, acesse o menu Arquivo > Preferências (ou pressione
Ctrl + Vírgula). - No campo URLs Adicionais do Gerenciador de Placas, cole exatamente a seguinte URL:
http://arduino.esp8266.com/stable/package_esp8266com_index.json
- Se o campo já contiver outras URLs (por exemplo, de placas ESP32 ou Raspberry Pi Pico), separe as URLs com uma vírgula ou clique no ícone ao lado para abrir uma janela de múltiplas linhas. Clique em OK para salvar.


Instalação do Pacote ESP8266 Core
- Abra o painel do Gerenciador de Placas clicando no ícone de placa na barra lateral esquerda da IDE (ou pelo menu Ferramentas > Placa > Gerenciador de Placas…).
- Na caixa de pesquisa no topo, digite
esp8266. - Localize o pacote oficial intitulado esp8266 por ESP8266 Community. Selecione a versão recomendada (ex.: 3.1.2) e clique no botão Instalar. Aguarde o download completo dos compiladores
xtensa-lx106-elf-gcc, ferramentas de flashesptool.pye bibliotecas base do sistema.
Configuração dos Parâmetros de Compilação no Menu Ferramentas
Com o pacote instalado e a placa conectada à porta USB, ajuste as opções no menu Ferramentas:
- Placa:
NodeMCU 1.0 (ESP-12E Module) - CPU Frequency:
80 MHz(ou160 MHzpara melhor desempenho em conexões de socket de rede) - Flash Size:
4MB (FS:2MB OTA:~1019KB) - Upload Speed:
115200(ou921600para upload ultrarrápido) - Porta: Selecione a porta COM atribuída ao conversor CP2102 (ex.:
COM3,COM4)
Tabela-mestre de bibliotecas do curso
A tabela abaixo relaciona todas as bibliotecas de software utilizadas ao longo dos projetos deste curso, indicando sua origem e função no firmware:
| Biblioteca | Versão Homologada | Tipo / Origem | Função Principal no Sistema |
|---|---|---|---|
<Servo.h> | Embutida (ESP8266 Core) | Core Oficial | Geração de pulsos PWM por interrupção de hardware para os 8 servomotores |
<ESP8266WiFi.h> | Embutida (ESP8266 Core) | Core Oficial | Configuração do rádio Wi-Fi nos modos SoftAP e Station, controle de pilha IP |
<ESP8266WebServer.h> | Embutida (ESP8266 Core) | Core Oficial | Servidor HTTP embarcado para páginas web de controle manual |
"text.h" | Arquivo local do projeto | ACEBOTT | Matrizes de decomposição cinemática de passos e rotinas de acionamento |
Lições na Ordem do Tutorial do Fabricante
Seguindo rigorosamente a estrutura didática e a numeração oficial dos manuais do fabricante ACEBOTT, as lições a seguir conduzem o estudante pelos ensaios eletroeletrônicos iniciais até a integração total de locomoção e controle sem fio via smartphone.
Lição 1 — Instalação de Software e Compreensão de Hardware
Antes de exigir qualquer esforço mecânico dos servomotores ou carregar rotinas cinemáticas complexas, é indispensável validar o funcionamento do microcontrolador e o comportamento da modulação PWM de controle angular.
Experimento 1.1: Olá ESP8266 (Comunicação Serial)
O primeiro teste valida o fluxo de compilação, gravação e comunicação serial assíncrona entre o computador e o microcontrolador ESP8266 na velocidade padrão de 115200 bauds.
void setup() { // inicializa e transmite mensagem serial
Serial.begin(115200); // inicializa e transmite mensagem serial
} // inicializa e transmite mensagem serial
void loop() { // inicializa e transmite mensagem serial
Serial.println("Hello, ESP8266!"); // inicializa e transmite mensagem serial
delay(1000); // inicializa e transmite mensagem serial
} // inicializa e transmite mensagem serial
Ao carregar o código acima e abrir o Monitor Serial da IDE do Arduino configurado em 115200 baud, a mensagem Hello, ESP8266! será impressa ciclicamente a cada 1000 milissegundos (1 segundo). Este teste confirma que o processador Tensilica L106 está executando seu loop principal perfeitamente e que os circuitos de cristal de clock e comunicação UART operam sem ruído.


Experimento 1.2: Teste de Varredura de Servomotor
Neste ensaio, conectamos um servomotor avulso à porta D4 (GPIO 2) para verificar a resposta do circuito analógico interno do servo a uma rampa de pulsos de posição de 10° a 170°, com incremento unitário a cada 15 milissegundos.
#include <Servo.h> // controla varredura angular do servomotor
Servo myservo; // create servo object to control a servo
int pos; // controla varredura angular do servomotor
void setup() { // controla varredura angular do servomotor
myservo.attach(D4); // attaches the servo on GIO2 to the servo objec t
for (pos = 10; pos <= 170; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
} // controla varredura angular do servomotor
for (pos = 170; pos >= 10; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
} // controla varredura angular do servomotor
delay(1000); // controla varredura angular do servomotor
} // controla varredura angular do servomotor
void loop() { // controla varredura angular do servomotor
myservo.write(90); // controla varredura angular do servomotor
} // controla varredura angular do servomotor
Neste experimento, o servomotor executa um movimento pendular suave e contínuo. A função myservo.write(pos) converte o valor angular passado em microssegundos de pulso ativo de acordo com a calibração interna da biblioteca Servo.h. Ao final da varredura, o loop posiciona o servo em 90°, que é a posição neutra de referência.
Experimento 1.3: Zeroização Geral dos 8 Servomotores (zero_0)
Este é o programa mais importante de toda a montagem do robô. Ele inicializa simultaneamente as 8 variáveis de servo associadas aos pinos digitais correspondentes e envia os comandos de centralização e posição zero estática calculados para cada membro.
#include <Servo.h> //Import servo library
//Create eight servos variables
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
void setup(){ //Initialize the GPIO pin number of each servo
servo_14.attach(14); // calibra servomotor para o ponto neutro de 90 graus
servo_12.attach(12); // calibra servomotor para o ponto neutro de 90 graus
servo_13.attach(13); // calibra servomotor para o ponto neutro de 90 graus
servo_15.attach(15); // calibra servomotor para o ponto neutro de 90 graus
servo_16.attach(16); // calibra servomotor para o ponto neutro de 90 graus
servo_5.attach(5); // calibra servomotor para o ponto neutro de 90 graus
servo_4.attach(4); // calibra servomotor para o ponto neutro de 90 graus
servo_2.attach(2); // calibra servomotor para o ponto neutro de 90 graus
} // calibra servomotor para o ponto neutro de 90 graus
void zero() { //Define the zeroing function
servo_14.write(135);//Set right upper [paw]135°
servo_12.write(45);//Set upper right [arm]45°
servo_13.write(135);//Set lower right [arm]135°
servo_15.write(45);//Set right lower [paw]45°
servo_16.write(45);//Set upper left [paw]45°
servo_5.write(135);//Set upper left [arm]135°
servo_4.write(45);//Set lower left [arm]45°
servo_2.write(135);//Set left lower [paw]135°
} // calibra servomotor para o ponto neutro de 90 graus
void loop() { // calibra servomotor para o ponto neutro de 90 graus
zero();//Call the zeroing function
} // calibra servomotor para o ponto neutro de 90 graus
Após o upload deste programa, todos os 8 eixos do robô assumirão suas posições de referência travadas por controle ativo. É com este código rodando e a alimentação de bateria ligada que os braços oscilantes de acrílico das pernas devem ser assentados e aparafusados nos eixos, assegurando que o ponto físico de repouso corresponda exatamente ao valor angular esperado pelo firmware.
Lição 3 — Inicialização de Posição e Calibração dos Servos
A cinemática de um robô aranha de 8 eixos depende intrinsecamente do alinhamento angular relativo entre os elos proximais (ombros) e distais (patas). Qualquer discrepância mecânica de montagem em um único dente do acoplamento do servo horn (que introduz um erro típico de aproximadamente 8° a 10°) provocará assimetria de distribuição de carga no solo, fazendo com que o robô curve-se involuntariamente para os lados durante a caminhada reta ou bata as pernas entre si.


O programa de inicialização de posição calibra os eixos para os seguintes ângulos mestres:
- Articulações Proximais (Braços/Ombros): Os motores traseiros (
servo_13eservo_4) e dianteiros (servo_12eservo_5) são posicionados para manter as quatro pernas abertas simetricamente em ângulos de 45° e 135° em relação à linha de centro longitudinal do chassi. - Articulações Distais (Patas/Elevação): Os motores de elevação verticais (
servo_14,servo_15,servo_16eservo_2) ajustam as patas para tocarem o solo com uma inclinação descendente uniforme, garantindo sustentação da massa total de aproximadamente 280 gramas com centro de gravidade rebaixado.
Lição 4 — Movimento para Frente e para Trás dos Robôs
A geração de locomoção em robôs quadrupedais é obtida através da amostragem periódica de posições angulares discretas coordenadas no tempo. A ACEBOTT estruturou o padrão de caminhada através de matrizes bidimensionais de estados cinemáticos onde cada linha representa uma pose congelada no tempo (quadro-chave ou keyframe) e as colunas representam os ângulos dos 8 motores (G14, G12, G13, G15, G16, G5, G4, G2), acompanhados do tempo de transição e espera em milissegundos (coluna MS).



Experimento 4.1: Programa de Modo de Espera (standby)
No modo de espera, o robô aranha recolhe suas patas e estabiliza o corpo em uma altura média de equilíbrio estático:
#include <Servo.h> // posiciona os 8 servos na postura de espera
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
void setup(){ // posiciona os 8 servos na postura de espera
servo_14.attach(14); // posiciona os 8 servos na postura de espera
servo_12.attach(12); // posiciona os 8 servos na postura de espera
servo_13.attach(13); // posiciona os 8 servos na postura de espera
servo_15.attach(15); // posiciona os 8 servos na postura de espera
servo_16.attach(16); // posiciona os 8 servos na postura de espera
servo_5.attach(5); // posiciona os 8 servos na postura de espera
servo_4.attach(4); // posiciona os 8 servos na postura de espera
servo_2.attach(2); // posiciona os 8 servos na postura de espera
} // posiciona os 8 servos na postura de espera
//Create the standby array
int array1[2][9] = { // posiciona os 8 servos na postura de espera
//G14 G12 G13 G15 G16 G5 G4 G2 MS
{90, 90, 90, 90, 90, 90, 90, 90, 500},//Center point position
{70, 90, 90, 110, 110, 90, 90, 70, 500},//Standby mode
}; // posiciona os 8 servos na postura de espera
//A function that sets the standby state
void standby() { // posiciona os 8 servos na postura de espera
for (int i = 0; i <= 1; i = i + 1) { //There are two sets of arrays that need to be traversed twice
servo_14.write(array1[i][0]); //The servo executes row i and column 1
servo_12.write(array1[i][1]); //The servo executes row i and column 2
servo_13.write(array1[i][2]); //The servo executes row i and column 3
servo_15.write(array1[i][3]); //The servo executes row i and column 4
servo_16.write(array1[i][4]); //The servo executes row i and column 5
servo_5.write(array1[i][5]); //The servo executes row i and column 6
servo_4.write(array1[i][6]); //The servo executes row i and column 7
servo_2.write(array1[i][7]); //The servo executes row i and column 8
delay(array1[i][8]); //Row i, column 9, execution delay time
} // posiciona os 8 servos na postura de espera
} // posiciona os 8 servos na postura de espera
//Run the standby function
void loop() { // posiciona os 8 servos na postura de espera
standby(); // posiciona os 8 servos na postura de espera
delay(1000); // posiciona os 8 servos na postura de espera
} // posiciona os 8 servos na postura de espera
A matriz array1[2][9] transita suavemente entre a posição de ponto central a 90° em todos os eixos e a postura de espera (standby), na qual as patas dianteiras e traseiras flexionam-se para apoiar as extremidades no piso com pressão simétrica.
Experimento 4.2: Programa de Mover para a Frente (forward)
A marcha para a frente decompõe um ciclo completo de caminhada trotante em 11 passos coordenados. Enquanto um par diagonal de pernas se levanta, projeta-se à frente e volta a descer, o par diagonal oposto realiza tração para trás rente ao solo, impulsionando a massa do chassi para frente.
#include <Servo.h> // executa sequência de avanço nos 8 servomotores
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
//Creates an array of action decompositions for moving forward
int array2[11][9] = { //There are 11 arrays with 9 columns
//G14 G12 G13 G15 G16 G5 G4 G2 MS (The latter is uniformly sorted according to this pin)
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Ready for standby
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 120, 90, 110, 110, 90, 60, 90, 200},//Right upper arm and left lower arm forward
{70, 120, 90, 110, 110, 90, 60, 70, 200},//Right upper paw and left lower paw drop
{70, 120, 90, 90, 90, 90, 60, 70, 200},//The left upper paw and right lower paw are raised
{70, 90, 90, 90, 90, 90, 90, 70, 200},//Right upper arm and left lower arm back
{70, 90, 120,90, 90, 60, 90, 70, 200},//Left upper arm and right lower arm forward
{70, 90, 120,110, 110, 60, 90, 70, 200},//Left upper paw and right lower paw drop
{90, 90, 120,110, 110, 60, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 90, 90, 110, 110, 90, 90, 90, 200},//The upper left arm and lower right arm back
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Right upper paw and left lower paw drop
}; // executa sequência de avanço nos 8 servomotores
//Sets the forward function
void forward() { // executa sequência de avanço nos 8 servomotores
for (int i = 0; i <= 10; i = i + 1) { // executa sequência de avanço nos 8 servomotores
servo_14.write(array2[i][0]); // executa sequência de avanço nos 8 servomotores
servo_12.write(array2[i][1]); // executa sequência de avanço nos 8 servomotores
servo_13.write(array2[i][2]); // executa sequência de avanço nos 8 servomotores
servo_15.write(array2[i][3]); // executa sequência de avanço nos 8 servomotores
servo_16.write(array2[i][4]); // executa sequência de avanço nos 8 servomotores
servo_5.write(array2[i][5]); // executa sequência de avanço nos 8 servomotores
servo_4.write(array2[i][6]); // executa sequência de avanço nos 8 servomotores
servo_2.write(array2[i][7]); // executa sequência de avanço nos 8 servomotores
delay(array2[i][8]); // executa sequência de avanço nos 8 servomotores
} // executa sequência de avanço nos 8 servomotores
} // executa sequência de avanço nos 8 servomotores
void setup(){ // executa sequência de avanço nos 8 servomotores
servo_14.attach(14); // executa sequência de avanço nos 8 servomotores
servo_12.attach(12); // executa sequência de avanço nos 8 servomotores
servo_13.attach(13); // executa sequência de avanço nos 8 servomotores
servo_15.attach(15); // executa sequência de avanço nos 8 servomotores
servo_16.attach(16); // executa sequência de avanço nos 8 servomotores
servo_5.attach(5); // executa sequência de avanço nos 8 servomotores
servo_4.attach(4); // executa sequência de avanço nos 8 servomotores
servo_2.attach(2); // executa sequência de avanço nos 8 servomotores
} // executa sequência de avanço nos 8 servomotores
// Run the forward function (to pause, put the swing switch on the servo extension board into OFF gear)
void loop() { // executa sequência de avanço nos 8 servomotores
forward();// The robot may not necessarily walk in a straight line due to errors
} // executa sequência de avanço nos 8 servomotores
A sincronia temporal da coluna 9 (MS = 100 e MS = 60) garante que o tempo de balanço da perna aérea seja ligeiramente menor que o tempo de apoio da perna de tração, evitando perda de contato com a superfície.
Experimento 4.3: Programa de Mover para Trás (back)
A marcha reversa inverte a ordem vetorial de propulsão dos eixos horizontais, mantendo a elevação vertical das patas para descolar a ponta da perna do solo antes de empurrá-la para a frente no ar:
#include <Servo.h> // executa sequência de recuo nos 8 servomotores
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
//Creates a backward-moving action decomposition array
int array3[11][9] = { // executa sequência de recuo nos 8 servomotores
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Ready for standby
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 60, 90, 110, 110, 90, 120,90, 200},//Right upper arm and left lower arm back
{70, 60, 90, 110, 110, 90, 120,70, 200},//Right upper paw and left lower paw drop
{70, 60, 90, 90, 90, 90, 120,70, 200},//The left upper paw and right lower paw are raised
{70, 90, 90, 90, 90, 90, 90, 70, 200},//Right upper arm and left lower arm forward
{70, 90, 60, 90, 90, 120,90, 70, 200},//The upper left arm and lower right arm back
{70, 90, 60,110, 110, 120,90, 70, 200},//Left upper paw and right lower paw drop
{90, 90, 60,110, 110, 120,90, 90, 200},//Right upper paw and left lower paw are raised
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Left upper arm and right lower arm forward
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Right upper paw and left lower paw drop
}; // executa sequência de recuo nos 8 servomotores
//Sets the backoff function
void back() { // executa sequência de recuo nos 8 servomotores
for (int i = 0; i <= 10; i = i + 1) { // executa sequência de recuo nos 8 servomotores
servo_14.write(array3[i][0]); // executa sequência de recuo nos 8 servomotores
servo_12.write(array3[i][1]); // executa sequência de recuo nos 8 servomotores
servo_13.write(array3[i][2]); // executa sequência de recuo nos 8 servomotores
servo_15.write(array3[i][3]); // executa sequência de recuo nos 8 servomotores
servo_16.write(array3[i][4]); // executa sequência de recuo nos 8 servomotores
servo_5.write(array3[i][5]); // executa sequência de recuo nos 8 servomotores
servo_4.write(array3[i][6]); // executa sequência de recuo nos 8 servomotores
servo_2.write(array3[i][7]); // executa sequência de recuo nos 8 servomotores
delay(array3[i][8]); // executa sequência de recuo nos 8 servomotores
} // executa sequência de recuo nos 8 servomotores
} // executa sequência de recuo nos 8 servomotores
void setup(){ // executa sequência de recuo nos 8 servomotores
servo_14.attach(14); // executa sequência de recuo nos 8 servomotores
servo_12.attach(12); // executa sequência de recuo nos 8 servomotores
servo_13.attach(13); // executa sequência de recuo nos 8 servomotores
servo_15.attach(15); // executa sequência de recuo nos 8 servomotores
servo_16.attach(16); // executa sequência de recuo nos 8 servomotores
servo_5.attach(5); // executa sequência de recuo nos 8 servomotores
servo_4.attach(4); // executa sequência de recuo nos 8 servomotores
servo_2.attach(2); // executa sequência de recuo nos 8 servomotores
} // executa sequência de recuo nos 8 servomotores
//Running the backoff program
void loop() { // executa sequência de recuo nos 8 servomotores
back();//Calling the backoff function
} // executa sequência de recuo nos 8 servomotores
Experimento 4.4: Tarefas de Extensão (expand)
Na tarefa de extensão, o código implementa controle dinâmico de marcha através de funções modulares encapsuladas com loops repetitivos, permitindo ao programador invocar caminhadas contínuas por contagem de passos ou tempo determinado:
#include <Servo.h> // ajusta dinamicamente a marcha do robô
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
//Create the standby array
int array1[2][9] = { // ajusta dinamicamente a marcha do robô
//G14 G12 G13 G15 G16 G5 G4 G2 MS
{90, 90, 90, 90, 90, 90, 90, 90, 500},//Center point position
{70, 90, 90, 110, 110, 90, 90, 70, 500},//Standby mode
}; // ajusta dinamicamente a marcha do robô
//Creates an array of action decompositions for moving forward
int array2[11][9] = { //There are 11 arrays with 9 columns
//G14 G12 G13 G15 G16 G5 G4 G2 MS (The latter is uniformly sorted according to this pin)
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Ready for standby
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 120, 90, 110, 110, 90, 60, 90, 200},//Right upper arm and left lower arm forward
{70, 120, 90, 110, 110, 90, 60, 70, 200},//Right upper paw and left lower paw drop
{70, 120, 90, 90, 90, 90, 60, 70, 200},//The left upper paw and right lower paw are raised
{70, 90, 90, 90, 90, 90, 90, 70, 200},//Right upper arm and left lower arm back
{70, 90, 120,90, 90, 60, 90, 70, 200},//Left upper arm and right lower arm forward
{70, 90, 120,110, 110, 60, 90, 70, 200},//Left upper paw and right lower paw drop
{90, 90, 120,110, 110, 60, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 90, 90, 110, 110, 90, 90, 90, 200},//The upper left arm and lower right arm back
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Right upper paw and left lower paw drop
}; // ajusta dinamicamente a marcha do robô
//Creates a backward-moving action decomposition array
int array3[11][9] = { // ajusta dinamicamente a marcha do robô
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Ready for standby
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 60, 90, 110, 110, 90, 120,90, 200},//Right upper arm and left lower arm back
{70, 60, 90, 110, 110, 90, 120,70, 200},//Right upper paw and left lower paw drop
{70, 60, 90, 90, 90, 90, 120,70, 200},//The left upper paw and right lower paw are raised
{70, 90, 90, 90, 90, 90, 90, 70, 200},//Right upper arm and left lower arm forward
{70, 90, 60, 90, 90, 120,90, 70, 200},//The upper left arm and lower right arm back
{70, 90, 60,110, 110, 120,90, 70, 200},//Left upper paw and right lower paw drop
{90, 90, 60,110, 110, 120,90, 90, 200},//Right upper paw and left lower paw are raised
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Left upper arm and right lower arm forward
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Right upper paw and left lower paw drop
}; // ajusta dinamicamente a marcha do robô
//A function that sets the standby state
void standby() { // ajusta dinamicamente a marcha do robô
for (int i = 0; i <= 1; i = i + 1) { //There are two sets of arrays that need to be traversed twice
servo_14.write(array1[i][0]); //The servo executes row i and column 1
servo_12.write(array1[i][1]); //The servo executes row i and column 2
servo_13.write(array1[i][2]); //The servo executes row i and column 3
servo_15.write(array1[i][3]); //The servo executes row i and column 4
servo_16.write(array1[i][4]); //The servo executes row i and column 5
servo_5.write(array1[i][5]); //The servo executes row i and column 6
servo_4.write(array1[i][6]); //The servo executes row i and column 7
servo_2.write(array1[i][7]); //The servo executes row i and column 8
delay(array1[i][8]); //Row i, column 9, execution delay time
} // ajusta dinamicamente a marcha do robô
} // ajusta dinamicamente a marcha do robô
//Sets the forward function
void forward() { // ajusta dinamicamente a marcha do robô
for (int i = 0; i <= 10; i = i + 1) { // ajusta dinamicamente a marcha do robô
servo_14.write(array2[i][0]); // ajusta dinamicamente a marcha do robô
servo_12.write(array2[i][1]); // ajusta dinamicamente a marcha do robô
servo_13.write(array2[i][2]); // ajusta dinamicamente a marcha do robô
servo_15.write(array2[i][3]); // ajusta dinamicamente a marcha do robô
servo_16.write(array2[i][4]); // ajusta dinamicamente a marcha do robô
servo_5.write(array2[i][5]); // ajusta dinamicamente a marcha do robô
servo_4.write(array2[i][6]); // ajusta dinamicamente a marcha do robô
servo_2.write(array2[i][7]); // ajusta dinamicamente a marcha do robô
delay(array2[i][8]); // ajusta dinamicamente a marcha do robô
} // ajusta dinamicamente a marcha do robô
} // ajusta dinamicamente a marcha do robô
//Sets the backoff function
void back() { // ajusta dinamicamente a marcha do robô
for (int i = 0; i <= 10; i = i + 1) { // ajusta dinamicamente a marcha do robô
servo_14.write(array3[i][0]); // ajusta dinamicamente a marcha do robô
servo_12.write(array3[i][1]); // ajusta dinamicamente a marcha do robô
servo_13.write(array3[i][2]); // ajusta dinamicamente a marcha do robô
servo_15.write(array3[i][3]); // ajusta dinamicamente a marcha do robô
servo_16.write(array3[i][4]); // ajusta dinamicamente a marcha do robô
servo_5.write(array3[i][5]); // ajusta dinamicamente a marcha do robô
servo_4.write(array3[i][6]); // ajusta dinamicamente a marcha do robô
servo_2.write(array3[i][7]); // ajusta dinamicamente a marcha do robô
delay(array3[i][8]); // ajusta dinamicamente a marcha do robô
} // ajusta dinamicamente a marcha do robô
} // ajusta dinamicamente a marcha do robô
void setup(){ // ajusta dinamicamente a marcha do robô
servo_14.attach(14); // ajusta dinamicamente a marcha do robô
servo_12.attach(12); // ajusta dinamicamente a marcha do robô
servo_13.attach(13); // ajusta dinamicamente a marcha do robô
servo_15.attach(15); // ajusta dinamicamente a marcha do robô
servo_16.attach(16); // ajusta dinamicamente a marcha do robô
servo_5.attach(5); // ajusta dinamicamente a marcha do robô
servo_4.attach(4); // ajusta dinamicamente a marcha do robô
servo_2.attach(2); // ajusta dinamicamente a marcha do robô
} // ajusta dinamicamente a marcha do robô
void loop() { // ajusta dinamicamente a marcha do robô
for (int i = 0; i <= 2; i = i + 1){ // ajusta dinamicamente a marcha do robô
forward();//Move forward three times
} // ajusta dinamicamente a marcha do robô
for (int i = 0; i <= 1; i = i + 1){ // ajusta dinamicamente a marcha do robô
back();//Move backwards twice
} // ajusta dinamicamente a marcha do robô
standby();//Standby mode
} // ajusta dinamicamente a marcha do robô
Lição 5 — Rotação à Direita e à Esquerda do Robô
Para efetuar curvas no próprio eixo (giro sobre o centro geométrico com raio nulo), o robô aranha utiliza o princípio dos torques opostos. As pernas do lado direito executam passos com orientação angular de avanço para frente, enquanto as pernas do lado esquerdo executam passos simultâneos orientados para trás.


Experimento 5.1: Programa de Rotação à Esquerda (turn_left)
A rotação anti-horária aplica uma decomposição de 9 estados cinemáticos na matriz array4[9][9]:
#include <Servo.h> // executa rotação anti-horária sobre o eixo central
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
//Create an array of turns to the left. By default, the robot rotates 22.5 degrees
int array6[8][9] = { // executa rotação anti-horária sobre o eixo central
//G14 G12 G13 G15 G16 G5 G4 G2 MS
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Ready for standby
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 135, 90, 110, 110, 90,135, 90, 200},//Right upper arm forward, left lower arm back
{70, 135, 90, 110, 110, 90,135, 70, 200},//Right upper paw and left lower paw drop
{70, 135, 90, 90, 90, 90, 135, 70, 200},//The left upper paw and right lower paw are raised
{70, 135, 135, 90, 90, 135,135, 70, 200},//Put your upper left arm back and your lower right arm forward
{70, 135, 135, 110, 110, 135,135, 70, 200},//Left upper paw and right lower paw drop
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Four arms rotation
}; // executa rotação anti-horária sobre o eixo central
//A function that sets the left turn
void turnleft() { // executa rotação anti-horária sobre o eixo central
for (int i = 0; i <= 7; i = i + 1) { // executa rotação anti-horária sobre o eixo central
servo_14.write(array6[i][0]); // executa rotação anti-horária sobre o eixo central
servo_12.write(array6[i][1]); // executa rotação anti-horária sobre o eixo central
servo_13.write(array6[i][2]); // executa rotação anti-horária sobre o eixo central
servo_15.write(array6[i][3]); // executa rotação anti-horária sobre o eixo central
servo_16.write(array6[i][4]); // executa rotação anti-horária sobre o eixo central
servo_5.write(array6[i][5]); // executa rotação anti-horária sobre o eixo central
servo_4.write(array6[i][6]); // executa rotação anti-horária sobre o eixo central
servo_2.write(array6[i][7]); // executa rotação anti-horária sobre o eixo central
delay(array6[i][8]); // executa rotação anti-horária sobre o eixo central
} // executa rotação anti-horária sobre o eixo central
} // executa rotação anti-horária sobre o eixo central
void setup(){ // executa rotação anti-horária sobre o eixo central
servo_14.attach(14); // executa rotação anti-horária sobre o eixo central
servo_12.attach(12); // executa rotação anti-horária sobre o eixo central
servo_13.attach(13); // executa rotação anti-horária sobre o eixo central
servo_15.attach(15); // executa rotação anti-horária sobre o eixo central
servo_16.attach(16); // executa rotação anti-horária sobre o eixo central
servo_5.attach(5); // executa rotação anti-horária sobre o eixo central
servo_4.attach(4); // executa rotação anti-horária sobre o eixo central
servo_2.attach(2); // executa rotação anti-horária sobre o eixo central
} // executa rotação anti-horária sobre o eixo central
//Run the left turn
void loop() { // executa rotação anti-horária sobre o eixo central
turnleft(); // executa rotação anti-horária sobre o eixo central
} // executa rotação anti-horária sobre o eixo central
O momento angular de guinada resultante é positivo em relação ao eixo vertical :
Experimento 5.2: Programa de Rotação à Direita (turn_right)
Invertendo-se a polaridade dos vetores angulares horizontais, o robô executa giro horário suave:
#include <Servo.h> // executa rotação horária sobre o eixo central
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
//Create an array of actions for turning right (for setting the rotation Angle, see instructions for turning left arrays)
int array7[8][9] = { // executa rotação horária sobre o eixo central
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Ready for standby
{70, 90, 90, 90, 90, 90, 90, 70, 200},//The left upper paw and right lower paw are raised
{70, 90, 45, 90, 90, 45, 90, 70, 200},//The upper left arm goes forward and the lower right arm goes back
{70, 90, 45, 110, 110, 45, 90, 70, 200},//Left upper paw and right lower paw drop
{90, 90, 45, 110, 110, 45, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 45, 45, 110, 110, 45, 45, 90, 200},//Right upper arm back, left lower arm forward
{70, 45, 45, 110, 110, 45, 45, 70, 200},//Right upper paw and left lower paw drop
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Four arms rotation
}; // executa rotação horária sobre o eixo central
//A function that sets the right turn
void turnright() { // executa rotação horária sobre o eixo central
for (int i = 0; i <= 7; i = i + 1) { // executa rotação horária sobre o eixo central
servo_14.write(array7[i][0]); // executa rotação horária sobre o eixo central
servo_12.write(array7[i][1]); // executa rotação horária sobre o eixo central
servo_13.write(array7[i][2]); // executa rotação horária sobre o eixo central
servo_15.write(array7[i][3]); // executa rotação horária sobre o eixo central
servo_16.write(array7[i][4]); // executa rotação horária sobre o eixo central
servo_5.write(array7[i][5]); // executa rotação horária sobre o eixo central
servo_4.write(array7[i][6]); // executa rotação horária sobre o eixo central
servo_2.write(array7[i][7]); // executa rotação horária sobre o eixo central
delay(array7[i][8]); // executa rotação horária sobre o eixo central
} // executa rotação horária sobre o eixo central
} // executa rotação horária sobre o eixo central
void setup(){ // executa rotação horária sobre o eixo central
servo_14.attach(14); // executa rotação horária sobre o eixo central
servo_12.attach(12); // executa rotação horária sobre o eixo central
servo_13.attach(13); // executa rotação horária sobre o eixo central
servo_15.attach(15); // executa rotação horária sobre o eixo central
servo_16.attach(16); // executa rotação horária sobre o eixo central
servo_5.attach(5); // executa rotação horária sobre o eixo central
servo_4.attach(4); // executa rotação horária sobre o eixo central
servo_2.attach(2); // executa rotação horária sobre o eixo central
} // executa rotação horária sobre o eixo central
//Run the right turn
void loop() { // executa rotação horária sobre o eixo central
turnright(); // executa rotação horária sobre o eixo central
} // executa rotação horária sobre o eixo central
Experimento 5.3: Tarefas de Extensão (expand2)
Neste projeto avançado, as rotinas de curva são encapsuladas em funções com parâmetros de repetição para execução de manobras de desvio de 90° e 180°:
#include <Servo.h> // aplica interpolação contínua de giro
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
//Creates an array of action decompositions for moving forward
int array2[11][9] = { //There are 11 arrays with 9 columns
//G14 G12 G13 G15 G16 G5 G4 G2 MS (The latter is uniformly sorted according to this pin)
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Ready for standby
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 120, 90, 110, 110, 90, 60, 90, 200},//Right upper arm and left lower arm forward
{70, 120, 90, 110, 110, 90, 60, 70, 200},//Right upper paw and left lower paw drop
{70, 120, 90, 90, 90, 90, 60, 70, 200},//The left upper paw and right lower paw are raised
{70, 90, 90, 90, 90, 90, 90, 70, 200},//Right upper arm and left lower arm back
{70, 90, 120,90, 90, 60, 90, 70, 200},//Left upper arm and right lower arm forward
{70, 90, 120,110, 110, 60, 90, 70, 200},//Left upper paw and right lower paw drop
{90, 90, 120,110, 110, 60, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 90, 90, 110, 110, 90, 90, 90, 200},//The upper left arm and lower right arm back
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Right upper paw and left lower paw drop
}; // aplica interpolação contínua de giro
//Create an array of turns to the left. By default, the robot rotates 22.5 degrees
int array6[8][9] = { // aplica interpolação contínua de giro
//G14 G12 G13 G15 G16 G5 G4 G2 MS
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Ready for standby
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 135, 90, 110, 110, 90,135, 90, 200},//Right upper arm forward, left lower arm back
{70, 135, 90, 110, 110, 90,135, 70, 200},//Right upper paw and left lower paw drop
{70, 135, 90, 90, 90, 90, 135, 70, 200},//The left upper paw and right lower paw are raised
{70, 135, 135, 90, 90, 135,135, 70, 200},//Put your upper left arm back and your lower right arm forward
{70, 135, 135, 110, 110, 135,135, 70, 200},//Left upper paw and right lower paw drop
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Four arms rotation
}; // aplica interpolação contínua de giro
//Create an array of actions for turning right (for setting the rotation Angle, see instructions for turning left arrays)
int array7[8][9] = { // aplica interpolação contínua de giro
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Ready for standby
{70, 90, 90, 90, 90, 90, 90, 70, 200},//The left upper paw and right lower paw are raised
{70, 90, 45, 90, 90, 45, 90, 70, 200},//The upper left arm goes forward and the lower right arm goes back
{70, 90, 45, 110, 110, 45, 90, 70, 200},//Left upper paw and right lower paw drop
{90, 90, 45, 110, 110, 45, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 45, 45, 110, 110, 45, 45, 90, 200},//Right upper arm back, left lower arm forward
{70, 45, 45, 110, 110, 45, 45, 70, 200},//Right upper paw and left lower paw drop
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Four arms rotation
}; // aplica interpolação contínua de giro
//Sets the forward function
void forward() { // aplica interpolação contínua de giro
for (int i = 0; i <= 10; i = i + 1) { // aplica interpolação contínua de giro
servo_14.write(array2[i][0]); // aplica interpolação contínua de giro
servo_12.write(array2[i][1]); // aplica interpolação contínua de giro
servo_13.write(array2[i][2]); // aplica interpolação contínua de giro
servo_15.write(array2[i][3]); // aplica interpolação contínua de giro
servo_16.write(array2[i][4]); // aplica interpolação contínua de giro
servo_5.write(array2[i][5]); // aplica interpolação contínua de giro
servo_4.write(array2[i][6]); // aplica interpolação contínua de giro
servo_2.write(array2[i][7]); // aplica interpolação contínua de giro
delay(array2[i][8]); // aplica interpolação contínua de giro
} // aplica interpolação contínua de giro
} // aplica interpolação contínua de giro
//A function that sets the left turn
void turnleft() { // aplica interpolação contínua de giro
for (int i = 0; i <= 7; i = i + 1) { // aplica interpolação contínua de giro
servo_14.write(array6[i][0]); // aplica interpolação contínua de giro
servo_12.write(array6[i][1]); // aplica interpolação contínua de giro
servo_13.write(array6[i][2]); // aplica interpolação contínua de giro
servo_15.write(array6[i][3]); // aplica interpolação contínua de giro
servo_16.write(array6[i][4]); // aplica interpolação contínua de giro
servo_5.write(array6[i][5]); // aplica interpolação contínua de giro
servo_4.write(array6[i][6]); // aplica interpolação contínua de giro
servo_2.write(array6[i][7]); // aplica interpolação contínua de giro
delay(array6[i][8]); // aplica interpolação contínua de giro
} // aplica interpolação contínua de giro
} // aplica interpolação contínua de giro
//A function that sets the right turn
void turnright() { // aplica interpolação contínua de giro
for (int i = 0; i <= 7; i = i + 1) { // aplica interpolação contínua de giro
servo_14.write(array7[i][0]); // aplica interpolação contínua de giro
servo_12.write(array7[i][1]); // aplica interpolação contínua de giro
servo_13.write(array7[i][2]); // aplica interpolação contínua de giro
servo_15.write(array7[i][3]); // aplica interpolação contínua de giro
servo_16.write(array7[i][4]); // aplica interpolação contínua de giro
servo_5.write(array7[i][5]); // aplica interpolação contínua de giro
servo_4.write(array7[i][6]); // aplica interpolação contínua de giro
servo_2.write(array7[i][7]); // aplica interpolação contínua de giro
delay(array7[i][8]); // aplica interpolação contínua de giro
} // aplica interpolação contínua de giro
} // aplica interpolação contínua de giro
void setup(){ // aplica interpolação contínua de giro
servo_14.attach(14); // aplica interpolação contínua de giro
servo_12.attach(12); // aplica interpolação contínua de giro
servo_13.attach(13); // aplica interpolação contínua de giro
servo_15.attach(15); // aplica interpolação contínua de giro
servo_16.attach(16); // aplica interpolação contínua de giro
servo_5.attach(5); // aplica interpolação contínua de giro
servo_4.attach(4); // aplica interpolação contínua de giro
servo_2.attach(2); // aplica interpolação contínua de giro
} // aplica interpolação contínua de giro
//Four edges need to repeat forward and rotation actions four times, preferentially using the traversal loop.
void loop() { // aplica interpolação contínua de giro
for (int i = 0; i <= 3; i = i + 1){ // aplica interpolação contínua de giro
for (int i = 0; i <= 2; i = i + 1){ // aplica interpolação contínua de giro
forward(); //Three times forward
} // aplica interpolação contínua de giro
for (int i = 0; i <= 3; i = i + 1){ // aplica interpolação contínua de giro
turnright(); //One rotate it four times to the right, which is about 90 degrees
} // aplica interpolação contínua de giro
} // aplica interpolação contínua de giro
} // aplica interpolação contínua de giro
Lição 6 — Movimento à Esquerda e à Direita do Robô (Passo de Caranguejo e Aceno)
Uma das capacidades mais impressionantes do robô aranha de 8 servomotores é a locomoção holonômica lateral (crab walk). Sem girar a carcaça do robô, ele é capaz de caminhar lateralmente para a esquerda ou direita coordenando a abertura das patas de um lado com o fechamento das patas do lado oposto.



Experimento 6.1: Programa de Deslocamento Lateral Esquerdo (left_move)
O algoritmo sincroniza os servos em 11 quadros-chave na matriz array6[11][9]:
#include <Servo.h> // translada o quadrúpede lateralmente para a esquerda
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
//Create an array of moves to the left
int array4[11][9] = { // translada o quadrúpede lateralmente para a esquerda
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Ready for standby
{70, 90, 90, 90, 90, 90, 90, 70, 200},//The left upper paw and right lower paw are raised
{70, 90, 60, 90, 90, 120,90, 70, 200},//The upper left arm and lower right arm back
{70, 90, 60, 110, 110, 120,90, 70, 200},//Left upper paw and right lower paw drop
{90, 90, 60, 110, 110, 120,90, 90, 200},//Right upper paw and left lower paw are raised
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Left upper arm and right lower arm forward
{90, 120,90, 110, 110, 90, 60, 90, 200},//Right upper arm and left lower arm forward
{70, 120,90, 110, 110, 90, 60, 70, 200},//Right upper paw and left lower paw drop
{70, 120,90, 90, 90, 90, 60, 70, 200},//The left upper paw and right lower paw are raised
{70, 90, 90, 90, 90, 90, 90, 70, 200},//Right upper arm and left lower arm back
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Left upper paw and right lower paw drop
}; // translada o quadrúpede lateralmente para a esquerda
//Sets the function to move to the left
void leftmove() { // translada o quadrúpede lateralmente para a esquerda
for (int i = 0; i <= 10; i = i + 1) { // translada o quadrúpede lateralmente para a esquerda
servo_14.write(array4[i][0]); // translada o quadrúpede lateralmente para a esquerda
servo_12.write(array4[i][1]); // translada o quadrúpede lateralmente para a esquerda
servo_13.write(array4[i][2]); // translada o quadrúpede lateralmente para a esquerda
servo_15.write(array4[i][3]); // translada o quadrúpede lateralmente para a esquerda
servo_16.write(array4[i][4]); // translada o quadrúpede lateralmente para a esquerda
servo_5.write(array4[i][5]); // translada o quadrúpede lateralmente para a esquerda
servo_4.write(array4[i][6]); // translada o quadrúpede lateralmente para a esquerda
servo_2.write(array4[i][7]); // translada o quadrúpede lateralmente para a esquerda
delay(array4[i][8]); // translada o quadrúpede lateralmente para a esquerda
} // translada o quadrúpede lateralmente para a esquerda
} // translada o quadrúpede lateralmente para a esquerda
void setup() { // translada o quadrúpede lateralmente para a esquerda
servo_14.attach(14); // translada o quadrúpede lateralmente para a esquerda
servo_12.attach(12); // translada o quadrúpede lateralmente para a esquerda
servo_13.attach(13); // translada o quadrúpede lateralmente para a esquerda
servo_15.attach(15); // translada o quadrúpede lateralmente para a esquerda
servo_16.attach(16); // translada o quadrúpede lateralmente para a esquerda
servo_5.attach(5); // translada o quadrúpede lateralmente para a esquerda
servo_4.attach(4); // translada o quadrúpede lateralmente para a esquerda
servo_2.attach(2); // translada o quadrúpede lateralmente para a esquerda
} // translada o quadrúpede lateralmente para a esquerda
// Run the program moved to the left
void loop() { // translada o quadrúpede lateralmente para a esquerda
leftmove(); // translada o quadrúpede lateralmente para a esquerda
} // translada o quadrúpede lateralmente para a esquerda
Experimento 6.2: Programa de Deslocamento Lateral Direito (right_move)
A translação lateral para a direita reflete a cinemática de avanço sobre a matriz array7[11][9]:
#include <Servo.h> // translada o quadrúpede lateralmente para a direita
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
//Create an array of actions to move to the right
int array5[11][9] = { // translada o quadrúpede lateralmente para a direita
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Ready for standby
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 60, 90, 110, 110, 90, 120,90, 200},//Right upper arm and left lower arm back
{70, 60, 90, 110, 110, 90, 120,70, 200},//Right upper paw and left lower paw drop
{70, 60, 90, 90, 90, 90, 120,70, 200},//The left upper paw and right lower paw are raised
{70, 90, 90, 90, 90, 90, 90, 70, 200},//Right upper arm and left lower arm forward
{70, 90, 120,90, 90, 60, 90, 70, 200},//Left upper arm and right lower arm forward
{70, 90, 120,110, 110, 60, 90, 70, 200},//Left upper paw and right lower paw drop
{90, 90, 120,110, 110, 60, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 90, 90, 110, 110, 90, 90, 90, 200},//The upper left arm and lower right arm back
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Right upper paw and left lower paw drop
}; // translada o quadrúpede lateralmente para a direita
//Sets the function to move to the right
void rightmove() { // translada o quadrúpede lateralmente para a direita
for (int i = 0; i <= 10; i = i + 1) { // translada o quadrúpede lateralmente para a direita
servo_14.write(array5[i][0]); // translada o quadrúpede lateralmente para a direita
servo_12.write(array5[i][1]); // translada o quadrúpede lateralmente para a direita
servo_13.write(array5[i][2]); // translada o quadrúpede lateralmente para a direita
servo_15.write(array5[i][3]); // translada o quadrúpede lateralmente para a direita
servo_16.write(array5[i][4]); // translada o quadrúpede lateralmente para a direita
servo_5.write(array5[i][5]); // translada o quadrúpede lateralmente para a direita
servo_4.write(array5[i][6]); // translada o quadrúpede lateralmente para a direita
servo_2.write(array5[i][7]); // translada o quadrúpede lateralmente para a direita
delay(array5[i][8]); // translada o quadrúpede lateralmente para a direita
} // translada o quadrúpede lateralmente para a direita
} // translada o quadrúpede lateralmente para a direita
void setup() { // translada o quadrúpede lateralmente para a direita
servo_14.attach(14); // translada o quadrúpede lateralmente para a direita
servo_12.attach(12); // translada o quadrúpede lateralmente para a direita
servo_13.attach(13); // translada o quadrúpede lateralmente para a direita
servo_15.attach(15); // translada o quadrúpede lateralmente para a direita
servo_16.attach(16); // translada o quadrúpede lateralmente para a direita
servo_5.attach(5); // translada o quadrúpede lateralmente para a direita
servo_4.attach(4); // translada o quadrúpede lateralmente para a direita
servo_2.attach(2); // translada o quadrúpede lateralmente para a direita
} // translada o quadrúpede lateralmente para a direita
// Run the program moved to the right
void loop() { // translada o quadrúpede lateralmente para a direita
rightmove(); // translada o quadrúpede lateralmente para a direita
} // translada o quadrúpede lateralmente para a direita
Experimento 6.3: Programa de Saudação e Aceno (say_hello)
No gesto de saudação, o robô aranha desloca ligeiramente seu centro de massa para a retaguarda e para a esquerda, formando um triângulo de suporte estático indeformável com as patas LF, LH e RH. A pata dianteira direita (RF) eleva-se no ar e executa uma oscilação pendular rápida simulando um aceno amigável:
#include <Servo.h> // mantém apoio em 3 patas e acena com a pata dianteira
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
//Create an array of hello actions
int array8[7][9] = { // mantém apoio em 3 patas e acena com a pata dianteira
{70, 90, 135, 90, 90, 90, 90, 90, 400},//Left upper paw, right lower paw, left lower paw down
{170, 90, 135, 90, 90, 90, 90, 90, 400},//Right upper paw raised
{170, 130, 135, 90, 90, 90, 90, 90, 400},//Swing your right upper arm forward
{170, 50, 135, 90, 90, 90, 90, 90, 400},//Swing your right upper arm back
{170, 130, 135, 90, 90, 90, 90, 90, 400},//Swing your right upper arm forward
{170, 90, 135, 90, 90, 90, 90, 90, 400},//Swing your right upper arm back
{70, 90, 135, 90, 90, 90, 90, 90, 400},//Right upper arm down
}; // mantém apoio em 3 patas e acena com a pata dianteira
//Set the hello function
void hello() { // mantém apoio em 3 patas e acena com a pata dianteira
for (int i = 0; i <= 6; i = i + 1) { // mantém apoio em 3 patas e acena com a pata dianteira
servo_14.write(array8[i][0]); // mantém apoio em 3 patas e acena com a pata dianteira
servo_12.write(array8[i][1]); // mantém apoio em 3 patas e acena com a pata dianteira
servo_13.write(array8[i][2]); // mantém apoio em 3 patas e acena com a pata dianteira
servo_15.write(array8[i][3]); // mantém apoio em 3 patas e acena com a pata dianteira
servo_16.write(array8[i][4]); // mantém apoio em 3 patas e acena com a pata dianteira
servo_5.write(array8[i][5]); // mantém apoio em 3 patas e acena com a pata dianteira
servo_4.write(array8[i][6]); // mantém apoio em 3 patas e acena com a pata dianteira
servo_2.write(array8[i][7]); // mantém apoio em 3 patas e acena com a pata dianteira
delay(array8[i][8]); // mantém apoio em 3 patas e acena com a pata dianteira
} // mantém apoio em 3 patas e acena com a pata dianteira
} // mantém apoio em 3 patas e acena com a pata dianteira
void setup() { // mantém apoio em 3 patas e acena com a pata dianteira
servo_14.attach(14); // mantém apoio em 3 patas e acena com a pata dianteira
servo_12.attach(12); // mantém apoio em 3 patas e acena com a pata dianteira
servo_13.attach(13); // mantém apoio em 3 patas e acena com a pata dianteira
servo_15.attach(15); // mantém apoio em 3 patas e acena com a pata dianteira
servo_16.attach(16); // mantém apoio em 3 patas e acena com a pata dianteira
servo_5.attach(5); // mantém apoio em 3 patas e acena com a pata dianteira
servo_4.attach(4); // mantém apoio em 3 patas e acena com a pata dianteira
servo_2.attach(2); // mantém apoio em 3 patas e acena com a pata dianteira
} // mantém apoio em 3 patas e acena com a pata dianteira
// Run the hello program
void loop() { // mantém apoio em 3 patas e acena com a pata dianteira
hello(); // mantém apoio em 3 patas e acena com a pata dianteira
} // mantém apoio em 3 patas e acena com a pata dianteira
Lição 7 — Programa de Dança do Robô
As rotinas de dança combinam modulação periódica de altura (flexão e extensão de joelhos/patas) com oscilação harmônica de rotação de ombros, explorando os limites de aceleração dos servomotores para criar coreografias rítmicas cativantes.




Experimento 7.1: Dança 1 — Balanço e Agachamento Sincronizado (dance1)
A primeira dança executa movimentos suaves de ondulação corporal:
#include <Servo.h> // executa coreografia de balanço e flexão sincronizada
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
//Create an action array for the elementary step
int array9[10][9] = { // executa coreografia de balanço e flexão sincronizada
{90, 90, 90, 90, 90, 90, 90, 90, 400},//Lift all four paws
{50, 90, 90, 90, 90, 90, 90, 90, 400},//Right upper paw down
{90, 90, 90, 130, 90, 90, 90, 90, 400},//Right upper paw up, right lower paw down
{90, 90, 90, 90, 90, 90, 90, 50, 400},//Right lower paw up , left lower paw down
{90, 90, 90, 90, 130, 90, 90, 90, 400},//Left upper paw down, left lower paw up
{50, 90, 90, 90, 90, 90, 90, 90, 400},//Left upper paw up, right upper paw down
{90, 90, 90, 130, 90, 90, 90, 90, 400},//Right upper paw up, right lower paw down
{90, 90, 90, 90, 90, 90, 90, 50, 400},//Right lower paw up,left lower paw down
{90, 90, 90, 90, 130, 90, 90, 90, 400},//Left upper paw down, left lower paw up
{90, 90, 90, 90, 90, 90, 90, 90, 400},//Left upper paw up
}; // executa coreografia de balanço e flexão sincronizada
//A function to set the elementary steps
void dance1() { // executa coreografia de balanço e flexão sincronizada
for (int i = 0; i <= 9; i = i + 1) { // executa coreografia de balanço e flexão sincronizada
servo_14.write(array9[i][0]); // executa coreografia de balanço e flexão sincronizada
servo_12.write(array9[i][1]); // executa coreografia de balanço e flexão sincronizada
servo_13.write(array9[i][2]); // executa coreografia de balanço e flexão sincronizada
servo_15.write(array9[i][3]); // executa coreografia de balanço e flexão sincronizada
servo_16.write(array9[i][4]); // executa coreografia de balanço e flexão sincronizada
servo_5.write(array9[i][5]); // executa coreografia de balanço e flexão sincronizada
servo_4.write(array9[i][6]); // executa coreografia de balanço e flexão sincronizada
servo_2.write(array9[i][7]); // executa coreografia de balanço e flexão sincronizada
delay(array9[i][8]); // executa coreografia de balanço e flexão sincronizada
} // executa coreografia de balanço e flexão sincronizada
} // executa coreografia de balanço e flexão sincronizada
void setup() { // executa coreografia de balanço e flexão sincronizada
servo_14.attach(14); // executa coreografia de balanço e flexão sincronizada
servo_12.attach(12); // executa coreografia de balanço e flexão sincronizada
servo_13.attach(13); // executa coreografia de balanço e flexão sincronizada
servo_15.attach(15); // executa coreografia de balanço e flexão sincronizada
servo_16.attach(16); // executa coreografia de balanço e flexão sincronizada
servo_5.attach(5); // executa coreografia de balanço e flexão sincronizada
servo_4.attach(4); // executa coreografia de balanço e flexão sincronizada
servo_2.attach(2); // executa coreografia de balanço e flexão sincronizada
} // executa coreografia de balanço e flexão sincronizada
//Run the program for the elementary step
void loop() { // executa coreografia de balanço e flexão sincronizada
dance1(); // executa coreografia de balanço e flexão sincronizada
delay(1000); // executa coreografia de balanço e flexão sincronizada
} // executa coreografia de balanço e flexão sincronizada
Experimento 7.2: Dança 2 — Pulso Alternado em Diagonal (dance2)
A segunda dança utiliza transições mais enérgicas com passos de 60 milissegundos:
#include <Servo.h> // executa passos rítmicos cruzados em diagonal
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
//Create an action array for intermediate steps
int array10[9][9] = { // executa passos rítmicos cruzados em diagonal
{70, 45, 135, 110, 110, 135, 45, 70, 400},//The four arms are left and right together
{115, 45, 135, 65, 110, 135, 45, 70, 400},//Right upper paw and right lower paw are raised
{70, 45, 135, 110, 65, 135, 45, 115, 400},//Right upper and lower paws down,left upper and lower paws up
{115, 45, 135, 65, 110, 135, 45, 70, 400},//Left upper and lower paws down,right upper and lower paws up
{70, 45, 135, 110, 65, 135, 45, 115, 400},//Right upper and lower paws down,left upper and lower paws up
{115, 45, 135, 65, 110, 135, 45, 70, 400},//Left upper and lower paws down,right upper and lower paws up
{70, 45, 135, 110, 65, 135, 45, 115, 400},//Right upper and lower paws down,left upper and lower paws up
{115, 45, 135, 65, 110, 135, 45, 70, 400},//Left upper and lower paws down,right upper and lower paws up
{75, 45, 135, 105, 110, 135, 45, 70, 400},//Right upper paw and right lower paw down
}; // executa passos rítmicos cruzados em diagonal
//A function to set intermediate steps
void dance2() { // executa passos rítmicos cruzados em diagonal
for (int i = 0; i <= 8; i = i + 1) { // executa passos rítmicos cruzados em diagonal
servo_14.write(array10[i][0]); // executa passos rítmicos cruzados em diagonal
servo_12.write(array10[i][1]); // executa passos rítmicos cruzados em diagonal
servo_13.write(array10[i][2]); // executa passos rítmicos cruzados em diagonal
servo_15.write(array10[i][3]); // executa passos rítmicos cruzados em diagonal
servo_16.write(array10[i][4]); // executa passos rítmicos cruzados em diagonal
servo_5.write(array10[i][5]); // executa passos rítmicos cruzados em diagonal
servo_4.write(array10[i][6]); // executa passos rítmicos cruzados em diagonal
servo_2.write(array10[i][7]); // executa passos rítmicos cruzados em diagonal
delay(array10[i][8]); // executa passos rítmicos cruzados em diagonal
} // executa passos rítmicos cruzados em diagonal
} // executa passos rítmicos cruzados em diagonal
void setup() { // executa passos rítmicos cruzados em diagonal
servo_14.attach(14); // executa passos rítmicos cruzados em diagonal
servo_12.attach(12); // executa passos rítmicos cruzados em diagonal
servo_13.attach(13); // executa passos rítmicos cruzados em diagonal
servo_15.attach(15); // executa passos rítmicos cruzados em diagonal
servo_16.attach(16); // executa passos rítmicos cruzados em diagonal
servo_5.attach(5); // executa passos rítmicos cruzados em diagonal
servo_4.attach(4); // executa passos rítmicos cruzados em diagonal
servo_2.attach(2); // executa passos rítmicos cruzados em diagonal
} // executa passos rítmicos cruzados em diagonal
//Run the intermediate step program
void loop() { // executa passos rítmicos cruzados em diagonal
dance2(); // executa passos rítmicos cruzados em diagonal
delay(1000); // executa passos rítmicos cruzados em diagonal
} // executa passos rítmicos cruzados em diagonal
Experimento 7.3: Dança 3 — Torção Helicoidal (dance3)
A terceira dança conjuga torção de quadril com abaixamento alternado do chassi:
#include <Servo.h> // executa torção helicoidal com movimentação de patas
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
//Create an action array for advanced steps
int array11[10][9] = { // executa torção helicoidal com movimentação de patas
{70, 45, 45, 110, 110, 135, 135, 70, 400},//All four arms back
{90, 45, 45, 60, 90, 135, 135, 70, 400},//Right upper paw, left upper paw, right lower paw up
{70, 45, 45, 110, 110, 135, 135, 70, 400},//Right upper paw, left upper paw and right lower paw down
{90, 45, 45, 110, 90, 135, 135, 120, 400},//Right upper paw, left upper paw, left lower paw up
{70, 45, 45, 110, 110, 135, 135, 70, 400},//Right upper paw, left upper paw and left lower paw down
{90, 45, 45, 60, 90, 135, 135, 70, 400},//Right upper paw, left upper paw, right lower paw up
{70, 45, 45, 110, 110, 135, 135, 70, 400},//Right upper paw, left upper paw and right lower paw down
{90, 45, 45, 110, 90, 135, 135, 120, 400},//Right upper paw, left upper paw, left lower paw up
{70, 45, 45, 110, 110, 135, 135, 70, 400},//Right upper paw, left upper paw and left lower paw down
{70, 90, 90, 110, 110, 90, 90, 70, 400},//Standby mode
}; // executa torção helicoidal com movimentação de patas
//A function to set advanced steps
void dance3() { // executa torção helicoidal com movimentação de patas
for (int i = 0; i <= 9; i = i + 1) { // executa torção helicoidal com movimentação de patas
servo_14.write(array11[i][0]); // executa torção helicoidal com movimentação de patas
servo_12.write(array11[i][1]); // executa torção helicoidal com movimentação de patas
servo_13.write(array11[i][2]); // executa torção helicoidal com movimentação de patas
servo_15.write(array11[i][3]); // executa torção helicoidal com movimentação de patas
servo_16.write(array11[i][4]); // executa torção helicoidal com movimentação de patas
servo_5.write(array11[i][5]); // executa torção helicoidal com movimentação de patas
servo_4.write(array11[i][6]); // executa torção helicoidal com movimentação de patas
servo_2.write(array11[i][7]); // executa torção helicoidal com movimentação de patas
delay(array11[i][8]); // executa torção helicoidal com movimentação de patas
} // executa torção helicoidal com movimentação de patas
} // executa torção helicoidal com movimentação de patas
void setup() { // executa torção helicoidal com movimentação de patas
servo_14.attach(14); // executa torção helicoidal com movimentação de patas
servo_12.attach(12); // executa torção helicoidal com movimentação de patas
servo_13.attach(13); // executa torção helicoidal com movimentação de patas
servo_15.attach(15); // executa torção helicoidal com movimentação de patas
servo_16.attach(16); // executa torção helicoidal com movimentação de patas
servo_5.attach(5); // executa torção helicoidal com movimentação de patas
servo_4.attach(4); // executa torção helicoidal com movimentação de patas
servo_2.attach(2); // executa torção helicoidal com movimentação de patas
} // executa torção helicoidal com movimentação de patas
//Run the advanced step program
void loop() { // executa torção helicoidal com movimentação de patas
dance3(); // executa torção helicoidal com movimentação de patas
delay(1000); // executa torção helicoidal com movimentação de patas
} // executa torção helicoidal com movimentação de patas
Experimento 7.4: Coreografia Encadeada Completa (expand)
O sketch a seguir consolida as três danças em uma apresentação contínua:
#include <Servo.h> // encadeia ciclo coreográfico com repetição automática
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
String item;//Because serial data is in string format, the variables are also in string format
//Create the standby array
int array1[2][9] = { // encadeia ciclo coreográfico com repetição automática
//G14 G12 G13 G15 G16 G5 G4 G2 MS
{90, 90, 90, 90, 90, 90, 90, 90, 500},//Center point position
{70, 90, 90, 110, 110, 90, 90, 70, 500},//Standby mode
}; // encadeia ciclo coreográfico com repetição automática
//dance1
int array9[10][9] = { // encadeia ciclo coreográfico com repetição automática
{90, 90, 90, 90, 90, 90, 90, 90, 400}, // encadeia ciclo coreográfico com repetição automática
{50, 90, 90, 90, 90, 90, 90, 90, 400}, // encadeia ciclo coreográfico com repetição automática
{90, 90, 90, 130, 90, 90, 90, 90, 400}, // encadeia ciclo coreográfico com repetição automática
{90, 90, 90, 90, 90, 90, 90, 50, 400}, // encadeia ciclo coreográfico com repetição automática
{90, 90, 90, 90, 130, 90, 90, 90, 400}, // encadeia ciclo coreográfico com repetição automática
{50, 90, 90, 90, 90, 90, 90, 90, 400}, // encadeia ciclo coreográfico com repetição automática
{90, 90, 90, 130, 90, 90, 90, 90, 400}, // encadeia ciclo coreográfico com repetição automática
{90, 90, 90, 90, 90, 90, 90, 50, 400}, // encadeia ciclo coreográfico com repetição automática
{90, 90, 90, 90, 130, 90, 90, 90, 400}, // encadeia ciclo coreográfico com repetição automática
{90, 90, 90, 90, 90, 90, 90, 90, 400}, // encadeia ciclo coreográfico com repetição automática
}; // encadeia ciclo coreográfico com repetição automática
//dance2
int array10[9][9] = { // encadeia ciclo coreográfico com repetição automática
{70, 45, 135, 110, 110, 135, 45, 70, 400}, // encadeia ciclo coreográfico com repetição automática
{115, 45, 135, 65, 110, 135, 45, 70, 400}, // encadeia ciclo coreográfico com repetição automática
{70, 45, 135, 110, 65, 135, 45, 115, 400}, // encadeia ciclo coreográfico com repetição automática
{115, 45, 135, 65, 110, 135, 45, 70, 400}, // encadeia ciclo coreográfico com repetição automática
{70, 45, 135, 110, 65, 135, 45, 115, 400}, // encadeia ciclo coreográfico com repetição automática
{115, 45, 135, 65, 110, 135, 45, 70, 400}, // encadeia ciclo coreográfico com repetição automática
{70, 45, 135, 110, 65, 135, 45, 115, 400}, // encadeia ciclo coreográfico com repetição automática
{115, 45, 135, 65, 110, 135, 45, 70, 400}, // encadeia ciclo coreográfico com repetição automática
{75, 45, 135, 105, 110, 135, 45, 70, 400}, // encadeia ciclo coreográfico com repetição automática
}; // encadeia ciclo coreográfico com repetição automática
//dance3
int array11[10][9] = { // encadeia ciclo coreográfico com repetição automática
{70, 45, 45, 110, 110, 135, 135, 70, 400}, // encadeia ciclo coreográfico com repetição automática
{90, 45, 45, 60, 90, 135, 135, 70, 400}, // encadeia ciclo coreográfico com repetição automática
{70, 45, 45, 110, 110, 135, 135, 70, 400}, // encadeia ciclo coreográfico com repetição automática
{90, 45, 45, 110, 90, 135, 135, 120, 400}, // encadeia ciclo coreográfico com repetição automática
{70, 45, 45, 110, 110, 135, 135, 70, 400}, // encadeia ciclo coreográfico com repetição automática
{90, 45, 45, 60, 90, 135, 135, 70, 400}, // encadeia ciclo coreográfico com repetição automática
{70, 45, 45, 110, 110, 135, 135, 70, 400}, // encadeia ciclo coreográfico com repetição automática
{90, 45, 45, 110, 90, 135, 135, 120, 400}, // encadeia ciclo coreográfico com repetição automática
{70, 45, 45, 110, 110, 135, 135, 70, 400}, // encadeia ciclo coreográfico com repetição automática
{70, 90, 90, 110, 110, 90, 90, 70, 400}, // encadeia ciclo coreográfico com repetição automática
}; // encadeia ciclo coreográfico com repetição automática
//A function that sets the standby state
void standby() { // encadeia ciclo coreográfico com repetição automática
for (int i = 0; i <= 1; i = i + 1) { //There are two sets of arrays that need to be traversed twice
servo_14.write(array1[i][0]); //The servo executes row i and column 1
servo_12.write(array1[i][1]); //The servo executes row i and column 2
servo_13.write(array1[i][2]); //The servo executes row i and column 3
servo_15.write(array1[i][3]); //The servo executes row i and column 4
servo_16.write(array1[i][4]); //The servo executes row i and column 5
servo_5.write(array1[i][5]); //The servo executes row i and column 6
servo_4.write(array1[i][6]); //The servo executes row i and column 7
servo_2.write(array1[i][7]); //The servo executes row i and column 8
delay(array1[i][8]); //Row i, column 9, execution delay time
} // encadeia ciclo coreográfico com repetição automática
} // encadeia ciclo coreográfico com repetição automática
void dance1() { // encadeia ciclo coreográfico com repetição automática
for (int i = 0; i <= 9; i = i + 1) { // encadeia ciclo coreográfico com repetição automática
servo_14.write(array9[i][0]); // encadeia ciclo coreográfico com repetição automática
servo_12.write(array9[i][1]); // encadeia ciclo coreográfico com repetição automática
servo_13.write(array9[i][2]); // encadeia ciclo coreográfico com repetição automática
servo_15.write(array9[i][3]); // encadeia ciclo coreográfico com repetição automática
servo_16.write(array9[i][4]); // encadeia ciclo coreográfico com repetição automática
servo_5.write(array9[i][5]); // encadeia ciclo coreográfico com repetição automática
servo_4.write(array9[i][6]); // encadeia ciclo coreográfico com repetição automática
servo_2.write(array9[i][7]); // encadeia ciclo coreográfico com repetição automática
delay(array9[i][8]); // encadeia ciclo coreográfico com repetição automática
} // encadeia ciclo coreográfico com repetição automática
} // encadeia ciclo coreográfico com repetição automática
void dance2() { // encadeia ciclo coreográfico com repetição automática
for (int i = 0; i <= 8; i = i + 1) { // encadeia ciclo coreográfico com repetição automática
servo_14.write(array10[i][0]); // encadeia ciclo coreográfico com repetição automática
servo_12.write(array10[i][1]); // encadeia ciclo coreográfico com repetição automática
servo_13.write(array10[i][2]); // encadeia ciclo coreográfico com repetição automática
servo_15.write(array10[i][3]); // encadeia ciclo coreográfico com repetição automática
servo_16.write(array10[i][4]); // encadeia ciclo coreográfico com repetição automática
servo_5.write(array10[i][5]); // encadeia ciclo coreográfico com repetição automática
servo_4.write(array10[i][6]); // encadeia ciclo coreográfico com repetição automática
servo_2.write(array10[i][7]); // encadeia ciclo coreográfico com repetição automática
delay(array10[i][8]); // encadeia ciclo coreográfico com repetição automática
} // encadeia ciclo coreográfico com repetição automática
} // encadeia ciclo coreográfico com repetição automática
void dance3() { // encadeia ciclo coreográfico com repetição automática
for (int i = 0; i <= 9; i = i + 1) { // encadeia ciclo coreográfico com repetição automática
servo_14.write(array11[i][0]); // encadeia ciclo coreográfico com repetição automática
servo_12.write(array11[i][1]); // encadeia ciclo coreográfico com repetição automática
servo_13.write(array11[i][2]); // encadeia ciclo coreográfico com repetição automática
servo_15.write(array11[i][3]); // encadeia ciclo coreográfico com repetição automática
servo_16.write(array11[i][4]); // encadeia ciclo coreográfico com repetição automática
servo_5.write(array11[i][5]); // encadeia ciclo coreográfico com repetição automática
servo_4.write(array11[i][6]); // encadeia ciclo coreográfico com repetição automática
servo_2.write(array11[i][7]); // encadeia ciclo coreográfico com repetição automática
delay(array11[i][8]); // encadeia ciclo coreográfico com repetição automática
} // encadeia ciclo coreográfico com repetição automática
} // encadeia ciclo coreográfico com repetição automática
void setup() { // encadeia ciclo coreográfico com repetição automática
servo_14.attach(14); // encadeia ciclo coreográfico com repetição automática
servo_12.attach(12); // encadeia ciclo coreográfico com repetição automática
servo_13.attach(13); // encadeia ciclo coreográfico com repetição automática
servo_15.attach(15); // encadeia ciclo coreográfico com repetição automática
servo_16.attach(16); // encadeia ciclo coreográfico com repetição automática
servo_5.attach(5); // encadeia ciclo coreográfico com repetição automática
servo_4.attach(4); // encadeia ciclo coreográfico com repetição automática
servo_2.attach(2); // encadeia ciclo coreográfico com repetição automática
standby(); // encadeia ciclo coreográfico com repetição automática
Serial.begin(115200); // encadeia ciclo coreográfico com repetição automática
item = "";//Initialize the variable as an empty string
} // encadeia ciclo coreográfico com repetição automática
// Don't select \r\n in serial port, just select no
void loop() { // Run the serial control dance program
//Determine whether there is data in the serial port
if (Serial.available()) { // encadeia ciclo coreográfico com repetição automática
item = Serial.readString(); //The variable is assigned to the data read by the serial port
Serial.println(item); //The serial port prints out the input data
//According to the input data, the condition is judged and the corresponding function is executed
if (item == "1") { //When 1 is input to the serial port, dance1 is executed
dance1(); // encadeia ciclo coreográfico com repetição automática
} // encadeia ciclo coreográfico com repetição automática
if (item == "2") { //When 2 is input to the serial port, dance2 is executed
dance2(); // encadeia ciclo coreográfico com repetição automática
} // encadeia ciclo coreográfico com repetição automática
if (item == "3") { //When 3 is input to the serial port, dance3 is executed
dance3(); // encadeia ciclo coreográfico com repetição automática
} // encadeia ciclo coreográfico com repetição automática
} // encadeia ciclo coreográfico com repetição automática
} // encadeia ciclo coreográfico com repetição automática
Lição 8 — Controle de WiFi do Robô (ACEBOTT Mobile App)
A última lição integra todas as funções cinemáticas desenvolvidas nas lições anteriores em um firmware completo com conectividade sem fio. O ESP8266 é configurado em modo Ponto de Acesso (SoftAP), gerando uma rede Wi-Fi própria e executando um servidor TCP nativo na porta 100 para recepção e decodificação dos pacotes enviados pelo aplicativo móvel ACEBOTT para Android e iOS.



Arquitetura de Rede e Protocolo Binário de Comunicação
Ao ser ligado, o robô inicializa sua interface de rádio criando a rede Wi-Fi:
- SSID da Rede:
QuadBot-E - Senha WPA2-PSK:
12345678 - Endereço IP Padrão:
192.168.4.1 - Porta do Servidor de Sockets:
100(Protocolo TCP Stream)
Os comandos enviados pelo aplicativo ACEBOTT seguem um protocolo de quadros binários estruturado com cabeçalho de sincronização fixo, tamanho de dados e código de comando:
+--------+--------+---------+--------+-------------+
| Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 |
| 0xFF | 0x55 | DataLen | Mode | CommandByte |
+--------+--------+---------+--------+-------------+
Header Header Tamanho Modo Ação / Função
A tabela abaixo descreve os comandos recebidos pelo servidor TCP:
| Código de Comando | Constante do Pacote | Ação Cinemática Executada | Função Acionada no text.h |
|---|---|---|---|
0x01 | callback_forward_package | Caminhar para a Frente | forward() |
0x02 | callback_back_package | Caminhar para Trás | back() |
0x03 | callback_leftmove_package | Passo Lateral para a Esquerda | leftmove() |
0x04 | callback_rightmove_package | Passo Lateral para a Direita | rightmove() |
0x05 | callback_turnleft_package | Girar para a Esquerda | turnleft() |
0x06 | callback_turnright_package | Girar para a Direita | turnright() |
0x07 | callback_standby_package | Postura de Espera (Standby) | standby() |
0x08 | callback_sleep_package | Modo de Repouso Baixo (Sleep) | sleep() |
0x09 | callback_lie_package | Deitar sobre o Chassi (Lie) | lie() |
0x0A | callback_hello_package | Acenar com a Pata Dianteira | hello() |
0x0B | callback_pushup_package | Exercício de Flexão (Pushup) | pushup() |
0x0C | callback_fighting_package | Postura de Batalha (Fighting) | fighting() |
0x0D | callback_dance1_package | Executar Dança 1 | dance1() |
0x0E | callback_dance2_package | Executar Dança 2 | dance2() |
0x0F | callback_dance3_package | Executar Dança 3 | dance3() |
Código Completo do Firmware Mestre (8.1app_control.ino)
O código abaixo integra o servidor Wi-Fi, o parser do protocolo binário e o acionamento de todas as ações de movimentação:
#include <ESP8266WiFi.h> // processa conexão WiFi e comandos TCP do aplicativo
#include <ESP8266WebServer.h> // processa conexão WiFi e comandos TCP do aplicativo
#include "text.h" // processa conexão WiFi e comandos TCP do aplicativo
const char* ssid = "QuadBot-E";//Wi-Fi name of the quadruped robot
const char* password = "12345678";//Wi-Fi password for the quadruped robot
WiFiServer server(100);//Create a Wi-Fi server object with port 100
WiFiClient client;//Create a Wi-Fi client object
String sendBuff;//Send buffer
byte RX_package[17] = {0};//An array of incoming packets
byte callback_forward_package[5] = {0xff,0x55,0x02,0x01,0x01};// Forward command packet
byte callback_back_package[5] = {0xff,0x55,0x02,0x01,0x02};// Back command packet
byte callback_leftmove_package[5] = {0xff,0x55,0x02,0x01,0x03};// Move command packet left
byte callback_rightmove_package[5] = {0xff,0x55,0x02,0x01,0x04};// Right shift command packet
byte callback_turnleft_package[5] = {0xff,0x55,0x02,0x01,0x05};// Left turn command packet
byte callback_turnright_package[5] = {0xff,0x55,0x02,0x01,0x06};// Right turn command packet
byte callback_standby_package[5] = {0xff,0x55,0x02,0x01,0x07};// standby command packet
byte callback_sleep_package[5] = {0xff,0x55,0x02,0x01,0x08};// command packet
byte callback_lie_package[5] = {0xff,0x55,0x02,0x01,0x09};// command packet
byte callback_hello_package[5] = {0xff,0x55,0x02,0x01,0x0a};// command packet
byte callback_pushup_package[5] = {0xff,0x55,0x02,0x01,0x0b};// command packet
byte callback_fighting_package[5] = {0xff,0x55,0x02,0x01,0x0c};// command packet
byte callback_dance1_package[5] = {0xff,0x55,0x02,0x01,0x0d};// command packet
byte callback_dance2_package[5] = {0xff,0x55,0x02,0x01,0x0e};// command packet
byte callback_dance3_package[5] = {0xff,0x55,0x02,0x01,0x0f};// command packet
byte Serial_package[5] = {0};// Serial packets
byte dataLen, index_a = 0;// Data length and index variable
char buffer[52];// Buffer
unsigned char prevc=0;// previous character
bool isStart = false;// Flag if receive has started
bool ED_client = true;// Flag if the client is connected
bool WA_en = false;// Mark if WA is enabled
bool st = false; // processa conexão WiFi e comandos TCP do aplicativo
#define CMD_RUN 1 // Forward command identity
#define CMD_daiji 3 // Flag for standby command
#define CMD_jiaozun 4 // Identity of the calibration command
#define CMD_suijiao 5 // Identifier for the sleep command
#define CMD_padi 6 // The flag of the planking command
#define CMD_dazaohu 7 // Flag for the say hello command
#define CMD_fuwoceng 8 // The flag for the push up command
#define CMD_zandou 9 // Battle command identifier
#define CMD_dance1 10 //The identity of the Dance 1 command
#define CMD_dance2 11 //The identity of the Dance 2 command
#define CMD_dance3 12 //The identity of the Dance 3 command
void setup() // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
Serial.setTimeout(10); // Set the serial timeout to 10ms
Serial.begin(115200); // Initiate serial communication with baud rate of 115200
WiFi.mode(WIFI_AP);// Set Wi-Fi mode to access point mode
WiFi.softAP(ssid,password,5);//Create a Wi-Fi access point, specify the network name and password, and set the channel to 5
server.begin();// Start the Wi-Fi server
delay(100); // processa conexão WiFi e comandos TCP do aplicativo
servo_14.attach(14, SERVOMIN, SERVOMAX);// Connect the servo to pin 14
servo_12.attach(12, SERVOMIN, SERVOMAX);// Connect the servo to pin 12
servo_13.attach(13, SERVOMIN, SERVOMAX);// Connect the servo to pin 13
servo_15.attach(15, SERVOMIN, SERVOMAX);// Connect the servo to pin 15
servo_16.attach(16, SERVOMIN, SERVOMAX);// Connect the servo to pin 16
servo_5.attach(5, SERVOMIN, SERVOMAX);// Connect the servo to pin 5
servo_4.attach(4, SERVOMIN, SERVOMAX);// Connect the servo to pin 4
servo_2.attach(2, SERVOMIN, SERVOMAX);// Connect the servo to pin 2
Servo_PROGRAM_Zero();// Reset the servo program to zero
} // processa conexão WiFi e comandos TCP do aplicativo
unsigned char readBuffer(int index_r)// Read the characters in the buffer with index index_r and return
{ // processa conexão WiFi e comandos TCP do aplicativo
return buffer[index_r]; // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
void writeBuffer(int index_w,unsigned char c) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
buffer[index_w]=c;// Write the character c to the buffer at index index_w position
} // processa conexão WiFi e comandos TCP do aplicativo
// Pattern
void runModule(int device) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
switch(device) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
case 0x0C: // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
int val = readBuffer(12); // processa conexão WiFi e comandos TCP do aplicativo
switch (val) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
case 0x01: // processa conexão WiFi e comandos TCP do aplicativo
forward();//Serial.println("ok");
//Serial.write(callback_forward_package,5);
client.write(callback_forward_package,5); // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case 0x02: // processa conexão WiFi e comandos TCP do aplicativo
back(); // processa conexão WiFi e comandos TCP do aplicativo
client.write(callback_back_package,5); // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case 0x03: // processa conexão WiFi e comandos TCP do aplicativo
leftmove(); // processa conexão WiFi e comandos TCP do aplicativo
client.write(callback_leftmove_package,5); // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case 0x04: // processa conexão WiFi e comandos TCP do aplicativo
rightmove(); // processa conexão WiFi e comandos TCP do aplicativo
client.write(callback_rightmove_package,5); // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case 0x05: // processa conexão WiFi e comandos TCP do aplicativo
turnleft(); // processa conexão WiFi e comandos TCP do aplicativo
client.write(callback_turnleft_package,5); // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case 0x06: // processa conexão WiFi e comandos TCP do aplicativo
turnright(); // processa conexão WiFi e comandos TCP do aplicativo
client.write(callback_turnright_package,5); // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
default: // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
}break; // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
void parseData() // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
isStart = false; // processa conexão WiFi e comandos TCP do aplicativo
int action = readBuffer(9); // processa conexão WiFi e comandos TCP do aplicativo
int device = readBuffer(10); // processa conexão WiFi e comandos TCP do aplicativo
switch(action) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
case CMD_RUN: // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
runModule(device); // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case CMD_daiji: // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
standby();//Serial.println("ok");
client.write(callback_standby_package,5); // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case CMD_jiaozun: // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
//zero();
} // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case CMD_suijiao: // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
sleep(); // processa conexão WiFi e comandos TCP do aplicativo
client.write(callback_sleep_package,5); // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case CMD_padi: // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
lie(); // processa conexão WiFi e comandos TCP do aplicativo
client.write(callback_lie_package,5); // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case CMD_dazaohu: // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
hello(); // processa conexão WiFi e comandos TCP do aplicativo
client.write(callback_hello_package,5); // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case CMD_fuwoceng: // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
pushup(); // processa conexão WiFi e comandos TCP do aplicativo
client.write(callback_pushup_package,5); // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case CMD_zandou: // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
fighting(); // processa conexão WiFi e comandos TCP do aplicativo
client.write(callback_fighting_package,5); // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case CMD_dance1: // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
dance1(); // processa conexão WiFi e comandos TCP do aplicativo
client.write(callback_dance1_package,5); // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case CMD_dance2: // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
dance2(); // processa conexão WiFi e comandos TCP do aplicativo
client.write(callback_dance2_package,5); // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
case CMD_dance3: // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
dance3(); // processa conexão WiFi e comandos TCP do aplicativo
client.write(callback_dance3_package,5); // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
void loop() // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
client = server.available(); // processa conexão WiFi e comandos TCP do aplicativo
if (client) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
WA_en = true; // processa conexão WiFi e comandos TCP do aplicativo
ED_client = true; // processa conexão WiFi e comandos TCP do aplicativo
Serial.println("[Client connected]"); // processa conexão WiFi e comandos TCP do aplicativo
unsigned long previousMillis = millis(); // processa conexão WiFi e comandos TCP do aplicativo
const unsigned long timeoutDuration = 3000; // processa conexão WiFi e comandos TCP do aplicativo
while (client.connected()) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
if ((millis() - previousMillis) > timeoutDuration && client.available() == 0 && st==true) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
break; // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
if (client.available()) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
previousMillis = millis(); // processa conexão WiFi e comandos TCP do aplicativo
unsigned char c = client.read()&0xff; // processa conexão WiFi e comandos TCP do aplicativo
Serial.write(c); // processa conexão WiFi e comandos TCP do aplicativo
st = false; // processa conexão WiFi e comandos TCP do aplicativo
if (c == 200) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
st = true; // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
if(c==0x55&&isStart==false) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
if(prevc==0xff) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
index_a=1; // processa conexão WiFi e comandos TCP do aplicativo
isStart = true; // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
else // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
prevc = c; // processa conexão WiFi e comandos TCP do aplicativo
if(isStart) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
if(index_a==2) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
dataLen = c; // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
else if(index_a>2) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
dataLen--; // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
writeBuffer(index_a,c); // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
index_a++; // processa conexão WiFi e comandos TCP do aplicativo
if(index_a>120) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
index_a=0; // processa conexão WiFi e comandos TCP do aplicativo
isStart=false; // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
if(isStart&&dataLen==0&&index_a>3) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
isStart = false; // processa conexão WiFi e comandos TCP do aplicativo
parseData(); // processa conexão WiFi e comandos TCP do aplicativo
index_a=0; // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
if (Serial.available()) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
char c = Serial.read(); // processa conexão WiFi e comandos TCP do aplicativo
sendBuff += c; // processa conexão WiFi e comandos TCP do aplicativo
client.print(sendBuff); // processa conexão WiFi e comandos TCP do aplicativo
Serial.print(sendBuff); // processa conexão WiFi e comandos TCP do aplicativo
sendBuff = ""; // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
static unsigned long Test_time = 0; // processa conexão WiFi e comandos TCP do aplicativo
if (millis() - Test_time > 1000) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
Test_time = millis(); // processa conexão WiFi e comandos TCP do aplicativo
if (0 == (WiFi.softAPgetStationNum())) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
//Serial.write(Stop,17);
break; // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
//Serial.write(Stop,17);
client.stop(); // processa conexão WiFi e comandos TCP do aplicativo
Servo_PROGRAM_Zero(); // processa conexão WiFi e comandos TCP do aplicativo
Serial.println("[Client disconnected]"); // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
else // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
if (ED_client == true) // processa conexão WiFi e comandos TCP do aplicativo
{ // processa conexão WiFi e comandos TCP do aplicativo
ED_client = false; // processa conexão WiFi e comandos TCP do aplicativo
//Serial.write(Stop,17);
} // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
} // processa conexão WiFi e comandos TCP do aplicativo
Cabeçalho de Definições Cinemáticas (text.h)
O arquivo auxiliar text.h armazena todas as tabelas de passos e funções cinemáticas de interpolação angular invocadas pelo sketch principal:
#include <Servo.h> // matriz de ângulos e rotina de acionamento cinemático
Servo servo_14;//Upper right [paw]
Servo servo_12;//Upper right [arm]
Servo servo_13;//Lower right [arm]
Servo servo_15;//Lower right [paw]
Servo servo_16;//Upper left [paw]
Servo servo_5;//Upper left [arm]
Servo servo_4;//Lower left [arm]
Servo servo_2;//Lower left [paw]
String item;//Because serial data is in string format, the variables are also in string format
const int PWMRES_Min = 1; // PWM Resolution 1
const int PWMRES_Max = 180; // PWM Resolution 180
const int ALLMATRIX = 9; // GPIO14 + GPIO12 + GPIO13 + GPIO15 + GPIO16 + GPIO5 + GPIO4 + GPIO2 + Run Time
const int ALLSERVOS = 8; // GPIO14 + GPIO12 + GPIO13 + GPIO15 + GPIO16 + GPIO5 + GPIO4 + GPIO2
const int SERVOMIN = 400; // 400
const int SERVOMAX = 2400; // 2400
// Backup servo value
int Running_Servo_POS [ALLMATRIX]; // matriz de ângulos e rotina de acionamento cinemático
// Servo delay base time
int BASEDELAYTIME = 10; // 10 ms
// ----------------------------- G14, G12, G13, G15, G16, G5, G4, G2, ms
const int Servo_Act_0 [ ] PROGMEM = { 90, 90, 90, 90, 90, 90, 90, 90, 500 }; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Act_1 [ ] PROGMEM = { 60, 90, 90, 120, 120, 90, 90, 60, 500 }; // matriz de ângulos e rotina de acionamento cinemático
// Standby 待机
const int Servo_Prg_1_Step = 2; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_1 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
// { 90, 90, 90, 90, 90, 90, 90, 90, 500 }, // servo center point
// { 70, 90, 90, 110, 110, 90, 90, 70, 500 }, // standby
{ 90, 90, 90, 90, 90, 90, 90, 90, 500 }, // servo center point
{ 60, 90, 90, 120, 120, 90, 90, 60, 500 }, // standby
}; // matriz de ângulos e rotina de acionamento cinemático
// Forward 前进
const int Servo_Prg_2_Step = 11; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_2 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
/*{ 70, 90, 90, 110, 110, 90, 90, 70, 200 }, // standby
{ 90, 90, 90, 110, 110, 90, 45, 90, 200 }, // leg1,4 up; leg4 fw
{ 70, 90, 90, 110, 110, 90, 45, 70, 200 }, // leg1,4 dn
{ 70, 90, 90, 90, 90, 90, 45, 70, 200 }, // leg2,3 up
{ 70, 45-6, 135+6, 90, 90, 90, 90, 70, 200 }, // leg1,4 bk; leg2 fw
{ 70, 45-6, 135+6, 110, 110, 90, 90, 70, 200 }, // leg2,3 dn
{ 90, 90, 135+6, 110, 110, 90, 90, 90, 200 }, // leg1,4 up; leg1 fw
{ 90, 90, 90, 110, 110, 135, 90, 90, 200 }, // leg2,3 bk
{ 70, 90, 90, 110, 110, 135, 90, 70, 200 }, // leg1,4 dn
{ 70, 90, 90, 110, 90, 135, 90, 70, 200 }, // leg3 up
{ 70, 90, 90, 110, 110, 90, 90, 70, 200 }, // leg3 fw dn*/
{70, 90, 90, 110, 110, 90, 90, 70, 200},// standby
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 120, 90, 110, 110, 90, 60, 90, 200},//Right upper arm and left lower arm forward
{70, 120, 90, 110, 110, 90, 60, 70, 200},//Right upper paw and left lower paw drop
{70, 120, 90, 90, 90, 90, 60, 70, 200},//The left upper paw and right lower paw are raised
{70, 90, 90, 90, 90, 90, 90, 70, 200},//Right upper arm and left lower arm back
{70, 90, 120,90, 90, 60, 90, 70, 200},//Left upper arm and right lower arm forward
{70, 90, 120,110, 110, 60, 90, 70, 200},//Left upper paw and right lower paw drop
{90, 90, 120,110, 110, 60, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 90, 90, 110, 110, 90, 90, 90, 200},//The upper left arm and lower right arm back
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Right upper paw and left lower paw drop
}; // matriz de ângulos e rotina de acionamento cinemático
// Backward 后退
const int Servo_Prg_3_Step = 11; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_3 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
/*{ 70, 90, 90, 110, 110, 90, 90, 70, 200 }, // standby
{ 90, 45, 90, 110, 110, 90, 90, 90, 200 }, // leg4,1 up; leg1 fw
{ 70, 45, 90, 110, 110, 90, 90, 70, 200 }, // leg4,1 dn
{ 70, 45, 90, 90, 90, 90, 90, 70, 200 }, // leg3,2 up
{ 70, 90, 90, 90, 90, 135, 45, 70, 200 }, // leg4,1 bk; leg3 fw
{ 70, 90, 90, 110, 110, 135, 45, 70, 200 }, // leg3,2 dn
{ 90, 90, 90, 110, 110, 135, 90, 90, 200 }, // leg4,1 up; leg4 fw
{ 90, 90, 135, 110, 110, 90, 90, 90, 200 }, // leg3,1 bk
{ 70, 90, 135, 110, 110, 90, 90, 70, 200 }, // leg4,1 dn
{ 70, 90, 135, 90, 110, 90, 90, 70, 200 }, // leg2 up
{ 70, 90, 90, 110, 110, 90, 90, 70, 200 }, // leg2 fw dn*/
{70, 90, 90, 110, 110, 90, 90, 70, 200},//standby
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 60, 90, 110, 110, 90, 120,90, 200},//Right upper arm and left lower arm back
{70, 60, 90, 110, 110, 90, 120,70, 200},//Right upper paw and left lower paw drop
{70, 60, 90, 90, 90, 90, 120,70, 200},//The left upper paw and right lower paw are raised
{70, 90, 90, 90, 90, 90, 90, 70, 200},//Right upper arm and left lower arm forward
{70, 90, 60, 90, 90, 120,90, 70, 200},//The upper left arm and lower right arm back
{70, 90, 60,110, 110, 120,90, 70, 200},//Left upper paw and right lower paw drop
{90, 90, 60,110, 110, 120,90, 90, 200},//Right upper paw and left lower paw are raised
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Left upper arm and right lower arm forward
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Right upper paw and left lower paw drop
}; // matriz de ângulos e rotina de acionamento cinemático
// Left shift 左移
const int Servo_Prg_4_Step = 11; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_4 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
/*{ 70, 90, 90, 110, 110, 90, 90, 70, 200 }, // standby
{ 70, 90, 45, 90, 90, 90, 90, 70, 200 }, // leg3,2 up; leg2 fw
{ 70, 90, 45, 110, 110, 90, 90, 70, 200 }, // leg3,2 dn
{ 90, 90, 45, 110, 110, 90, 90, 90, 200 }, // leg1,4 up
{ 90, 135, 90, 110, 110, 45, 90, 90, 200 }, // leg3,2 bk; leg1 fw
{ 70, 135, 90, 110, 110, 45, 90, 70, 200 }, // leg1,4 dn
{ 70, 135, 90, 90, 90, 90, 90, 70, 200 }, // leg3,2 up; leg3 fw
{ 70, 90, 90, 90, 90, 90, 135, 70, 200 }, // leg1,4 bk
{ 70, 90, 90, 110, 110, 90, 135, 70, 200 }, // leg3,2 dn
{ 70, 90, 90, 110, 110, 90, 135, 90, 200 }, // leg4 up
{ 70, 90, 90, 110, 110, 90, 90, 70, 200 }, // leg4 fw dn*/
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Standby mode
{70, 90, 90, 90, 90, 90, 90, 70, 200},//The left upper paw and right lower paw are raised
{70, 90, 60, 90, 90, 120,90, 70, 200},//Left upper paw and right lower paw drop
{70, 90, 60, 110, 110, 120,90, 70, 200},//Left upper paw and right lower paw drop
{90, 90, 60, 110, 110, 120,90, 90, 200},//Right upper paw and left lower paw are raised
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Left upper arm and right lower arm forward
{90, 120,90, 110, 110, 90, 60, 90, 200},//Right upper arm and left lower arm forward
{70, 120,90, 110, 110, 90, 60, 70, 200},//Right upper paw and left lower paw drop
{70, 120,90, 90, 90, 90, 60, 70, 200},//The left upper paw and right lower paw are raised
{70, 90, 90, 90, 90, 90, 90, 70, 200},//Right upper arm and left lower arm back
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Left upper paw and right lower paw drop
}; // matriz de ângulos e rotina de acionamento cinemático
// Right shift 右移
const int Servo_Prg_5_Step = 11; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_5 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
/*{ 70, 90, 90, 110, 110, 90, 90, 70, 200 }, // standby
{ 70, 90, 90, 90, 90, 45, 90, 70, 200 }, // leg2,3 up; leg3 fw
{ 70, 90, 90, 110, 110, 45, 90, 70, 200 }, // leg2,3 dn
{ 90, 90, 90, 110, 110, 45, 90, 90, 200 }, // leg4,1 up
{ 90, 90, 45, 110, 110, 90, 135, 90, 200 }, // leg2,3 bk; leg4 fw
{ 70, 90, 45, 110, 110, 90, 135, 70, 200 }, // leg4,1 dn
{ 70, 90, 90, 90, 90, 90, 135, 70, 200 }, // leg2,3 up; leg2 fw
{ 70, 135, 90, 90, 90, 90, 90, 70, 200 }, // leg4,1 bk
{ 70, 135, 90, 110, 110, 90, 90, 70, 200 }, // leg2,3 dn
{ 90, 135, 90, 110, 110, 90, 90, 70, 200 }, // leg1 up
{ 70, 90, 90, 110, 110, 90, 90, 70, 200 }, // leg1 fw dn*/
{70, 90, 90, 110, 110, 90, 90, 70, 200},//standby
{90, 90, 90, 110, 110, 90, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 60, 90, 110, 110, 90, 120,90, 200},//Right upper arm and left lower arm back
{70, 60, 90, 110, 110, 90, 120,70, 200},//Right upper paw and left lower paw drop
{70, 60, 90, 90, 90, 90, 120,70, 200},//The left upper paw and right lower paw are raised
{70, 90, 90, 90, 90, 90, 90, 70, 200},//Right upper arm and left lower arm forward
{70, 90, 120,90, 90, 60, 90, 70, 200},//Left upper arm and right lower arm forward
{70, 90, 120,110, 110, 60, 90, 70, 200},//Left upper paw and right lower paw drop
{90, 90, 120,110, 110, 60, 90, 90, 200},//Right upper paw and left lower paw are raised
{90, 90, 90, 110, 110, 90, 90, 90, 200},//The upper left arm and lower right arm back
{70, 90, 90, 110, 110, 90, 90, 70, 200},//Right upper paw and left lower paw drop
}; // matriz de ângulos e rotina de acionamento cinemático
// Turn left 左转
const int Servo_Prg_6_Step = 8; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_6 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
{ 70, 90, 90, 110, 110, 90, 90, 70, 200 }, // standby
{ 90, 90, 90, 110, 110, 90, 90, 90, 200 }, // leg1,4 up
{ 90, 135, 90, 110, 110, 90, 135, 90, 200 }, // leg1,4 turn
{ 70, 135, 90, 110, 110, 90, 135, 70, 200 }, // leg1,4 dn
{ 70, 135, 90, 90, 90, 90, 135, 70, 200 }, // leg2,3 up
{ 70, 135, 135, 90, 90, 135, 135, 70, 200 }, // leg2,3 turn
{ 70, 135, 135, 110, 110, 135, 135, 70, 200 }, // leg2,3 dn
{ 70, 90, 90, 110, 110, 90, 90, 70, 200 }, // leg1,2,3,4 turn
}; // matriz de ângulos e rotina de acionamento cinemático
// Turn right 右转
const int Servo_Prg_7_Step = 8; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_7 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
{ 70, 90, 90, 110, 110, 90, 90, 70, 200 }, // standby
{ 70, 90, 90, 90, 90, 90, 90, 70, 200 }, // leg2,3 up
{ 70, 90, 45, 90, 90, 45, 90, 70, 200 }, // leg2,3 turn
{ 70, 90, 45, 110, 110, 45, 90, 70, 200 }, // leg2,3 dn
{ 90, 90, 45, 110, 110, 45, 90, 90, 200 }, // leg1,4 up
{ 90, 45, 45, 110, 110, 45, 45, 90, 200 }, // leg1,4 turn
{ 70, 45, 45, 110, 110, 45, 45, 70, 200 }, // leg1,4 dn
{ 70, 90, 90, 110, 110, 90, 90, 70, 200 }, // leg1,2,3,4 turn
}; // matriz de ângulos e rotina de acionamento cinemático
// Lie 趴地
const int Servo_Prg_8_Step = 1; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_8 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
{ 110, 90, 90, 70, 70, 90, 90, 110, 500 }, // leg1,4 up
}; // matriz de ângulos e rotina de acionamento cinemático
// Say Hi 打招呼
const int Servo_Prg_9_Step = 7; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_9 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
// { 70, 90, 90, 90, 90, 90, 90, 90, 400}, // leg2,3,4 dn
// { 170, 90, 90, 90, 90, 90, 90, 90, 400}, // leg1 up
// { 170, 130, 90, 90, 90, 90, 90, 90, 400}, // leg1 left
// { 170, 50, 90, 90, 90, 90, 90, 90, 400}, // leg1 right
// { 170, 130, 90, 90, 90, 90, 90, 90, 400}, // leg1 left
// { 170, 90, 90, 90, 90, 90, 90, 90, 400}, // leg1 right
// { 70, 90, 90, 90, 90, 90, 90, 90, 400}, // leg1 dn
{ 70, 90, 135, 90, 90, 90, 90, 90, 400}, // leg2,3,4 dn
{ 170, 90, 135, 90, 90, 90, 90, 90, 400}, // leg1 up
{ 170, 130, 135, 90, 90, 90, 90, 90, 400}, // leg1 left
{ 170, 50, 135, 90, 90, 90, 90, 90, 400}, // leg1 right
{ 170, 130, 135, 90, 90, 90, 90, 90, 400}, // leg1 left
{ 170, 90, 135, 90, 90, 90, 90, 90, 400}, // leg1 right
{ 70, 90, 135, 90, 90, 90, 90, 90, 400}, // leg1 dn
}; // matriz de ângulos e rotina de acionamento cinemático
// Fighting 战斗姿态
const int Servo_Prg_10_Step = 11; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_10 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
{ 120, 90, 90, 110, 60, 90, 90, 70, 500 }, // leg1, 2 down
{ 120, 70, 70, 110, 60, 70, 70, 70, 500 }, // body turn left
{ 120, 110, 110, 110, 60, 110, 110, 70, 500 }, // body turn right
{ 120, 70, 70, 110, 60, 70, 70, 70, 500 }, // body turn left
{ 120, 110, 110, 110, 60, 110, 110, 70, 500 }, // body turn right
{ 70, 90, 90, 70, 110, 90, 90, 110, 500 }, // leg1, 2 up ; leg3, 4 down
{ 70, 70, 70, 70, 110, 70, 70, 110, 500 }, // body turn left
{ 70, 110, 110, 70, 110, 110, 110, 110, 500 }, // body turn right
{ 70, 70, 70, 70, 110, 70, 70, 110, 500 }, // body turn left
{ 70, 110, 110, 70, 110, 110, 110, 110, 500 }, // body turn right
{ 70, 90, 90, 70, 110, 90, 90, 110, 500 } // leg1, 2 up ; leg3, 4 down
}; // matriz de ângulos e rotina de acionamento cinemático
// Push up 俯卧撑
const int Servo_Prg_11_Step = 7; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_11 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
/*{ 70, 90, 90, 110, 110, 90, 90, 70, 500 }, // start
{ 100, 90, 90, 80, 80, 90, 90, 100, 600 }, // down
{ 70, 90, 90, 110, 110, 90, 90, 70, 700 }, // up
{ 100, 90, 90, 80, 80, 90, 90, 100, 800 }, // down
{ 70, 90, 90, 110, 110, 90, 90, 70, 900 }, // up
{ 100, 90, 90, 80, 80, 90, 90, 100, 1500 }, // down
{ 70, 90, 90, 110, 110, 90, 90, 70, 2000 }, // up
{ 135, 90, 90, 45, 45, 90, 90, 135, 200 }, // fast down
{ 70, 90, 90, 45, 60, 90, 90, 135, 800 }, // leg1 up
{ 70, 90, 90, 45, 110, 90, 90, 135, 800 }, // leg2 up
{ 70, 90, 90, 110, 110, 90, 90, 70, 800 } // leg3, leg4 up*/
{70, 90, 90, 110, 110, 90, 90, 70, 100},//时间
{90, 90, 90, 90, 90, 90, 90, 90, 600}, // matriz de ângulos e rotina de acionamento cinemático
{70, 90, 90, 110, 110, 90, 90, 70, 500}, // matriz de ângulos e rotina de acionamento cinemático
{90, 90, 90, 90, 90, 90, 90, 100, 700}, // matriz de ângulos e rotina de acionamento cinemático
{70, 90, 90, 110, 110, 90, 90, 70, 500}, // matriz de ângulos e rotina de acionamento cinemático
{90, 90, 90, 90, 90, 90, 90, 100, 800}, // matriz de ângulos e rotina de acionamento cinemático
{70, 90, 90, 110, 110, 90, 90, 70, 500}, // matriz de ângulos e rotina de acionamento cinemático
}; // matriz de ângulos e rotina de acionamento cinemático
// Sleep 睡眠姿勢
const int Servo_Prg_12_Step = 2; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_12 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
{ 30, 90, 90, 150, 150, 90, 90, 30, 500 }, // leg1,4 dn
{ 30, 45, 135, 150, 150, 135, 45, 30, 500 }, // protect myself
}; // matriz de ângulos e rotina de acionamento cinemático
// 舞步 1
const int Servo_Prg_13_Step = 10; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_13 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
{ 90, 90, 90, 90, 90, 90, 90, 90, 400 }, // leg1,2,3,4 up
{ 50, 90, 90, 90, 90, 90, 90, 90, 400 }, // leg1 dn
{ 90, 90, 90, 130, 90, 90, 90, 90, 400 }, // leg1 up; leg2 dn
{ 90, 90, 90, 90, 90, 90, 90, 50, 400 }, // leg2 up; leg4 dn
{ 90, 90, 90, 90, 130, 90, 90, 90, 400 }, // leg4 up; leg3 dn
{ 50, 90, 90, 90, 90, 90, 90, 90, 400 }, // leg3 up; leg1 dn
{ 90, 90, 90, 130, 90, 90, 90, 90, 400 }, // leg1 up; leg2 dn
{ 90, 90, 90, 90, 90, 90, 90, 50, 400 }, // leg2 up; leg4 dn
{ 90, 90, 90, 90, 130, 90, 90, 90, 400 }, // leg4 up; leg3 dn
{ 90, 90, 90, 90, 90, 90, 90, 90, 400 }, // leg3 up
}; // matriz de ângulos e rotina de acionamento cinemático
// 舞步 2
const int Servo_Prg_14_Step = 9; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_14 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
{ 70, 45, 135, 110, 110, 135, 45, 70, 400 }, // leg1,2,3,4 two sides
{ 115, 45, 135, 65, 110, 135, 45, 70, 400 }, // leg1,2 up
{ 70, 45, 135, 110, 65, 135, 45, 115, 400 }, // leg1,2 dn; leg3,4 up
{ 115, 45, 135, 65, 110, 135, 45, 70, 400 }, // leg3,4 dn; leg1,2 up
{ 70, 45, 135, 110, 65, 135, 45, 115, 400 }, // leg1,2 dn; leg3,4 up
{ 115, 45, 135, 65, 110, 135, 45, 70, 400 }, // leg3,4 dn; leg1,2 up
{ 70, 45, 135, 110, 65, 135, 45, 115, 400 }, // leg1,2 dn; leg3,4 up
{ 115, 45, 135, 65, 110, 135, 45, 70, 400 }, // leg3,4 dn; leg1,2 up
{ 75, 45, 135, 105, 110, 135, 45, 70, 400 }, // leg1,2 dn
}; // matriz de ângulos e rotina de acionamento cinemático
// 舞步 3
const int Servo_Prg_15_Step = 10; // matriz de ângulos e rotina de acionamento cinemático
const int Servo_Prg_15 [][ALLMATRIX] PROGMEM = { // matriz de ângulos e rotina de acionamento cinemático
// G14, G12, G13, G15, G16, G5, G4, G2, ms
{ 70, 45, 45, 110, 110, 135, 135, 70, 400 }, // leg1,2,3,4 bk
{ 110, 45, 45, 60, 70, 135, 135, 70, 400 }, // leg1,2,3 up
{ 70, 45, 45, 110, 110, 135, 135, 70, 400 }, // leg1,2,3 dn
{ 110, 45, 45, 110, 70, 135, 135, 120, 400 }, // leg1,3,4 up
{ 70, 45, 45, 110, 110, 135, 135, 70, 400 }, // leg1,3,4 dn
{ 110, 45, 45, 60, 70, 135, 135, 70, 400 }, // leg1,2,3 up
{ 70, 45, 45, 110, 110, 135, 135, 70, 400 }, // leg1,2,3 dn
{ 110, 45, 45, 110, 70, 135, 135, 120, 400 }, // leg1,3,4 up
{ 70, 45, 45, 110, 110, 135, 135, 70, 400 }, // leg1,3,4 dn
{ 70, 90, 90, 110, 110, 90, 90, 70, 400 }, // standby
}; // matriz de ângulos e rotina de acionamento cinemático
void Set_PWM_to_Servo(int iServo, int iValue) // matriz de ângulos e rotina de acionamento cinemático
{ // matriz de ângulos e rotina de acionamento cinemático
int NewPWM = map(iValue, PWMRES_Min, PWMRES_Max, SERVOMIN, SERVOMAX); // matriz de ângulos e rotina de acionamento cinemático
if (iServo >= 7) { // matriz de ângulos e rotina de acionamento cinemático
servo_2.write(NewPWM); // matriz de ângulos e rotina de acionamento cinemático
} else if (iServo >= 6) { // matriz de ângulos e rotina de acionamento cinemático
servo_4.write(NewPWM); // matriz de ângulos e rotina de acionamento cinemático
} else if (iServo >= 5) { // matriz de ângulos e rotina de acionamento cinemático
servo_5.write(NewPWM); // matriz de ângulos e rotina de acionamento cinemático
} else if (iServo >= 4) { // matriz de ângulos e rotina de acionamento cinemático
servo_16.write(NewPWM); // matriz de ângulos e rotina de acionamento cinemático
} else if (iServo >= 3) { // matriz de ângulos e rotina de acionamento cinemático
servo_15.write(NewPWM); // matriz de ângulos e rotina de acionamento cinemático
} else if (iServo >= 2) { // matriz de ângulos e rotina de acionamento cinemático
servo_13.write(NewPWM); // matriz de ângulos e rotina de acionamento cinemático
} else if (iServo >= 1) { // matriz de ângulos e rotina de acionamento cinemático
servo_12.write(NewPWM); // matriz de ângulos e rotina de acionamento cinemático
} else if (iServo == 0) { // matriz de ângulos e rotina de acionamento cinemático
servo_14.write(NewPWM); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
void Servo_PROGRAM_Run(const int iMatrix[][ALLMATRIX], int iSteps) // matriz de ângulos e rotina de acionamento cinemático
{ // matriz de ângulos e rotina de acionamento cinemático
int INT_TEMP_A, INT_TEMP_B, INT_TEMP_C; // matriz de ângulos e rotina de acionamento cinemático
for (int MainLoopIndex = 0; MainLoopIndex < iSteps; MainLoopIndex++) // iSteps Step main loop
{ // matriz de ângulos e rotina de acionamento cinemático
int InterTotalTime = iMatrix[MainLoopIndex][ALLMATRIX - 1]; // InterTotalTime Total time for this step
int InterDelayCounter = InterTotalTime / BASEDELAYTIME; // InterDelayCounter This step is delayed a basic number of times
for (int InterStepLoop = 0; InterStepLoop < InterDelayCounter; InterStepLoop++) // Interpolate loops
{ // matriz de ângulos e rotina de acionamento cinemático
for (int ServoIndex = 0; ServoIndex < ALLSERVOS; ServoIndex++) // Servo main cycle
{ // matriz de ângulos e rotina de acionamento cinemático
INT_TEMP_A = Running_Servo_POS[ServoIndex]; // The current position of the servo
INT_TEMP_B = iMatrix[MainLoopIndex][ServoIndex]; // Target position of the servo
if (INT_TEMP_A == INT_TEMP_B) // The servo values are unchanged
{ // matriz de ângulos e rotina de acionamento cinemático
INT_TEMP_C = INT_TEMP_B; // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
else if (INT_TEMP_A > INT_TEMP_B) // Reduction of servo value
{ // matriz de ângulos e rotina de acionamento cinemático
INT_TEMP_C = map(BASEDELAYTIME * InterStepLoop, 0, InterTotalTime, 0, INT_TEMP_A - INT_TEMP_B); // PWM internal difference = map(execution time accumulation, start time, end time, start value of internal difference, maximum value of internal difference)
if (INT_TEMP_A - INT_TEMP_C >= INT_TEMP_B) // matriz de ângulos e rotina de acionamento cinemático
{ // matriz de ângulos e rotina de acionamento cinemático
Set_PWM_to_Servo(ServoIndex, INT_TEMP_A - INT_TEMP_C); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
else if (INT_TEMP_A < INT_TEMP_B) // The servo value is increased
{ // matriz de ângulos e rotina de acionamento cinemático
INT_TEMP_C = map(BASEDELAYTIME * InterStepLoop, 0, InterTotalTime, 0, INT_TEMP_B - INT_TEMP_A); // PWM internal difference = map(execution time accumulation, start time, end time, start internal difference, maximum internal difference)
if (INT_TEMP_A + INT_TEMP_C <= INT_TEMP_B) { // matriz de ângulos e rotina de acionamento cinemático
Set_PWM_to_Servo(ServoIndex, INT_TEMP_A + INT_TEMP_C); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
delay(BASEDELAYTIME); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
// Backup current servo value
for (int Index = 0; Index < ALLMATRIX; Index++) // matriz de ângulos e rotina de acionamento cinemático
{ // matriz de ângulos e rotina de acionamento cinemático
Running_Servo_POS[Index] = iMatrix[MainLoopIndex][Index]; // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
void Servo_PROGRAM_Zero() // matriz de ângulos e rotina de acionamento cinemático
{ // matriz de ângulos e rotina de acionamento cinemático
for (int Index = 0; Index < ALLMATRIX; Index++) // matriz de ângulos e rotina de acionamento cinemático
{ // matriz de ângulos e rotina de acionamento cinemático
Running_Servo_POS[Index] = Servo_Act_0[Index]; // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
for (int iServo = 0; iServo < ALLSERVOS; iServo++) // matriz de ângulos e rotina de acionamento cinemático
{ // matriz de ângulos e rotina de acionamento cinemático
Set_PWM_to_Servo(iServo, Running_Servo_POS[iServo]); // matriz de ângulos e rotina de acionamento cinemático
delay(10); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
for (int Index = 0; Index < ALLMATRIX; Index++) // matriz de ângulos e rotina de acionamento cinemático
{ // matriz de ângulos e rotina de acionamento cinemático
Running_Servo_POS[Index] = Servo_Act_1[Index]; // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
for (int iServo = 0; iServo < ALLSERVOS; iServo++) // matriz de ângulos e rotina de acionamento cinemático
{ // matriz de ângulos e rotina de acionamento cinemático
Set_PWM_to_Servo(iServo, Running_Servo_POS[iServo]); // matriz de ângulos e rotina de acionamento cinemático
delay(10); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
void standby() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_1, Servo_Prg_1_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
// Sleep program
void sleep() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_1, Servo_Prg_1_Step); // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_12, Servo_Prg_12_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
// Planking procedure
void lie() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_8, Servo_Prg_8_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
void forward() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_2, Servo_Prg_2_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
void back() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_3, Servo_Prg_3_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
// Left turn program
void turnleft() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_6, Servo_Prg_6_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
// Right turn program
void turnright() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_7, Servo_Prg_7_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
//Left shift
void leftmove() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_4, Servo_Prg_4_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
//Right shift
void rightmove() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_5, Servo_Prg_5_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
void hello() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_9, Servo_Prg_9_Step); // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_1, Servo_Prg_1_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
void dance1() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_13, Servo_Prg_13_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
void dance2() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_14, Servo_Prg_14_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
void dance3() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_15, Servo_Prg_15_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
// Push up routine
void pushup() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_11, Servo_Prg_11_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
// Combat procedure
void fighting() { // matriz de ângulos e rotina de acionamento cinemático
Servo_PROGRAM_Run(Servo_Prg_10, Servo_Prg_10_Step); // matriz de ângulos e rotina de acionamento cinemático
} // matriz de ângulos e rotina de acionamento cinemático
Guia Diagnóstico de Falhas e Resolução de Problemas (Troubleshooting)
A tabela diagnóstica abaixo relaciona os sintomas operacionais mais comuns encontrados durante a montagem, teste e operação do robô quadrúpede aranha, apontando suas causas físicas raízes e as instruções técnicas corretivas imediatas:
| Sintoma Observado | Causa Raiz Provável | Ação Técnica Corretiva Recomendada |
|---|---|---|
| ESP8266 reinicia repentinamente quando os motores começam a se mover | Queda de tensão da bateria (Brownout Reset) provocada por pico de corrente dos 8 servomotores | 1. Recarregue completamente a célula 18650 até atingir 4.2V. 2. Verifique se a bateria utilizada possui capacidade de descarga contínua de pelo menos 10A (preferencialmente células com alta taxa C). 3. Verifique o aperto dos parafusos do suporte de bateria para evitar resistência de contato parasitária. |
| Servomotores vibram excessivamente ou tremem (jitter) parados | Ruído eletromagnético nas linhas de sinal PWM ou tensão de alimentação instável | 1. Certifique-se de que o barramento de alimentação comum (GND) esteja perfeitamente conectado entre o ESP8266 e a placa de expansão. 2. Afaste os chicotes de sinal dos motores dos cabos de alta corrente de alimentação. 3. Verifique se algum parafuso de articulação do acrílico está excessivamente apertado travando mecanicamente o eixo. |
| O robô caminha em círculo ou desvia da trajetória reta | Diferença angular de montagem em um dos eixos (assimetria na calibração de ponto neutro) | 1. Recarregue o programa 1.3zero_0.ino para energizar os servos nas posições mestre.2. Solte o parafuso central da perna desalinhada, retire o braço plástico do eixo dentado e recoloque-o exatamente no ângulo de 45° ou 135° correspondente. 3. Aperte novamente o parafuso de retenção. |
| Erro de compilação ou ‘Port not found’ no Arduino IDE | Driver CP2102 ausente ou porta COM ocupada por outro aplicativo (ex.: Monitor Serial aberto) | 1. Reinstale o driver CP210x Universal Driver na pasta de drivers. 2. Feche outras janelas do Monitor Serial ou terminais seriais (PuTTY, etc.). 3. Troque o cabo USB Type-C por um cabo certificado para dados (cabos apenas de carga não possuem os fios D+ e D-). |
| Smartphone não localiza a rede Wi-Fi ‘QuadBot-E’ | Firmware da Lição 8 não foi gravado com sucesso ou inicialização do rádio Wi-Fi falhou | 1. Abra o Monitor Serial a 115200 baud durante a inicialização para verificar se a mensagem de criação do SoftAP é exibida. 2. Se a rede ainda não aparecer, verifique se a chave de alimentação do shield está ligada fornecendo 5V para o regulador da placa. 3. Reinicie o ESP8266 pelo botão de reset físico (RST). |
| Aplicativo móvel exibe ‘Connected Fail’ ao tentar conectar | Smartphone desconectou da rede do robô por falta de acesso à internet | Em smartphones Android e iOS, o sistema operacional detecta que a rede Wi-Fi do robô não possui internet e pode desconectar automaticamente ou alternar para os dados móveis (4G/5G). Desative temporariamente os Dados Móveis no smartphone e confirme a permanência na rede QuadBot-E marcando a opção Manter conexão sem internet. |
| Uma das pernas não se move enquanto as outras 7 funcionam | Conector invertido ou rompimento de cabo na articulação móvel | 1. Inspecione o conector de 3 vias na placa de expansão: certifique-se de que a via marrom está no pino GND e a laranja no pino de Sinal. 2. Teste o servomotor suspeito individualmente utilizando o código do Experimento 1.2 ( 1.2Servo-Test.ino).3. Se o motor não responder mesmo com pulsos PWM corretos, substitua a unidade por um servo reserva SG90. |
Solução de problemas
Olá! Sou o assistente técnico da RoboBuilders. Descreva seu problema com o Kit Robô Avançado Quadrúpede Aranha Tutoriais Wifi App QD020 RB2055 - Curso Completo e eu ajudarei a encontrar a solução.
O assistente usa IA e pode errar. Confirme informações críticas no datasheet oficial do fabricante.