Como fazer um robô de controle por gestos em casa
Componentes e suprimentos
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 |
Ferramentas e máquinas necessárias
| ||||
| ||||
| ||||
|
Aplicativos e serviços online
|
Sobre este projeto
É sobre como fazer você mesmo um carro controlado por gestos. Basicamente, esta é uma aplicação simples do Giroscópio de 3 eixos MPU-6050, Acelerômetro. Você pode fazer muito mais coisas. entendendo como usá-lo, como fazer a interface com o Arduino e como transferir seus dados pelos módulos Bluetooth. neste artigo, vou me concentrar na comunicação de Bluetooth para Bluetooth, entre dois módulos Bluetooth HC-05.
Siga o vídeo para construir um corpo de robô e conexões para este projeto.
diagrama de conexão para robô e unidade transmissora são fornecidos abaixo, você pode consultá-los.
Pedido direto de PCB usado neste projeto da PCBway:https://www.pcbway.com/project/shareproject/How_to_Make_Arduino_Based_Edge_Avoiding_Robot.html
Agora vamos falar sobre a configuração do módulo Bluetooth. basicamente, o módulo HC-05 Bluetooth vem com uma configuração de fábrica do módulo escravo. isso significa que podemos enviar dados para o módulo apenas conectando-o. não há necessidade de fazer nenhuma outra configuração para enviar dados de dispositivos móveis para o módulo HC-05. basta inserir sua senha padrão (1234/0000) para conectá-lo. mas e se quisermos enviar dados usando este módulo para algum outro mesmo módulo ou para um dispositivo móvel.
neste projeto, fazemos a mesma coisa enviando dados através do módulo Bluetooth. coletado pelo sensor giroscópio mpu-6050 para o outro módulo Bluetooth.
então, para fazer isso, primeiro precisamos configurar esses dois módulos Bluetooth. para que eles possam se ligar automaticamente após serem ligados. Aqui, o primeiro módulo atua como um dispositivo escravo, que receberá sinais da unidade remota e será montado no carro. E configure o segundo como um dispositivo mestre que atuará como unidades transmissoras e enviará dados para o dispositivo escravo,
Portanto, primeiro configure o primeiro módulo bluetooth como dispositivo escravo. para fazer isso, conecte-o ao Arduino de acordo com este diagrama de fiação.
E carregue o código por nome, configure.
#include
SoftwareSerial BTSerial (10, 11); // RX | TX
void setup ()
{
Serial.begin (9600);
Serial.println ("Inserir comandos AT:");
BTSerial.begin (38400 ); // Velocidade padrão do HC-05 no comando AT mais
}
void loop ()
{
// Continue lendo do HC-05 e envie para o Arduino Serial Monitor
if (BTSerial.available ())
Serial.write (BTSerial.read ());
// Continue lendo do Arduino Serial Monitor e envie para HC-05
if (Serial. disponível ())
BTSerial.write (Serial.read ());
}
Desconecte o módulo. Pressione e segure o ky no módulo e conecte-o de volta. Você verá que o led no módulo está piscando mais lentamente. Uma vez a cada 2 segundos. Isso significa que o HC-05 está no modo de comando AT. Agora abra o monitor serial, altere a taxa de transmissão para 9600 e o tipo de saída como NL e CR. Agora digite AT na caixa de envio e envie. se responder com ok, significa que está tudo bem. Mas se não, e responde com algum erro, Envie AT novamente. Até que ele responda com ok ou chek connections e envie AT novamente ...
depois de obter uma resposta correta do módulo, digite os seguintes comandos um por um,
AT + ORGL e envie. este comando irá definir o módulo na configuração de fábrica.
AT + RMAAD este comando irá liberar o módulo de qualquer emparelhamento anterior
AT + UART? verifique a taxa de transmissão atual do módulo
AT + UART =38400, 0, 0 definir a taxa de baud como 38400
AT + ROLE? verifique a função se é escravo ou mestre. ele responde com 0 ou 1. se o módulo for escravo, ele responde 0 e se for um dispositivo mestre, ele responderá com 1
definir o papel como um dispositivo escravo. insira AT + ROLE =0
AT + ADDR? verifique o endereço do módulo.
Anote este endereço. respondido por módulo. após obter este endereço, a configuração do módulo escravo é feita.
Agora é hora de configurar o segundo módulo Bluetooth como dispositivo mestre. Conecte este módulo com a placa Arduino e entre no modo AT. como fizemos com o anterior.
Insira esses comandos AT por determinada sequência.
AT + ORGL
AT + RMAAD
AT + UART?
AT + UART =38400, 0, 0
AT + ROLE?
defina a função deste módulo como o dispositivo mestre. AT + ROLE =1
AT + CMODE =0 para que o módulo conecte apenas um único dispositivo. configuração padrão é 0
agora ligue este módulo ao dispositivo escravo para fazer esta entrada,
AT + BIND ="o endereço do módulo escravo" e tudo feito
agora instale bibliotecas para sensor MPU-6050 e comunicação I2C. Já o sensor giroscópio MPU-6050 possui interface I2C. baixe bibliotecas e código-fonte aqui:http://www.mediafire.com/file/l8mru5emulb8x93/gesture_control_robot.rar/file
se você tiver pré-instalado essas bibliotecas, pule isto.
Agora conecte a unidade do carro ao PC usando um cabo USB. selecione a porta de comunicação e o tipo de placa corretos. E carregue o programa com o nome "Gesture_controled_Robot__car_unit_". Certifique-se de que a bateria e o módulo Bluetooth não estejam conectados ao carro enquanto carrega o programa.
// programa de Shubham Shinganapure em 3-10-2019
//
// para carro robótico controlado por gestos
int lm1 =8; // saída do motor esquerdo 1
int lm2 =9; // saída do motor esquerdo 2
int rm1 =10; // saída do motor direito 1
int rm2 =11; // saída do motor direito 2
char d =0;
void setup ()
{
pinMode (lm1, OUTPUT);
pinMode (lm2, OUTPUT);
pinMode (rm1, OUTPUT);
pinMode (rm2, OUTPUT);
Serial.begin (38400);
sTOP ();
}
void loop ()
{
if (Serial.available ()> 0)
{
d =Serial.read ();
if (d ==' F ')
{
ForWard ();
}
if (d ==' B ')
{
BackWard ();
}
if (d =='L')
{
Esquerda ();
}
if (d =='R')
{
Direita ();
}
if (d =='S')
{
sTOP ();
}
}
}
void ForWard ()
{
digitalWrite (lm1, HIGH);
digitalWrite (lm2, LOW);
digitalWrite (rm1, HIGH);
digitalWrite (rm2, LOW);
}
vazio BackWard ()
{
digitalWrite (lm1, LOW);
digitalWrite (lm2, HIGH) );
digitalWrite (rm1, LOW);
digitalWrite (rm2, HIGH);
}
void Left ()
{
digitalWrite (lm1, LOW);
digitalWrite (lm2, HIGH);
digitalWrite (rm1, HIGH);
digitalWrite (rm2, LOW);
}
void Right ()
{
digitalWrite (lm1, HIGH);
digitalWrite (lm2, LOW);
digitalWrite (rm1, LOW);
digitalWrite (rm2, HIGH);
}
void sTOP ()
{
digitalWrite (lm1, LOW);
digitalWrite (lm2, LOW);
digitalWrite (rm1, LOW);
digitalWrite ( rm2, LOW);
}
Faça o mesmo com a unidade remota. programa aberto por nome remoto. e carregue-o na unidade remota.
// programa modificado em 3/10/19 por // por Shubham Shinganapure.
//
// para carro robótico controlado por gestos (remoto)
#include " I2Cdev.h "
#include" MPU6050_6Axis_MotionApps20.h "
// # include" MPU6050.h "// não é necessário se usar MotionApps incluir arquivo
// A biblioteca Arduino Wire é necessária se I2Cdev Implementação de I2CDEV_ARDUINO_WIRE
// é usado em I2Cdev.h
#if I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
// padrão de classe I2C endereço é 0x68
// endereços I2C específicos podem ser passados como um parâmetro aqui
// AD0 baixo =0x68 (padrão para quebra de SparkFun e placa de avaliação InvenSense)
// AD0 alto =0x69
MPU6050 mpu;
#define OUTPUT_READABLE_YAWPITCHROLL
// Vars de controle / status de MPU
bool dmpReady =false; // define verdadeiro se a inicialização DMP foi bem-sucedida
uint8_t mpuIntStatus; // mantém o byte de status de interrupção real do MPU
uint8_t devStatus; // retorna o status após cada operação do dispositivo (0 =sucesso,! 0 =erro)
uint16_t packetSize; // tamanho do pacote DMP esperado (o padrão é 42 bytes)
uint16_t fifoCount; // contagem de todos os bytes atualmente em FIFO
uint8_t fifoBuffer [64]; // buffer de armazenamento FIFO
VectorFloat gravity;
Quaternion q;
float ypr [3]; // [yaw, pitch, roll] yaw / pitch / roll container e vetor de gravidade
uint8_t teapotPacket [14] ={'$', 0x02, 0,0, 0,0, 0,0, 0,0 , 0x00, 0x00, '\ r', '\ n'};
bool volátil mpuInterrupt =false; // indica se o pino de interrupção MPU ficou alto
void dmpDataReady () {
mpuInterrupt =true;
}
#include
SoftwareSerial BTSerial ( 10, 11); // RX | TX
int bt =8;
int x =1;
configuração void () {
#if I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE
Wire.begin ();
TWBR =24; // Clock I2C de 400 kHz (200 kHz se CPU for 8 MHz)
#elif I2CDEV_IMPLEMENTATION ==I2CDEV_BUILTIN_FASTWIRE
Fastwire ::setup (400, true);
#endif
// inicializar serial comunicação
// (115200 escolhido porque é necessário para a saída do Teapot Demo, mas é
// realmente depende de você dependendo do seu projeto)
Serial.begin (115200);
BTSerial.begin (38400);
// while (! Serial); // aguarde a enumeração de Leonardo, outros continuam imediatamente
Serial.println (F ("Inicializando dispositivos I2C ..."));
mpu.initialize ();
// verifique a conexão
Serial.println(F("Testing device connections ... "));
Serial.println (mpu.testConnection ()? F (" MPU6050 connection bem-sucedida "):F (" MPU6050 connection failed " ));
// aguarde pronto
// carregue e configure o DMP
Serial.println (F ("Inicializando DMP ..."));
devStatus =mpu .dmpInitialize ();
// fornece seus próprios deslocamentos giroscópios aqui, escalados para sensibilidade mínima
mpu.setXGyroOffset (220);
mpu.setYGyroOffset (76);
mpu. setZGyroOffset (-85);
mpu.setZAccelOffset (1788);
// certifique-se de que funcionou (retorna 0 se assim for)
if (devStatus ==0) {
/ / ligar o DMP, agora que está pronto
Serial.println (F ("Ativando DMP ..."));
mpu.setDMPEnabled (true);
// ativar a interrupção do Arduino detecção
Serial.println (F ("Habilitando a detecção de interrupção (interrupção externa do Arduino 0) ..."));
a ttachInterrupt (0, dmpDataReady, RISING);
mpuIntStatus =mpu.getIntStatus ();
// definir nosso sinalizador DMP Ready para que a função loop () principal saiba que está tudo bem para usá-lo
Serial .println (F ("DMP pronto! Aguardando a primeira interrupção ... "));
dmpReady =true;
// obter o tamanho do pacote DMP esperado para comparação posterior
packetSize =mpu.dmpGetFIFOPacketSize ();
} else {
// ERROR!
// 1 =carregamento de memória inicial falhou
// 2 =atualizações de configuração DMP falhou
// (se vai quebrar, geralmente o código será 1)
Serial.print (F ("Falha na inicialização do DMP (código"));
Serial.print (devStatus);
Serial.println (F (")"));
}
// configurar LED para saída
pinMode (bt, INPUT);
}
// ========================================================================
// ===PROGRAMA PRINCIPAL LOOP ===
// ==========================================================================
void loop () {
if (digitalRead (bt) ==HIGH)
{
x ++;
delay (150);
}
if ((x% 2) ==0) {
// se a programação falhou, não tente fazer nada
if (! dmpReady) return;
// aguarde a interrupção do MPU ou pacote (s) extra disponível (s)
while (! mpuInterrupt &&fifoCount // outras coisas de comportamento de programa aqui
//.
//.
//.
// se você for realmente paranóico, você pode testar com frequência entre outras
// coisas para ver se mpuInterrupt é verdadeiro, e se for, "break;" do
// loop while () para processar imediatamente os dados MPU
//.
//.
//.
}
// redefinir sinalizador de interrupção e obter byte INT_STATUS
mpuInterrupt =false;
mpuIntStatus =mpu.getIntStatus ( );
// obter a contagem FIFO atual
fifoCount =mpu.getFIFOCount ();
// verificar o estouro (isso nunca deve acontecer a menos que nosso código seja muito ineficiente)
se ((mpuIntStatus &0x10) || fifoCount ==1024) {
// redefinir para que possamos continuar de forma limpa
mpu.resetFIFO ();
Serial.println (F ("FIFO overflow!"));
// caso contrário, verifique a interrupção dos dados DMP (isso deve acontecer com frequência)
} else if (mpuIntStatus &0x02) {
// aguarde o comprimento correto dos dados disponíveis, deve ser uma espera MUITO curta
while (fifoCount // ler um pacote de FIFO
mpu.getFIFOBytes (fifoBuffer, packetSize);
// rastrear a contagem de FIFO aqui caso haja> 1 pacote disponível
// (isso nos permite ler imediatamente mais sem esperar por uma interrupção)
fifoCount - =tamanho do pacote;
#ifdef OUTPUT_READABLE_YAWPITCHROLL
// display Ângulos de Euler em graus
mpu.dmpGetQuaternion (&q, fifoBuffer);
mpu.dmpGetGravity (&gravity, &q);
mpu.dmpGetYawPitchRoll (ypr, &q, &gravity);
Serial .print ("ypr \ t");
Serial.print (ypr [0] * 180 / M_PI);
Serial.print ("\ t");
Serial.print ( ypr [1] * 180 / M_PI);
Serial .print ("\ t");
Serial.println (ypr [2] * 180 / M_PI);
if ((ypr [1] * 180 / M_PI) <=-25)
{BTSerial.write('F ');
}
else if ((ypr [1] * 180 / M_PI)> =25)
{BTSerial.write (' B ' );
}
else if ((ypr [2] * 180 / M_PI) <=-25)
{BTSerial.write('L ');
}
else if ((ypr [2] * 180 / M_PI)> =20)
{BTSerial.write ('R');
}
else {
BTSerial. write ('S');
}
#endif
}
}
else {
BTSerial.write ('S');
}
}
Insira o módulo Bluetooth escravo na unidade do carro e domine o módulo Bluetooth na unidade remota. E tudo pronto.
Vamos ligá-lo e ele está pronto para jogar …….
Espero que você ache isso útil. se sim, goste, compartilhe, comente sua dúvida. Para mais projetos desse tipo, siga-me! Apoie meu trabalho e inscreva-se em Meu canal no YouTube.
Obrigada!
Código
- Robô controlado por gestos (unidade remota)
Robô controlado por gestos (unidade remota) Arduino
// programa modificado em 3/10/19 por // por Shubham Shinganapure. //// para carro robótico controlado por gestos (remoto) #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" // # include "MPU6050.h" // não é necessário se usar o arquivo de inclusão MotionApps // a biblioteca Arduino Wire é obrigatório se a implementação I2Cdev I2CDEV_ARDUINO_WIRE // for usada em I2Cdev.h # se I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE #include "Wire.h" # endif // o endereço I2C padrão da classe é 0x68 // endereços I2C específicos podem ser passados como um parâmetro aqui // AD0 baixo =0x68 (padrão para SparkFun breakout e placa de avaliação InvenSense) // AD0 alto =0x69MPU6050 mpu; #define OUTPUT_READABLE_YAWPITCHROLL // Controle / status MPU varsbool dmpReady =false; // define verdadeiro se a inicialização DMP foi bem-sucedidauint8_t mpuIntStatus; // mantém o byte de status de interrupção real de MPUuint8_t devStatus; // retorna o status após cada operação do dispositivo (0 =sucesso,! 0 =erro) uint16_t packetSize; // tamanho do pacote DMP esperado (o padrão é 42 bytes) uint16_t fifoCount; // contagem de todos os bytes atualmente em FIFOuint8_t fifoBuffer [64]; // buffer de armazenamento FIFOVectorFloat gravity; Quaternion q; float ypr [3]; // [yaw, pitch, roll] yaw / pitch / roll container e gravidade vectoruint8_t teapotPacket [14] ={'$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\ r', '\ n'}; volátil bool mpuInterrupt =false; // indica se o pino de interrupção MPU foi ativado dmpDataReady () {mpuInterrupt =true;} # includeSoftwareSerial BTSerial (10, 11); // RX | TXint bt =8; int x =1; void setup () {#if I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE Wire.begin (); TWBR =24; // Clock I2C de 400kHz (200kHz se CPU for 8MHz) #elif I2CDEV_IMPLEMENTATION ==I2CDEV_BUILTIN_FASTWIRE Fastwire ::setup (400, true); #endif // inicializar a comunicação serial // (115200 escolhido porque é necessário para a saída do Teapot Demo, mas // realmente depende de você dependendo do seu projeto) Serial.begin (115200); BTSerial.begin (38400); // while (! Serial); // aguarde a enumeração de Leonardo, outros continuam imediatamenteSerial.println (F ("Inicializando dispositivos I2C ...")); mpu.initialize (); // verificar a conexão Serial.println (F ("Testing device connections ...")); Serial.println (mpu.testConnection ()? F ("MPU6050 conexão bem-sucedida"):F ("MPU6050 conexão falhou")); // aguarde o pronto // carregue e configure o DMP Serial.println (F ("Inicializando DMP ...")); devStatus =mpu.dmpInitialize (); // forneça seus próprios offsets de giroscópio aqui, escalonados para sensibilidade mínima mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1788); // certifique-se de que funcionou (retorna 0 em caso afirmativo) if (devStatus ==0) {// liga o DMP, agora que está pronto Serial.println (F ("Ativando DMP ...")); mpu.setDMPEnabled (true); // habilita a detecção de interrupção do Arduino Serial.println (F ("Habilitando a detecção de interrupção (interrupção externa do Arduino 0) ...")); attachInterrupt (0, dmpDataReady, RISING); mpuIntStatus =mpu.getIntStatus (); // define nosso sinalizador DMP Ready para que a função loop () principal saiba que está tudo bem em usá-lo Serial.println (F ("DMP pronto! Aguardando a primeira interrupção ...")); dmpReady =true; // obtém o tamanho do pacote DMP esperado para comparação posterior packetSize =mpu.dmpGetFIFOPacketSize (); } else {// ERROR! // 1 =falha no carregamento inicial da memória // 2 =falha nas atualizações de configuração do DMP // (se houver falha, normalmente o código será 1) Serial.print (F ("Falha na inicialização do DMP (código")); Serial. imprimir (devStatus); Serial.println (F (")")); } // configura o LED para saída pinMode (bt, INPUT); } // ======================================================================// ===PROGRAMA PRINCIPAL LOOP ===// ======================================================================void loop () {if (leitura digital (bt) ==ALTO) {x ++; atraso (150); } if ((x% 2) ==0) {// se a programação falhou, não tente fazer nada if (! dmpReady) return; // aguarde a interrupção do MPU ou pacote (s) extra (s) disponíveis enquanto (! mpuInterrupt &&fifoCount 1 pacote disponível // (isso nos permite ler imediatamente mais sem esperar por uma interrupção) fifoCount - =packetSize; #ifdef OUTPUT_READABLE_YAWPITCHROLL // exibe ângulos de Euler em graus mpu.dmpGetQuaternion (&q, fifoBuffer); mpu.dmpGetGravity (&gravity, &q); mpu.dmpGetYawPitchRoll (ypr, &q, &gravity); Serial.print ("ypr \ t"); Serial.print (ypr [0] * 180 / M_PI); Serial.print ("\ t"); Serial.print (ypr [1] * 180 / M_PI); Serial.print ("\ t"); Serial.println (ypr [2] * 180 / M_PI); if ((ypr [1] * 180 / M_PI) <=-25) {BTSerial.write ('F'); } else if ((ypr [1] * 180 / M_PI)> =25) {BTSerial.write ('B'); } else if ((ypr [2] * 180 / M_PI) <=-25) {BTSerial.write ('L'); } else if ((ypr [2] * 180 / M_PI)> =20) {BTSerial.write ('R'); } else {BTSerial.write ('S'); } #endif}} else {BTSerial.write ('S'); }}
Esquemas
Processo de manufatura
- Como fazer uma plataforma de robô Arduino + Raspberry Pi
- Faça uma máquina de escrever trabalhos de casa DIY em casa
- Obstáculos para evitar o robô com servo motor
- Robô seguidor de linha
- Como fazer um botão de teclado punível personalizável
- Robô assistente autônomo da casa
- Como fazer música com um Arduino
- Como fazer a abertura automática de porta baseada no Arduino
- Controlar Arduino Robot Arm com aplicativo Android
- Robô para navegação interna supercool