Olá makers, como estão? Espero que estejam bem. Eu (Rodrigo Mesquita) e o Prof. Sandro Mesquita estávamos pensando no que escrever para vocês, até que tivemos a brilhante ideia de apresentar um projeto que o Prof. Sandro ajudou a desenvolver, sendo como um projeto mais “dinâmico”, digamos assim. Hoje iremos aprender a fazer a boneca do Round 6 usando Arduino Nano.
Para você que chegou aqui de paraquedas e se interessou pelo artigo, nós geralmente ensinamos como fazer um projeto, em que é usado no dia a dia e os incentivamos a pensar por si só em algum projeto e quem sabe mandar para nós fazermos e criarmos um artigo sobre.
O intuito deste artigo é mostrar que a robótica não se aplica somente em “máquinas que ajudam a sociedade” ou como trabalho, podemos “fazer” robótica em algo que gostamos, ou seja para o entretenimento.
Batatinha frita 1,2,3…
Você já deve ter assistido (caso tenha a idade indicada) ou ouvido falar sobre a série ou “dorama” coreano “Round 6” que ficou mundialmente conhecido e atingiu uma ótima avaliação na plataforma de streaming Netflix.
Esta série gira em torno da vida de Seong Gi-Hun que está afogado em dívidas. Ele acaba sendo convidado para participar de um jogo de sobrevivência, e caso ganhasse, receberia uma boa quantia de dinheiro que usaria para pagar suas dívidas e ajudar sua mãe e filha. Porém, este jogo de sobrevivência acaba virando um terrível pesadelo e assim segue a história.
O primeiro desafio enfrentado pelos participantes desse jogo se chama “batatinha frita 1,2,3”, na qual um robô gigante com feições de uma criança canta a musiquinha que se dá o nome da “brincadeira”, e os participantes tem que correr até a linha de chegada que fica na direção do robô, porém, quando a “boneca” terminar de cantar a música ninguém pode se mexer, caso o contrário, “perde” a brincadeira e consequentemente é desclassificado do jogo.
O projeto
Com a solicitação do Sana 2022 (evento geek anual de Fortaleza. Passaram aproximadamente 10 mil pessoas nos dois dias de evento) foi feito o projeto da “boneca” de Round 6, na qual o Walterlan Veríssimo fez a escultura do projeto, Sandro Mesquita a automação e Bianor Medeiros a parte mecânica e eletrônica.
A boneca possuía um Arduino Nano(que já usamos em vários projetos aqui no blog como o Carro controlado por Bluetooth) implantado na sua cabeça e controlado por rádio de frequência, possibilitando assim o movimento da cabeça assim como na série. Observe o esquemático de montagem do circuito eletrônico logo abaixo:
Além do Arduino Nano e o Rádio, usamos 02 sensores de fim de curso, representado pelos botões, um motor e uma ponte H de 43A para controle da cabeça.
Lista de componentes usados no projeto:
- 01 Arduino Nano
- 01 Motor CC
- 01 Ponte H BTS7960 (ou outra caso você use em menor escala)
- 01 Motor DC Alto Torque (ou outro caso você use em menor escala)
- 01 Led vermelho
- 01 Resistor de 330Ohm
- 01 Módulo Receptor 433MHz Rx B6 (ou outro similar)
- 02 Chaves Fim de Curso
- 01 Antena
- 01 Controle Remoto 433MHz Premium (ou outro similar)
- 01 Fonte Chaveada 5A (ou outro similar)
Abaixo segue uma imagem da primeira montagem e testes realizados fora o corpo da boneca, o rádio se comportou de forma surpreendente, com um alcance de mais 20 metros com barreiras.
E logo em seguida o projeto montado na case, acondicionados em uma caixa Patola com vedação para proteger da umidade.
Observe que deixamos o dissipador de calor da ponte H para fora da caixa patola para evitar superaquecimento em seu interior.
Funcionamento
O projeto é simples mas tem uma lógica bem interessante, a cabeça deverá ficar parada, virada para frente, ao acionar o controle ela irá girar até tocar na chave fim de curso que está posicionada para garantir que a cabeça pare exatamente quando completar um ângulo de 180º, ou seja, totalmente virada para trás.
Ela irá ficar virada por um determinado tempo e retornar para posição de descanso, parando quando tocar na outra chave fim de curso.
Caso uma das chaves não seja acionada, o sistema entrará em alarme, sendo desarmado via controle e ficando no modo manual, onde ao apertar o botão A ela gira em um sentido ou outro e apertando o botão B ela para.
Ou seja, mesmo os sensores sendo danificados, o jogo não iria parar, pois o modo manual seria acionado.
Mergulhando no código
#include <RCSwitch.h> RCSwitch mySwitch = RCSwitch(); #define led 5 #define MOTOR_POSITIVO A0 //Pino do arduino que será ligado no pino 1 do BTS7960 #define MOTOR_NEGATIVO A1 //Pino do arduino que será ligado no pino 2 do BTS7960 #define VELOCIDADE 150 //tempo (ms) que o motor ficará na mesma velocidade #define END_STOP_ESQUERDO 3 //Cabeça na posição inicial, de repouso #define END_STOP_DIREITO 4 //Cabeça virada, olhando para tras bool virada = false, inicial = false, erro = false, sentido = false; unsigned long tempoInicial = 0; int tempoMovimento = 0; void setup() { Serial.begin(9600); pinMode(led, OUTPUT); pinMode(MOTOR_POSITIVO, OUTPUT); pinMode(MOTOR_NEGATIVO, OUTPUT); pinMode(END_STOP_ESQUERDO, INPUT_PULLUP); pinMode(END_STOP_DIREITO, INPUT_PULLUP); digitalWrite(led, LOW); mySwitch.enableReceive(0); // Ligue o receptor do Radio no pino 02 tempoInicial = millis(); Serial.println("Setup"); inicializacao(); } void loop() { //Serial.println(digitalRead(END_STOP_DIREITO)); if (mySwitch.available()) { if (mySwitch.getReceivedValue() == 3851937) { sentido = !sentido; movimento(sentido); if (!virada or !inicial) { alarme(); } } mySwitch.resetAvailable(); } } void inicializacao() { if (!digitalRead(END_STOP_DIREITO)) { while (!digitalRead(END_STOP_DIREITO)) { digitalWrite(led, HIGH); analogWrite(MOTOR_POSITIVO, LOW); digitalWrite(MOTOR_NEGATIVO, VELOCIDADE); tempoMovimento = millis() - tempoInicial; if (tempoMovimento > 5000) { erro = true; digitalWrite(MOTOR_NEGATIVO, LOW); break; } } } else { alarme(); } if (!erro) { virada = true; digitalWrite(MOTOR_NEGATIVO, LOW); digitalWrite(led, LOW); delay(2000); tempoInicial = millis(); if (!digitalRead(END_STOP_ESQUERDO)) { while (!digitalRead(END_STOP_ESQUERDO)) { digitalWrite(led, HIGH); analogWrite(MOTOR_POSITIVO, VELOCIDADE); digitalWrite(MOTOR_NEGATIVO, LOW); tempoMovimento = millis() - tempoInicial; if (tempoMovimento > 5000) { erro = true; digitalWrite(MOTOR_POSITIVO, LOW); break; } } } else{ alarme(); } if (!erro) { digitalWrite(MOTOR_POSITIVO, LOW); digitalWrite(led, LOW); inicial = true; } else inicial = false; } else virada = false; if (!virada or !inicial) { alarme(); } } void movimento(bool sentido) { tempoInicial = millis(); tempoMovimento = 0; if (sentido) { while (!digitalRead(END_STOP_DIREITO)) { digitalWrite(led, HIGH); analogWrite(MOTOR_POSITIVO, LOW); digitalWrite(MOTOR_NEGATIVO, VELOCIDADE); tempoMovimento = millis() - tempoInicial; if (tempoMovimento > 5000) { erro = true; digitalWrite(MOTOR_NEGATIVO, LOW); break; } } digitalWrite(MOTOR_NEGATIVO, LOW); digitalWrite(led, LOW); if (!erro) { virada = true; } else virada = false; } else { while (!digitalRead(END_STOP_ESQUERDO)) { digitalWrite(led, HIGH); analogWrite(MOTOR_POSITIVO, VELOCIDADE); digitalWrite(MOTOR_NEGATIVO, LOW); tempoMovimento = millis() - tempoInicial; if (tempoMovimento > 5000) { erro = true; digitalWrite(MOTOR_POSITIVO, LOW); break; } } digitalWrite(MOTOR_POSITIVO, LOW); digitalWrite(led, LOW); if (!erro) { inicial = true; } else inicial = false; } } void alarme() { unsigned long tempoAtual = millis(); int tempoPisca = 0; bool estadoLed = 0; while (true) { tempoPisca = millis() - tempoAtual; if (mySwitch.available()) { if (mySwitch.getReceivedValue() == 3851938) { mySwitch.resetAvailable(); modoManual(); } mySwitch.resetAvailable(); } if (tempoPisca > 500) { digitalWrite(led, estadoLed); estadoLed = !estadoLed; tempoAtual = millis(); } } } void modoManual() { sentido = false; bool parado = false; digitalWrite(led, HIGH); while (true) { if (mySwitch.available()) { if ((mySwitch.getReceivedValue() == 3851937) and (parado)) { if (sentido) { digitalWrite(led, HIGH); analogWrite(MOTOR_POSITIVO, LOW); digitalWrite(MOTOR_NEGATIVO, VELOCIDADE); parado = false; } else { digitalWrite(led, HIGH); analogWrite(MOTOR_POSITIVO, VELOCIDADE); digitalWrite(MOTOR_NEGATIVO, LOW); parado = false; } } else if ((mySwitch.getReceivedValue() == 3851938) and (!parado)) { analogWrite(MOTOR_POSITIVO, LOW); digitalWrite(MOTOR_NEGATIVO, LOW); digitalWrite(led, LOW); sentido = !sentido; parado = true; } mySwitch.resetAvailable(); } } }
Acima você encontra o código completo!
Detalhamento do código
Na primeira parte do código tem a importação da biblioteca RCSwitch (rc-switch – Arduino Libraries) para o controle do módulo receptor, definição das variáveis e no setup as devidas atualizações dos pinos e rádio.
O void loop() ficou muito enxuto, ele verifica se existe uma comunicação entre o controle e o módulo receptor (linha 30), recebe o dado do controle (linha 31) e faz a lógica de inversão do sentido de rotação da cabeça, se ela estiver virada vai para posição inicial, se estiver na posição inicial vai virar chamando a função movimento( ), caso não detecte as chaves fim de curso irá chamar a função alarme( ) e resetar a comunicação.
Sugiro copiar o código acima e olhar com detalhes na IDE do Arduino ou na IDE de sua preferência, pois o código é um pouco longo, tem 200 linhas, basicamente após o loop o código tem 04 funções:
- void inicializacao()
Faz os testes iniciais para identificar se as chaves de fim de curso, motor e módulo receptor estão funcionando.
- void movimento(bool sentido)
Função responsável pelo movimento automático após acionar a cabeça, ou seja, lógica de virar, aguardar um tempo e retornar.
- void alarme()
Função responsável por parar a cabeça e acionar o modo alarme após identificar que as chaves de fim de curso estão danificadas.
- void modoManual()
Modo de controle manual da cabeça pelo controle.
Conclusão
Esse foi o projeto da boneca do round 6 usando Arduino Nano. E assim encerramos mais um artigo, dessa vez sobre um projeto mais “informal”, abrindo assim ainda mais a mente de vocês e dando mais exemplos de projetos na qual podem ser confeccionados. Já imaginou seu projeto sendo visto por aproximadamente 10 mil pessoas em um evento como o Sana? Mas lembrem-se, com o Arduino dá para fazer projetos mais profissionais também. Não esqueçam de compartilhar conosco suas dúvidas e projetos para enriquecer ainda mais a comunidade.
Deixe uma resposta