Construa um Braço Robótico Arduino Sem Fios, Controlado pelo Smartphone
Neste tutorial, vamos aprender como fazer um Braço Robótico Arduino que pode ser controlado e programado sem fio usando um aplicativo Android personalizado. Mostrarei todo o processo de construção, começando pelo design e impressão 3D das peças do robô, conexão dos componentes eletrônicos e programação do Arduino, até o desenvolvimento de nosso próprio aplicativo Android para controle do Braço Robótico.
Você pode assistir ao vídeo a seguir ou ler o tutorial escrito abaixo.
Visão Geral
Usando os sliders no app, podemos controlar manualmente o movimento de cada servo ou eixo do braço robótico. Também, usando o botão "Salvar", podemos gravar cada posição ou passo e então o braço robótico pode executar automaticamente e repetir estes passos. Com o mesmo botão, podemos pausar a operação automática, bem como resetar ou apagar todos os passos para gravar novos.
Modelo 3D do Braço Robótico Arduino
Para começar, projetei o Braço Robótico usando o software de modelagem 3D Solidworks. O braço tem 5 graus de liberdade.

Para os primeiros 3 eixos, a base, o ombro e o cotovelo, usei servos MG996R, e para os outros 2 eixos, rotação do pulso e inclinação do pulso, bem como a garra, usei os menores servos micro SG90.
Você pode encontrar e baixar este modelo 3D, bem como explorá-lo no seu navegador no Thangs:

Baixe o modelo 3D de montagem do Thangs.
Obrigado Thangs por apoiar este tutorial.
Arquivos STL para Impressão 3D:
Arquivos STL do Braço Robótico Arduino
1 arquivo(s) 0.00 KB DownloadImpressão 3D do Braço Robótico
Usando minha nova Impressora 3D, Creality CR-10, imprimi em 3D todas as peças para o braço robótico Arduino.

Aqui gostaria de dar um agradecimento à Banggood.com por me fornecer esta incrível impressora 3D. A qualidade de impressão da Creality CR-10 é incrível para seu preço e o que também é ótimo é que ela vem quase 90% pré-montada.

Para completar a montagem, só temos que conectar as partes superior e inferior das estruturas usando alguns parafusos e suportes, e então conectar os componentes eletrônicos com a caixa de controle usando os cabos fornecidos.

Antes de testar, é recomendado verificar se as rodas do rolo estão apertadas o suficiente, e se não estiverem, você pode simplesmente usar as porcas excêntricas para apertá-las. E pronto, após nivelar sua mesa de impressão 3D, você está pronto para transformar suas criações 3D em realidade.

Tive todas as peças para o Braço Robótico Arduino prontas em apenas algumas horas.
Leia mais: Top 15 Acessórios e Ferramentas Essenciais para Impressora 3D
Montagem do Braço Robótico
Ok, então neste ponto estamos prontos para montar o braço robótico. Comecei com a base na qual fixei o primeiro motor servo usando os parafusos incluídos em sua embalagem. Então, no eixo de saída do servo, fixei um chifre redondo com um parafuso.

E em cima coloquei a parte superior e a fixei usando dois parafusos.

Aqui novamente primeiro vai o servo, depois o chifre redondo na próxima parte, e então eles são fixados um ao outro usando o parafuso no eixo de saída.

Podemos notar aqui que no eixo do ombro é boa ideia incluir algum tipo de mola ou, no meu caso, usei um elástico para dar alguma ajuda ao servo porque este servo carrega todo o peso do resto do braço, bem como a carga útil.

De forma similar, continuei montando o resto do braço robótico. Quanto ao mecanismo da garra, usei alguns parafusos e porcas de 4 milímetros para montá-lo.

Finalmente, fixei o mecanismo da garra no último servo e o braço robótico Arduino foi completado.

Diagrama do Circuito do Braço Robótico Arduino
A próxima etapa é conectar a eletrônica. O diagrama de circuito deste projeto é na verdade bastante simples. Precisamos apenas de uma placa Arduino e um módulo Bluetooth HC-05 para comunicação com o smartphone. Os pinos de controle dos seis motores servo são conectados a seis pinos digitais da placa Arduino.

Para alimentar os servos precisamos de 5V, mas isso deve vir de uma fonte de alimentação externa porque o Arduino não consegue lidar com a quantidade de corrente que todos eles podem consumir. A fonte de energia deve ser capaz de lidar com pelo menos 2A de corrente. Então, uma vez conectado tudo, podemos passar para programar o Arduino e fazer o app Android.
Você pode obter os componentes necessários para este exemplo nos links abaixo:
- Motor Servo MG996R……………………….….
- Motor Servo Micro SG90 ……..…….….…….
- Módulo Bluetooth HC-05 ………………….…
- Placa Arduino …………………………………….
- Fonte DC 5V 2A ………………….…..
Código do Braço Robótico Arduino
Como o código é um pouco longo, para melhor compreensão, postarei o código fonte do programa em seções com descrição para cada seção. E no final deste artigo, postarei o código fonte completo.
Então, primeiro precisamos incluir a biblioteca SoftwareSerial para comunicação serial do módulo Bluetooth, bem como a biblioteca servo. Ambas as bibliotecas estão incluídas com a Arduino IDE, então você não precisa instalá-las externamente. Então, precisamos definir os seis servos, o módulo Bluetooth HC-05 e algumas variáveis para armazenar a posição atual e anterior dos servos, bem como arrays para armazenar as posições ou passos para o modo automático.
#include <SoftwareSerial.h> #include <Servo.h> Servo servo01; Servo servo02; Servo servo03; Servo servo04; Servo servo05; Servo servo06; SoftwareSerial Bluetooth(3, 4); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX) int servo1Pos, servo2Pos, servo3Pos, servo4Pos, servo5Pos, servo6Pos; // posição atual int servo1PPos, servo2PPos, servo3PPos, servo4PPos, servo5PPos, servo6PPos; // posição anterior int servo01SP[50], servo02SP[50], servo03SP[50], servo04SP[50], servo05SP[50], servo06SP[50]; // para armazenar posições/passos int speedDelay = 20; int index = 0; String dataIn = "";
Na seção setup, precisamos inicializar os servos e o módulo Bluetooth e mover o braço robótico para sua posição inicial. Fazemos isso usando a função write() que simplesmente move o servo para qualquer posição de 0 a 180 graus.
void setup() { servo01.attach(5); servo02.attach(6); servo03.attach(7); servo04.attach(8); servo05.attach(9); servo06.attach(10); Bluetooth.begin(38400); // Taxa de baud padrão do módulo Bluetooth Bluetooth.setTimeout(1); delay(20); // Posição inicial do braço robótico servo1PPos = 90; servo01.write(servo1PPos); servo2PPos = 150; servo02.write(servo2PPos); servo3PPos = 35; servo03.write(servo3PPos); servo4PPos = 140; servo04.write(servo4PPos); servo5PPos = 85; servo05.write(servo5PPos); servo6PPos = 80; servo06.write(servo6PPos); }
Em seguida, na seção loop, usando a função Bluetooth.available(), verificamos constantemente se há algum dado de entrada do Smartphone. Se verdadeiro, usando a função readString() lemos os dados como string e armazenamos na variável dataIn. Dependendo dos dados recebidos, diremos ao braço robótico o que fazer.
// Verifica dados de entrada if (Bluetooth.available() > 0) { dataIn = Bluetooth.readString(); // Lê os dados como string
App Android de Controle
Vamos dar uma olhada no app Android agora e ver que tipo de dados ele está realmente enviando para o Arduino.

Fiz o app usando o aplicativo online MIT App Inventor e aqui está como funciona. No topo, temos dois botões para conectar o smartphone ao módulo Bluetooth HC-05. Então, no lado esquerdo, temos uma imagem do braço robótico, e no lado direito temos os seis sliders para controle dos servos e um slider para controle de velocidade.

Cada slider tem diferentes valores inicial, mínimo e máximo que se adequam às juntas do braço robótico. Na parte inferior do app, temos três botões: SALVAR, EXECUTAR e RESET através dos quais podemos programar o braço robótico para rodar automaticamente. Há também um rótulo abaixo que mostra o número de passos salvos. No entanto, para mais detalhes de como construir apps como este usando o MIT App Inventor, você pode conferir meu outro tutorial detalhado para isso.
Ok, agora vamos ver o programa ou os blocos por trás da aplicação. Primeiro, no lado esquerdo, temos os blocos para conectar o smartphone ao módulo Bluetooth.

Então, temos os blocos dos sliders para controle de posição dos servos e os blocos dos botões para programação do braço robótico. Então, se mudarmos a posição do slider, usando a função Bluetooth .SendText, enviamos um texto para o Arduino. Este texto consiste em um prefixo que indica qual slider foi alterado, bem como o valor atual do slider.

Aqui está um arquivo para download do projeto MIT App Inventor acima, bem como o App Android pronto para ser instalado no seu smartphone:
Arquivo do Projeto MIT App Inventor - Controle Braço Robótico Arduino
1 arquivo(s) 24.85 KB Download
App Android Controle Braço Robótico Arduino
1 arquivo(s) 2.57 MB DownloadPortanto, no Arduino, usando a função startsWith(), verificamos o prefixo de cada dado de entrada e assim sabemos o que fazer a seguir. Por exemplo, se o prefixo for "s1", sabemos que precisamos mover o servo número um. Usando a função substring(), obtemos o texto restante, ou seja, o valor da posição, convertemos em inteiro e usamos o valor para mover o servo para aquela posição.
// Se slider "Base" mudou valor - Move Servo 1 para posição if (dataIn.startsWith("s1")) { String dataInS = dataIn.substring(2, dataIn.length()); // Extrai apenas o número. Ex: de "s1120" para "120" servo1Pos = dataInS.toInt(); // Converte a string em inteiro
Aqui podemos simplesmente chamar a função write() e o servo irá para aquela posição, mas dessa forma o servo rodaria em sua velocidade máxima, o que é demais para o braço robótico. Em vez disso, precisamos controlar a velocidade dos servos, então usei alguns loops FOR para mover gradualmente o servo da posição anterior para a atual, implementando um tempo de delay entre cada iteração. Mudando o tempo de delay, você pode mudar a velocidade do servo.
// Usamos loops for para controlar a velocidade do servo // Se posição anterior é maior que posição atual if (servo1PPos > servo1Pos) { for ( int j = servo1PPos; j >= servo1Pos; j--) { // Move servo para baixo servo01.write(j); delay(20); // define a velocidade na qual o servo gira } } // Se posição anterior é menor que posição atual if (servo1PPos < servo1Pos) { for ( int j = servo1PPos; j <= servo1Pos; j++) { // Move servo para cima servo01.write(j); delay(20); } } servo1PPos = servo1Pos; // define posição atual como posição anterior }
O mesmo método é usado para acionar cada eixo do braço robótico.
Abaixo deles está o botão SALVAR. Se pressionarmos o botão SALVAR, a posição de cada motor servo é armazenada em um array. A cada pressão, o índice aumenta, então o array é preenchido passo a passo.
// Se botão "SALVAR" é pressionado if (dataIn.startsWith("SAVE")) { servo01SP[index] = servo1PPos; // salva posição no array servo02SP[index] = servo2PPos; servo03SP[index] = servo3PPos; servo04SP[index] = servo4PPos; servo05SP[index] = servo5PPos; servo06SP[index] = servo6PPos; index++; // Aumenta índice do array }
Então, se pressionarmos o botão EXECUTAR, chamamos a função personalizada runservo() que executa os passos salvos. Vamos dar uma olhada nesta função. Aqui, executamos os passos salvos repetidamente até pressionarmos o botão RESET. Usando o loop FOR, percorremos todas as posições armazenadas nos arrays e, ao mesmo tempo, verificamos se temos algum dado de entrada do smartphone. Estes dados podem ser o botão EXECUTAR/PAUSAR, que pausa o robô, e se clicado novamente continua com os movimentos automáticos. Também, se mudarmos a posição do slider de velocidade, usaremos esse valor para mudar o tempo de delay entre cada iteração nos loops FOR abaixo, que controla a velocidade dos motores servo.
// Função personalizada modo automático - executa passos salvos void runservo() { while (dataIn != "RESET") { // Executa passos repetidamente até botão "RESET" ser pressionado for (int i = 0; i <= index - 2; i++) { // Percorre todos os passos(index) if (Bluetooth.available() > 0) { // Verifica dados de entrada dataIn = Bluetooth.readString(); if ( dataIn == "PAUSE") { // Se botão "PAUSAR" é pressionado while (dataIn != "RUN") { // Espera até "EXECUTAR" ser pressionado novamente if (Bluetooth.available() > 0) { dataIn = Bluetooth.readString(); if ( dataIn == "RESET") { break; } } } } // Se slider de VELOCIDADE é alterado if (dataIn.startsWith("ss")) { String dataInS = dataIn.substring(2, dataIn.length()); speedDelay = dataInS.toInt(); // Muda velocidade do servo (tempo de delay) } } // Servo 1 if (servo01SP[i] == servo01SP[i + 1]) { } if (servo01SP[i] > servo01SP[i + 1]) { for ( int j = servo01SP[i]; j >= servo01SP[i + 1]; j--) { servo01.write(j); delay(speedDelay); } } if (servo01SP[i] < servo01SP[i + 1]) { for ( int j = servo01SP[i]; j <= servo01SP[i + 1]; j++) { servo01.write(j); delay(speedDelay); } }
De forma similar, como explicado anteriormente com estas instruções IF e loops FOR, movemos os servos para sua próxima posição. Finalmente, se pressionarmos o botão RESET, limparemos todos os dados dos arrays para zero e também resetaremos o índice para zero, para que possamos reprogramar o braço robótico com novos movimentos.
// Se botão "RESET" é pressionado if ( dataIn == "RESET") { memset(servo01SP, 0, sizeof(servo01SP)); // Limpa dados do array para 0 memset(servo02SP, 0, sizeof(servo02SP)); memset(servo03SP, 0, sizeof(servo03SP)); memset(servo04SP, 0, sizeof(servo04SP)); memset(servo05SP, 0, sizeof(servo05SP)); memset(servo06SP, 0, sizeof(servo06SP)); index = 0; // Índice para 0 }
E pronto, agora podemos aproveitar e nos divertir com o braço robótico.
Aqui está o código completo do Braço Robótico Arduino:
/* DIY Braço Robótico Arduino Controle Smartphone por Dejan, www.HowToMechatronics.com */ #include <SoftwareSerial.h> #include <Servo.h> Servo servo01; Servo servo02; Servo servo03; Servo servo04; Servo servo05; Servo servo06; SoftwareSerial Bluetooth(3, 4); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX) int servo1Pos, servo2Pos, servo3Pos, servo4Pos, servo5Pos, servo6Pos; // posição atual int servo1PPos, servo2PPos, servo3PPos, servo4PPos, servo5PPos, servo6PPos; // posição anterior int servo01SP[50], servo02SP[50], servo03SP[50], servo04SP[50], servo05SP[50], servo06SP[50]; // para armazenar posições/passos int speedDelay = 20; int index = 0; String dataIn = ""; void setup() { servo01.attach(5); servo02.attach(6); servo03.attach(7); servo04.attach(8); servo05.attach(9); servo06.attach(10); Bluetooth.begin(38400); // Taxa de baud padrão do módulo Bluetooth Bluetooth.setTimeout(1); delay(20); // Posição inicial do braço robótico servo1PPos = 90; servo01.write(servo1PPos); servo2PPos = 150; servo02.write(servo2PPos); servo3PPos = 35; servo03.write(servo3PPos); servo4PPos = 140; servo04.write(servo4PPos); servo5PPos = 85; servo05.write(servo5PPos); servo6PPos = 80; servo06.write(servo6PPos); } void loop() { // Verifica dados de entrada if (Bluetooth.available() > 0) { dataIn = Bluetooth.readString(); // Lê os dados como string // Se slider "Base" mudou valor - Move Servo 1 para posição if (dataIn.startsWith("s1")) { String dataInS = dataIn.substring(2, dataIn.length()); // Extrai apenas o número. Ex: de "s1120" para "120" servo1Pos = dataInS.toInt(); // Converte string em inteiro // Usamos loops for para controlar velocidade do servo // Se posição anterior maior que atual if (servo1PPos > servo1Pos) { for ( int j = servo1PPos; j >= servo1Pos; j--) { // Move servo para baixo servo01.write(j); delay(20); // define velocidade do servo } } // Se posição anterior menor que atual if (servo1PPos < servo1Pos) { for ( int j = servo1PPos; j <= servo1Pos; j++) { // Move servo para cima servo01.write(j); delay(20); } } servo1PPos = servo1Pos; // define posição atual como anterior } // Move Servo 2 if (dataIn.startsWith("s2")) { String dataInS = dataIn.substring(2, dataIn.length()); servo2Pos = dataInS.toInt(); if (servo2PPos > servo2Pos) { for ( int j = servo2PPos; j >= servo2Pos; j--) { servo02.write(j); delay(50); } } if (servo2PPos < servo2Pos) { for ( int j = servo2PPos; j <= servo2Pos; j++) { servo02.write(j); delay(50); } } servo2PPos = servo2Pos; } // Move Servo 3 if (dataIn.startsWith("s3")) { String dataInS = dataIn.substring(2, dataIn.length()); servo3Pos = dataInS.toInt(); if (servo3PPos > servo3Pos) { for ( int j = servo3PPos; j >= servo3Pos; j--) { servo03.write(j); delay(30); } } if (servo3PPos < servo3Pos) { for ( int j = servo3PPos; j <= servo3Pos; j++) { servo03.write(j); delay(30); } } servo3PPos = servo3Pos; } // Move Servo 4 if (dataIn.startsWith("s4")) { String dataInS = dataIn.substring(2, dataIn.length()); servo4Pos = dataInS.toInt(); if (servo4PPos > servo4Pos) { for ( int j = servo4PPos; j >= servo4Pos; j--) { servo04.write(j); delay(30); } } if (servo4PPos < servo4Pos) { for ( int j = servo4PPos; j <= servo4Pos; j++) { servo04.write(j); delay(30); } } servo4PPos = servo4Pos; } // Move Servo 5 if (dataIn.startsWith("s5")) { String dataInS = dataIn.substring(2, dataIn.length()); servo5Pos = dataInS.toInt(); if (servo5PPos > servo5Pos) { for ( int j = servo5PPos; j >= servo5Pos; j--) { servo05.write(j); delay(30); } } if (servo5PPos < servo5Pos) { for ( int j = servo5PPos; j <= servo5Pos; j++) { servo05.write(j); delay(30); } } servo5PPos = servo5Pos; } // Move Servo 6 if (dataIn.startsWith("s6")) { String dataInS = dataIn.substring(2, dataIn.length()); servo6Pos = dataInS.toInt(); if (servo6PPos > servo6Pos) { for ( int j = servo6PPos; j >= servo6Pos; j--) { servo06.write(j); delay(30); } } if (servo6PPos < servo6Pos) { for ( int j = servo6PPos; j <= servo6Pos; j++) { servo06.write(j); delay(30); } } servo6PPos = servo6Pos; } // Se botão "SALVAR" é pressionado if (dataIn.startsWith("SAVE")) { servo01SP[index] = servo1PPos; // salva posição no array servo02SP[index] = servo2PPos; servo03SP[index] = servo3PPos; servo04SP[index] = servo4PPos; servo05SP[index] = servo5PPos; servo06SP[index] = servo6PPos; index++; // Aumenta índice do array } // Se botão "EXECUTAR" é pressionado if (dataIn.startsWith("RUN")) { runservo(); // Modo automático - executa passos salvos } // Se botão "RESET" é pressionado if ( dataIn == "RESET") { memset(servo01SP, 0, sizeof(servo01SP)); // Limpa dados do array para 0 memset(servo02SP, 0, sizeof(servo02SP)); memset(servo03SP, 0, sizeof(servo03SP)); memset(servo04SP, 0, sizeof(servo04SP)); memset(servo05SP, 0, sizeof(servo05SP)); memset(servo06SP, 0, sizeof(servo06SP)); index = 0; // Índice para 0 } } } // Função personalizada modo automático - executa passos salvos void runservo() { while (dataIn != "RESET") { // Executa passos repetidamente até botão "RESET" ser pressionado for (int i = 0; i <= index - 2; i++) { // Percorre todos os passos(index) if (Bluetooth.available() > 0) { // Verifica dados de entrada dataIn = Bluetooth.readString(); if ( dataIn == "PAUSE") { // Se botão "PAUSAR" é pressionado while (dataIn != "RUN") { // Espera até "EXECUTAR" ser pressionado novamente if (Bluetooth.available() > 0) { dataIn = Bluetooth.readString(); if ( dataIn == "RESET") { break; } } } } // Se slider de velocidade é alterado if (dataIn.startsWith("ss")) { String dataInS = dataIn.substring(2, dataIn.length()); speedDelay = dataInS.toInt(); // Muda velocidade do servo (tempo de delay) } } // Servo 1 if (servo01SP[i] == servo01SP[i + 1]) { } if (servo01SP[i] > servo01SP[i + 1]) { for ( int j = servo01SP[i]; j >= servo01SP[i + 1]; j--) { servo01.write(j); delay(speedDelay); } } if (servo01SP[i] < servo01SP[i + 1]) { for ( int j = servo01SP[i]; j <= servo01SP[i + 1]; j++) { servo01.write(j); delay(speedDelay); } } // Servo 2 if (servo02SP[i] == servo02SP[i + 1]) { } if (servo02SP[i] > servo02SP[i + 1]) { for ( int j = servo02SP[i]; j >= servo02SP[i + 1]; j--) { servo02.write(j); delay(speedDelay); } } if (servo02SP[i] < servo02SP[i + 1]) { for ( int j = servo02SP[i]; j <= servo02SP[i + 1]; j++) { servo02.write(j); delay(speedDelay); } } // Servo 3 if (servo03SP[i] == servo03SP[i + 1]) { } if (servo03SP[i] > servo03SP[i + 1]) { for ( int j = servo03SP[i]; j >= servo03SP[i + 1]; j--) { servo03.write(j); delay(speedDelay); } } if (servo03SP[i] < servo03SP[i + 1]) { for ( int j = servo03SP[i]; j <= servo03SP[i + 1]; j++) { servo03.write(j); delay(speedDelay); } } // Servo 4 if (servo04SP[i] == servo04SP[i + 1]) { } if (servo04SP[i] > servo04SP[i + 1]) { for ( int j = servo04SP[i]; j >= servo04SP[i + 1]; j--) { servo04.write(j); delay(speedDelay); } } if (servo04SP[i] < servo04SP[i + 1]) { for ( int j = servo04SP[i]; j <= servo04SP[i + 1]; j++) { servo04.write(j); delay(speedDelay); } } // Servo 5 if (servo05SP[i] == servo05SP[i + 1]) { } if (servo05SP[i] > servo05SP[i + 1]) { for ( int j = servo05SP[i]; j >= servo05SP[i + 1]; j--) { servo05.write(j); delay(speedDelay); } } if (servo05SP[i] < servo05SP[i + 1]) { for ( int j = servo05SP[i]; j <= servo05SP[i + 1]; j++) { servo05.write(j); delay(speedDelay); } } // Servo 6 if (servo06SP[i] == servo06SP[i + 1]) { } if (servo06SP[i] > servo06SP[i + 1]) { for ( int j = servo06SP[i]; j >= servo06SP[i + 1]; j--) { servo06.write(j); delay(speedDelay); } } if (servo06SP[i] < servo06SP[i + 1]) { for ( int j = servo06SP[i]; j <= servo06SP[i + 1]; j++) { servo06.write(j); delay(speedDelay); } } } } }
Gostei deste vídeo e aprendi algo novo. Sinta-se à vontade para fazer qualquer pergunta na seção de comentários abaixo e confira minha Coleção de Projetos Arduino.
Processo de manufatura
- Mealheiro Inteligente: Controlar Aceitador de Moedas com Arduino Nano
- Construa um Voltímetro Inteligente com Arduino e Smartphone – Projeto DIY Fácil
- Controle IoT Remoto de Braço Robótico Personalizado
- Robô Desviador de Obstáculos com Servo: Construa com Arduino e HC-SR04
- Controlar um LED via Bluetooth com Arduino – Guia DIY Simples
- Braço Robótico 6 GDL Controlado por Nunchuk com Arduino Mega
- Controle Dois Motores de Passo com Arduino Nano e Joystick – Tutorial Simples
- MobBob: Construa Seu Próprio Robô Arduino, Controlado via Smartphone Android
- LittleArm 2C: Braço Robótico Arduino 3D-Printado Durável para Educação STEM
- Yama Seiki GA-2000CR: Centro de Torneamento Compacto com Braço Robótico e Sistema de Paletes Avançado