Controle Perfeito de Braço Robótico Arduino com Plataforma Mecanum
Neste tutorial, mostrarei como fiz minha Plataforma Robótica com Rodas Mecanum do vídeo anterior funcionar em conjunto e operar automaticamente com meu Braço Robótico impresso em 3D, também um projeto Arduino de um dos meus vídeos anteriores.
Você pode assistir ao vídeo a seguir ou ler o tutorial escrito abaixo.
Visão Geral
Então, podemos controlar o robô com rodas Mecanum com o aplicativo Android personalizado da mesma forma que foi explicado no vídeo anterior. Além disso, agora o aplicativo também tem botões para controlar o braço robótico.

O aplicativo original de controle do braço robótico na verdade tinha sliders para controlar as juntas do robô, mas isso estava causando alguns problemas com a estabilidade do braço. Desta forma, o braço funciona muito melhor, portanto fornecerei esta versão atualizada do aplicativo de controle do braço robótico e o código Arduino para o projeto original do braço robótico também.
No entanto, a funcionalidade mais legal deste robô é a capacidade de armazenar os movimentos e depois repeti-los automaticamente.

Usando o botão Salvar, podemos simplesmente armazenar as posições dos motores para cada passo. Então, só precisamos clicar no botão Executar e o robô repetirá automaticamente os movimentos armazenados vezes sem conta.
Construção do Robô Arduino
Ok, então aqui tenho a plataforma com rodas Mecanum já montada e você pode encontrar todos os detalhes sobre ela no meu vídeo anterior.

Também aqui tenho as peças impressas em 3D do braço robótico e os motores servo e agora vou mostrar como montá-los. Aqui está o modelo 3D deste projeto.

Você pode encontrar e baixar este modelo 3D, bem como explorá-lo no seu navegador no Thangs.

Baixe o modelo 3D no Thangs.
Arquivos STL para impressão 3D:
O primeiro servo do braço robótico será montado diretamente na tampa superior da plataforma de rodas Mecanum.
Marquei a localização e, usando uma broca de 10mm, fiz vários furos.

Então, usando uma lima, cortei através dos furos e ajustei a abertura para o servo. Fixei o servo na placa superior usando quatro parafusos e porcas M3.

Então, no eixo de saída deste servo, usando a chaveta redonda que vem como acessório com o servo, precisamos fixar a próxima peça ou a cintura do braço robótico. No entanto, podemos notar que, desta forma, a peça fica cerca de 8mm acima da placa. Portanto, fixei duas peças de placas MDF de 8mm, para que a peça da cintura possa deslizar sobre elas e assim a junta ficará mais estável.

A chaveta redonda é fixada à peça da cintura usando os parafusos auto-roscantes que vêm como acessórios com o servo, e então a chaveta redonda é fixada ao eixo do servo usando os parafusos apropriados que também vêm com o servo.

Em seguida, temos o servo do ombro. Simplesmente o colocamos no lugar e o fixamos à peça impressa em 3D usando parafusos auto-roscantes.

A chaveta redonda vai na próxima peça, e então as duas peças são fixadas uma à outra usando um parafuso no eixo de saída do servo.

Devemos notar que, antes de fixar as peças, precisamos garantir que a peça tenha amplitude total de movimento. Aqui também adicionei uma borracha na junta do ombro para que dê uma pequena ajuda ao servo, porque este servo carrega o peso do resto do braço, bem como a carga útil.

De forma similar, montei o resto do braço robótico.

Em seguida, precisamos montar o mecanismo da garra. A garra é controlada com um motor servo SG90, no qual, primeiro fixamos um link engrenado personalizado. Emparelhamos este link com outro link engrenado no outro lado, que é fixado usando parafuso e porcas M4. Na verdade, todos os outros links são conectados usando parafusos e porcas M4.

O modelo 3D da garra originalmente tem furos de 3mm, mas não tinha parafusos M3 suficientes, então alarguei os furos usando broca de 4mm e usei parafusos M4 em vez disso.
Uma vez montado o mecanismo da garra, fixei-o ao último servo e assim o braço robótico foi completado.

Em seguida, fiz algum gerenciamento de cabos. Passei os fios dos servos através dos furos especificamente projetados no braço robótico. Usando uma broca de 10mm, fiz um furo na placa superior para que os fios possam passar.

Usando uma abraçadeira, fixei todos os fios juntos, e agora o que resta é conectá-los à placa Arduino.
Diagrama de Circuito do Robô Arduino
Aqui está o diagrama de circuito deste projeto e como tudo precisa ser conectado.

Você pode obter os componentes necessários para este projeto nos links abaixo:
- Motor de Passo – NEMA 17 ………………..
- Driver de Passo DRV8825 ……….…….…
- Motor Servo MG996R………………….….
- Micro Servo SG90 …………….….
- Módulo Bluetooth HC-05 …………….…
- Bateria Li-Po …………………………….……
- Placa Arduino Mega ………….……….…
No tutorial anterior, expliquei como funciona a parte do robô com rodas Mecanum e também mostrei como fiz uma PCB personalizada para ele.

Incluí um regulador de tensão de 5V nesta PCB para que possamos fazer este projeto, ou conectar os motores servo porque eles funcionam a 5V. O regulador de tensão é o LM350, que pode lidar com até 3 amps de corrente. Todos os seis servos do braço robótico podem consumir de cerca de 2 a 3 amps de corrente, o que significa que ele pode lidar com eles, mas isso fará o regulador ficar muito quente.

Portanto, fixei um dissipador de calor a ele, bem como um pequeno ventilador DC de 12V para soprar ar, porque o dissipador sozinho não era suficiente para resfriar o regulador.
Conectei os fios de sinal dos servos aos pinos digitais do Arduino do número 5 a 10, e para alimentação usei o header de pinos de 5V na PCB. Finalmente, empurrei todos os fios para dentro da plataforma e fixei a placa superior a ela usando as duas porcas.

E pronto, agora terminamos com este projeto.

Código Arduino
O que resta é dar uma olhada em como o código Arduino e o aplicativo Android funcionam. Como o código é um pouco longo, para melhor entendimento, 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 definir os 6 servos, os 4 motores de passo e a comunicação Bluetooth, bem como definir algumas variáveis necessárias para o programa abaixo. Na seção setup, definimos a velocidade máxima dos steppers, definimos os pinos aos quais os servos estão conectados, iniciamos a comunicação Bluetooth e posicionamos o braço robótico na posição inicial.
#include <SoftwareSerial.h> #include <AccelStepper.h> #include <Servo.h> Servo servo01; Servo servo02; Servo servo03; Servo servo04; Servo servo05; Servo servo06; SoftwareSerial Bluetooth(A8, 38); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX) // Define os motores de passo e os pinos que eles usarão AccelStepper LeftBackWheel(1, 42, 43); // (Tipo:driver, STEP, DIR) - Stepper1 AccelStepper LeftFrontWheel(1, 40, 41); // Stepper2 AccelStepper RightBackWheel(1, 44, 45); // Stepper3 AccelStepper RightFrontWheel(1, 46, 47); // Stepper4 #define led 14 int wheelSpeed = 1500; int lbw[50], lfw[50], rbw[50], rfw[50]; // arrays para armazenar posições/passos 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; int dataIn; int m = 0; void setup() { // Define valores iniciais para os steppers LeftFrontWheel.setMaxSpeed(3000); LeftBackWheel.setMaxSpeed(3000); RightFrontWheel.setMaxSpeed(3000); RightBackWheel.setMaxSpeed(3000); pinMode(led, OUTPUT); 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(5); delay(20); Serial.begin(38400); // Move o braço robótico para posição inicial servo1PPos = 90; servo01.write(servo1PPos); servo2PPos = 100; servo02.write(servo2PPos); servo3PPos = 120; servo03.write(servo3PPos); servo4PPos = 95; servo04.write(servo4PPos); servo5PPos = 60; servo05.write(servo5PPos); servo6PPos = 110; servo06.write(servo6PPos); }
Então, na seção loop, começamos verificando se há algum dado de entrada.
// Verifica dados de entrada if (Bluetooth.available() > 0) { dataIn = Bluetooth.read(); // Lê os dados
Esses dados vêm do smartphone ou do aplicativo Android, então vamos ver que tipo de dados ele está realmente enviando. O aplicativo Android é feito usando o aplicativo online MIT App Inventor. Consiste em botões simples que têm imagens apropriadas como fundo.

Se dermos uma olhada nos blocos do aplicativo, podemos ver que tudo o que ele faz é enviar números de um byte quando os botões são clicados.

Então, dependendo do botão clicado, dizemos ao Arduino o que fazer. Por exemplo, se recebermos o número '2', a plataforma de rodas Mecanum se moverá para frente, usando a função personalizada moveForward.
if (dataIn == 2) { m = 2; } // if (m == 2) { moveForward(); }
Esta função personalizada define todos os quatro motores de passo para girar para frente.
void moveForward() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(wheelSpeed); }
Para mover em qualquer outra direção, só precisamos girar as rodas nas direções apropriadas.
Para controlar o braço robótico, usamos o mesmo método. Novamente, temos botões no aplicativo e, ao segurar os botões, as juntas do braço robótico se movem na direção particular.

Como mencionei anteriormente, no aplicativo original de controle do Braço Robótico estávamos usando sliders para controlar as posições dos servos, mas isso estava causando alguns problemas porque, dessa forma, tínhamos que enviar Texto para o Arduino, em vez de número de 1 byte. O problema é que o Arduino às vezes perde o Texto vindo do App e comete erro ou o braço robótico treme e se comporta de forma anormal.
Desta forma, simplesmente enviamos um único número de 1 byte quando um botão particular é tocado (touch down).

O código Arduino entra no loop while daquele número e permanece lá até soltarmos o botão, porque nesse momento enviamos o número 0, que significa que o robô não deve fazer nada.
// Move servo 1 na direção positiva while (m == 16) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo01.write(servo1PPos); servo1PPos++; delay(speedDelay); } // Move servo 1 na direção negativa while (m == 17) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo01.write(servo1PPos); servo1PPos--; delay(speedDelay); }
Então, dependendo dos botões tocados, os servos se movem na direção positiva ou negativa. O mesmo princípio de funcionamento se aplica a todos os motores servo. Para alterar a velocidade de movimento, usamos os valores vindos do slider que variam de 100 a 250.
// Se slider de velocidade do braço é alterado if (dataIn > 101 & dataIn < 250) { speedDelay = dataIn / 10; // Altera velocidade do servo (tempo de delay) }
Dividindo-os por 10, obtemos valores de 10 a 25, que são usados como delay em microssegundos nos loops while para acionar os servos.
Para armazenar os movimentos do robô, simplesmente salvamos as posições atuais dos servos e dos steppers em arrays, cada vez que o botão Salvar é clicado.
// Se botão "SAVE" é pressionado if (m == 12) { //se for salvamento inicial, define posição dos steppers para 0 if (index == 0) { LeftBackWheel.setCurrentPosition(0); LeftFrontWheel.setCurrentPosition(0); RightBackWheel.setCurrentPosition(0); RightFrontWheel.setCurrentPosition(0); } lbw[index] = LeftBackWheel.currentPosition(); // salva posição no array lfw[index] = LeftFrontWheel.currentPosition(); rbw[index] = RightBackWheel.currentPosition(); rfw[index] = RightFrontWheel.currentPosition(); servo01SP[index] = servo1PPos; // salva posição no array servo02SP[index] = servo2PPos; servo03SP[index] = servo3PPos; servo04SP[index] = servo4PPos; servo05SP[index] = servo5PPos; servo06SP[index] = servo6PPos; index++; // Incrementa o índice do array m = 0; }
Então, quando pressionamos o botão Executar (Run), chamamos a função personalizada runSteps(). Esta função personalizada percorre todos os passos armazenados usando alguns loops for e while.
if (m == 14) { runSteps(); // Se botão "RESET" é pressionado if (dataIn != 14) { stopMoving(); memset(lbw, 0, sizeof(lbw)); // Limpa dados do array para 0 memset(lfw, 0, sizeof(lfw)); memset(rbw, 0, sizeof(rbw)); memset(rfw, 0, sizeof(rfw)); 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 } }
Devemos notar que ele começa da primeira posição e vai até a última posição, e repete isso vezes sem conta. Portanto, ao salvar os passos, na verdade precisamos posicionar o robô de forma que o primeiro passo tenha a mesma posição do último passo. Enquanto executa os passos, também podemos alterar a velocidade tanto da plataforma quanto do braço robótico, bem como pausar e reiniciar todos os passos.
Aqui você pode baixar este aplicativo, bem como o arquivo de projeto editável:
Aqui está o código Arduino completo para este projeto de robô Arduino:
/* Braço Robótico Arduino e Robô Rodas Mecanum Controle via Smartphone Bluetooth por Dejan, www.HowToMechatronics.com */ #include <SoftwareSerial.h> #include <AccelStepper.h> #include <Servo.h> Servo servo01; Servo servo02; Servo servo03; Servo servo04; Servo servo05; Servo servo06; SoftwareSerial Bluetooth(A8, 38); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX) // Define os motores de passo e os pinos que eles usarão AccelStepper LeftBackWheel(1, 42, 43); // (Tipo:driver, STEP, DIR) - Stepper1 AccelStepper LeftFrontWheel(1, 40, 41); // Stepper2 AccelStepper RightBackWheel(1, 44, 45); // Stepper3 AccelStepper RightFrontWheel(1, 46, 47); // Stepper4 #define led 14 int wheelSpeed = 1500; int lbw[50], lfw[50], rbw[50], rfw[50]; // arrays para armazenar posições/passos 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; int dataIn; int m = 0; void setup() { // Define valores iniciais para os steppers LeftFrontWheel.setMaxSpeed(3000); LeftBackWheel.setMaxSpeed(3000); RightFrontWheel.setMaxSpeed(3000); RightBackWheel.setMaxSpeed(3000); pinMode(led, OUTPUT); 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(5); delay(20); Serial.begin(38400); // Move o braço robótico para posição inicial servo1PPos = 90; servo01.write(servo1PPos); servo2PPos = 100; servo02.write(servo2PPos); servo3PPos = 120; servo03.write(servo3PPos); servo4PPos = 95; servo04.write(servo4PPos); servo5PPos = 60; servo05.write(servo5PPos); servo6PPos = 110; servo06.write(servo6PPos); } void loop() { // Verifica dados de entrada if (Bluetooth.available() > 0) { dataIn = Bluetooth.read(); // Lê os dados if (dataIn == 0) { m = 0; } if (dataIn == 1) { m = 1; } if (dataIn == 2) { m = 2; } if (dataIn == 3) { m = 3; } if (dataIn == 4) { m = 4; } if (dataIn == 5) { m = 5; } if (dataIn == 6) { m = 6; } if (dataIn == 7) { m = 7; } if (dataIn == 8) { m = 8; } if (dataIn == 9) { m = 9; } if (dataIn == 10) { m = 10; } if (dataIn == 11) { m = 11; } if (dataIn == 12) { m = 12; } if (dataIn == 14) { m = 14; } if (dataIn == 16) { m = 16; } if (dataIn == 17) { m = 17; } if (dataIn == 18) { m = 18; } if (dataIn == 19) { m = 19; } if (dataIn == 20) { m = 20; } if (dataIn == 21) { m = 21; } if (dataIn == 22) { m = 22; } if (dataIn == 23) { m = 23; } if (dataIn == 24) { m = 24; } if (dataIn == 25) { m = 25; } if (dataIn == 26) { m = 26; } if (dataIn == 27) { m = 27; } // Move a plataforma de rodas Mecanum if (m == 4) { moveSidewaysLeft(); } if (m == 5) { moveSidewaysRight(); } if (m == 2) { moveForward(); } if (m == 7) { moveBackward(); } if (m == 3) { moveRightForward(); } if (m == 1) { moveLeftForward(); } if (m == 8) { moveRightBackward(); } if (m == 6) { moveLeftBackward(); } if (m == 9) { rotateLeft(); } if (m == 10) { rotateRight(); } if (m == 0) { stopMoving(); } // Velocidade das rodas Mecanum if (dataIn > 30 & dataIn < 100) { wheelSpeed = dataIn * 20; } // Move braço robótico // Move servo 1 na direção positiva while (m == 16) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo01.write(servo1PPos); servo1PPos++; delay(speedDelay); } // Move servo 1 na direção negativa while (m == 17) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo01.write(servo1PPos); servo1PPos--; delay(speedDelay); } // Move servo 2 while (m == 19) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo02.write(servo2PPos); servo2PPos++; delay(speedDelay); } while (m == 18) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo02.write(servo2PPos); servo2PPos--; delay(speedDelay); } // Move servo 3 while (m == 20) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo03.write(servo3PPos); servo3PPos++; delay(speedDelay); } while (m == 21) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo03.write(servo3PPos); servo3PPos--; delay(speedDelay); } // Move servo 4 while (m == 23) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo04.write(servo4PPos); servo4PPos++; delay(speedDelay); } while (m == 22) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo04.write(servo4PPos); servo4PPos--; delay(speedDelay); } // Move servo 5 while (m == 25) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo05.write(servo5PPos); servo5PPos++; delay(speedDelay); } while (m == 24) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo05.write(servo5PPos); servo5PPos--; delay(speedDelay); } // Move servo 6 while (m == 26) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo06.write(servo6PPos); servo6PPos++; delay(speedDelay); } while (m == 27) { if (Bluetooth.available() > 0) { m = Bluetooth.read(); } servo06.write(servo6PPos); servo6PPos--; delay(speedDelay); } // Se slider de velocidade do braço é alterado if (dataIn > 101 & dataIn < 250) { speedDelay = dataIn / 10; // Altera velocidade do servo (tempo de delay) } // Se botão "SAVE" é pressionado if (m == 12) { //se for salvamento inicial, define posição dos steppers para 0 if (index == 0) { LeftBackWheel.setCurrentPosition(0); LeftFrontWheel.setCurrentPosition(0); RightBackWheel.setCurrentPosition(0); RightFrontWheel.setCurrentPosition(0); } lbw[index] = LeftBackWheel.currentPosition(); // salva posição no array lfw[index] = LeftFrontWheel.currentPosition(); rbw[index] = RightBackWheel.currentPosition(); rfw[index] = RightFrontWheel.currentPosition(); servo01SP[index] = servo1PPos; // salva posição no array servo02SP[index] = servo2PPos; servo03SP[index] = servo3PPos; servo04SP[index] = servo4PPos; servo05SP[index] = servo5PPos; servo06SP[index] = servo6PPos; index++; // Incrementa o índice do array m = 0; } // Se botão "RUN" é pressionado if (m == 14) { runSteps(); // Se botão "RESET" é pressionado if (dataIn != 14) { stopMoving(); memset(lbw, 0, sizeof(lbw)); // Limpa dados do array para 0 memset(lfw, 0, sizeof(lfw)); memset(rbw, 0, sizeof(rbw)); memset(rfw, 0, sizeof(rfw)); 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 } } } LeftFrontWheel.runSpeed(); LeftBackWheel.runSpeed(); RightFrontWheel.runSpeed(); RightBackWheel.runSpeed(); // Monitora tensão da bateria int sensorValue = analogRead(A0); float voltage = sensorValue * (5.0 / 1023.00) * 3; // Converte valores de leitura de 5v para 12V adequados //Serial.println(voltage); // Se tensão abaixo de 11V liga o LED if (voltage < 11) { digitalWrite(led, HIGH); } else { digitalWrite(led, LOW); } } void moveForward() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(wheelSpeed); } void moveBackward() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(-wheelSpeed); } void moveSidewaysRight() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(wheelSpeed); } void moveSidewaysLeft() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(-wheelSpeed); } void rotateLeft() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(wheelSpeed); } void rotateRight() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(-wheelSpeed); } void moveRightForward() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(0); RightFrontWheel.setSpeed(0); RightBackWheel.setSpeed(wheelSpeed); } void moveRightBackward() { LeftFrontWheel.setSpeed(0); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(0); } void moveLeftForward() { LeftFrontWheel.setSpeed(0); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(0); } void moveLeftBackward() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(0); RightFrontWheel.setSpeed(0); RightBackWheel.setSpeed(-wheelSpeed); } void stopMoving() { LeftFrontWheel.setSpeed(0); LeftBackWheel.setSpeed(0); RightFrontWheel.setSpeed(0); RightBackWheel.setSpeed(0); } // Função personalizada modo automático - executa passos salvos void runSteps() { while (dataIn != 13) { // Executa os passos vezes sem conta 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.read(); if ( dataIn == 15) { // Se botão "PAUSE" é pressionado while (dataIn != 14) { // Espera até "RUN" ser pressionado novamente if (Bluetooth.available() > 0) { dataIn = Bluetooth.read(); if ( dataIn == 13) { break; } } } } // Se slider de velocidade é alterado if (dataIn > 100 & dataIn < 150) { speedDelay = dataIn / 10; // Altera velocidade do servo (tempo de delay) } // Velocidade rodas Mecanum if (dataIn > 30 & dataIn < 100) { wheelSpeed = dataIn * 10; dataIn = 14; } } LeftFrontWheel.moveTo(lfw[i]); LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.moveTo(lbw[i]); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.moveTo(rfw[i]); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.moveTo(rbw[i]); RightBackWheel.setSpeed(wheelSpeed); while (LeftBackWheel.currentPosition() != lbw[i] & LeftFrontWheel.currentPosition() != lfw[i] & RightFrontWheel.currentPosition() != rfw[i] & RightBackWheel.currentPosition() != rbw[i]) { LeftFrontWheel.runSpeedToPosition(); LeftBackWheel.runSpeedToPosition(); RightFrontWheel.runSpeedToPosition(); RightBackWheel.runSpeedToPosition(); } // 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); } } } } }
Então, isso é praticamente tudo para este tutorial. O projeto funciona bem, mas por favor note que está longe de ser perfeito. Os movimentos automáticos podem não ser tão precisos devido ao deslizamento das rodas Mecanum, bem como ao desempenho ruim dos motores servo. Estes servos baratos também podem tremer ou trepidar mesmo quando não estão se movendo apenas porque não têm força suficiente para segurar o peso das peças impressas em 3D.
Espero que tenha gostado deste tutorial e aprendido 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
- Construa um Robô de Streaming de Vídeo Controlado por Internet com Arduino e Raspberry Pi
- Simple Pi Robot – Construa Rover Autônomo 2-WD com Raspberry Pi
- Robô Desviador de Obstáculos com Servo: Construa com Arduino e HC-SR04
- Controlar Roomba Create 2 com Arduino e Android: Guia Passo a Passo
- Arduino e MPU6050: Controle Preciso de Servomotores SG90 e MG996R
- Braço Robótico Inteligente Controlado por Arduino: Tutorial DIY Fácil
- LittleArm 2C: Braço Robótico Arduino 3D-Printado Durável para Educação STEM
- Braço Robótico Arduino Controlado por Gestos Manuais – Construção Passo a Passo
- Kit Braço Robótico 3 Eixos Programável – Controle Local e Remoto com Arduino e Bluetooth
- KUKA KMR iiwa: Braço Robótico Colaborativo Móvel para Indústria 4.0