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