Índice:

Controle remoto hackeável para Microcarro ZenWheels: 7 etapas
Controle remoto hackeável para Microcarro ZenWheels: 7 etapas

Vídeo: Controle remoto hackeável para Microcarro ZenWheels: 7 etapas

Vídeo: Controle remoto hackeável para Microcarro ZenWheels: 7 etapas
Vídeo: Миниатюрная радиоуправляемая машинка для iPhone и Android — ZenWheels 2024, Novembro
Anonim
Image
Image
conjunto
conjunto

Neste tutorial, vamos construir um controle remoto personalizado para o microcarro ZenWheels. O microcar ZenWheels é um carrinho de brinquedo de 5 cm que pode ser controlado através de um aplicativo Android ou Iphone. Vou mostrar como fazer a engenharia reversa do aplicativo Android para descobrir mais sobre o protocolo de comunicação e como construir um controle remoto usando arduino e um giroscópio.

Etapa 1: Componentes e ferramentas

Partes:

1. O microcarro ZenWheels

2. Arduino pro mini 328p

3. Placa de ensaio

4. Giroscópio MPU6050

5. fonte de alimentação <= 5 v (alguma bateria que podemos anexar à placa de ensaio)

6. Cabos de ligação em U (opcional). Usei esses cabos jumper porque eles ficam melhores na placa de ensaio. Cabos de jumper regulares podem ser usados em seu lugar

7. Módulo bluetooth HC-05 (com um botão para entrar no modo AT)

Ferramentas:

1. USB para adaptador FTDI serial FT232RL para programar o Arduino pro mini

2. Arduino IDE

3. Telefone Android

4. Android Studio [opcional]

Etapa 2: fazer engenharia reversa do aplicativo ZenWheels para Android [opcional]

Algum conhecimento de Java e Android é necessário para entender esta parte.

O objetivo do projeto é controlar o microcarro por meio de um giroscópio. Para isso, precisamos saber mais sobre a comunicação bluetooth entre este brinquedo e o aplicativo Android.

Nesta etapa, explicarei como fazer a engenharia reversa do protocolo de comunicação entre o microcarro e o aplicativo Android. Se você deseja apenas construir o controle remoto, esta etapa não é necessária. Uma maneira de descobrir o protocolo é examinar o código-fonte. Hmm, mas isso não é simples, os aplicativos Android são compilados e pode-se instalar o apk através do Google Play.

Então, eu fiz um guia básico para fazer isso:

1. Baixe o APK. Um Android Package Kit (APK para abreviar) é o formato de arquivo do pacote usado pelo sistema operacional Android para distribuição e instalação de aplicativos móveis

Primeiro pesquise o aplicativo na google play store, em nosso caso, pesquise "zenwheels" e você obterá o link do aplicativo

Em seguida, pesquise no google por "downloader apk online" e use um para baixar o apk. Normalmente eles vão pedir o link do aplicativo (o que obtivemos anteriormente), então vamos clicar no botão de download e salvá-lo em nosso computador.

2. Descompile o APK. Um descompilador em nossa situação é uma ferramenta que pega o APK e produz o código-fonte Java.

A solução mais simples é usar um descompilador online para fazer o trabalho. Eu pesquisei no google por "descomplilador online" e escolhi https://www.javadecompilers.com/. Você só precisa fazer o upload do APK obtido anteriormente e

pressione o decompile. Então você acabou de baixar as fontes.

3. Tente fazer engenharia reversa olhando através do código

Para abrir o projeto é necessário um editor de texto ou melhor, um IDE (ambiente de desenvolvimento integrado). O IDE padrão para projetos Android é Android Studio (https://developer.android.com/studio). Depois de instalar o Android Studio, abra a pasta do projeto.

Como nosso carro é controlado por bluetooth comecei minha busca no código descompilado com a palavra-chave "bluetooth", a partir das ocorrências que encontrei "BluetoothSerialService" estava no controle da comunicação. Se esta classe lida com a comunicação, ela deve ter um método de comando de envio. Acontece que existe um método de gravação que envia dados por meio do canal bluetooth:

public void write (byte out)

Este é um bom começo, eu pesquisei pelo.write (método sendo usado e há uma classe "ZenWheelsMicrocar" que estende nosso "BluetoothSerialService". Esta classe contém a maior parte da lógica de nossa comunicação por Bluetooth. A outra parte de a lógica está nos controladores: BaseController e StandardController.

No BaseController temos a inicialização do serviço, e também as definições dos canais de direção e aceleração, os canais são na verdade prefixos de comando para especificar que algum tipo de comando seguirá:

protegido ZenWheelsMicrocar microcar = novo ZenWheelsMicrocar (this, this.btHandler);

protegido ChannelOutput outputs = {new TrimChannelOutput (ZenWheelsMicrocar. STEERING_CHANNEL), novo TrimChannelOutput (ZenWheelsMicrocar. THROTTLE_CHANNEL)};

No StandardController, a direção é tratada em:

public void handleSteering (TouchEvent touchEvent) {

… This.microcar.setChannel (SteeringOutput.channel, SteeringOutput.resolveValue ()); }

Analisando o método, o SteeringOutput.channel tem o valor 129 (canal usado para direcionamento) e o SteeringOutput.resolveValue () pode ter um valor entre -90 e 90. O valor do canal (129) é enviado diretamente, e o valor do direcionamento é modificado aplicando operações bit a bit:

private final int value_convert_out (valor int) {

booleano negativo = falso; if (valor <0) {negativo = f6D; } valor interno 2 = valor & 63; if (negativo) {return value2 | 64; } return value2; }

Existe um método semelhante no StandardController chamado

public void handleThrottle (TouchEvent touchEvent)

Etapa 3: Componentes

Partes:

1. Arduino pro mini 328p 2 $

2. Placa de ensaio

3. Giroscópio MPU6050 1,2 $

4. Módulo mestre-escravo HC-05 de 6 pinos 3 $

5. 4 baterias AA com 4 baterias

6. Cabos de ligação em U (opcional). Usei esses cabos jumper porque eles ficam melhores na placa de ensaio e os leds são mais visíveis dessa forma. Se você não tiver esses cabos, pode substituí-los por fios duplos.

Os preços acima foram retirados do eBay.

Ferramentas:

1. USB para adaptador FTDI serial FT232RL para programar o arduino pro mini

2. Arduino IDE

3. Android Studio (opcional se você quiser fazer engenharia reversa)

Etapa 4: Montagem

conjunto
conjunto

A montagem é muito simples porque estamos fazendo isso em uma placa de ensaio:)

- primeiro colocamos nossos componentes na placa de ensaio: o microcontrolador, o módulo bluetooth e o giroscópio

- conecte os pinos RX e TX do bluetooth HC-05 aos pinos do arduino 10 e 11. O giroscópio SDA e SCL deve ser conectado aos pinos do arduino A4 e A5

- conecte os pinos de alimentação ao bluetooth, giroscópio e arduino. os pinos devem ser conectados ao + e - na lateral da placa de ensaio

- por último, conecte uma fonte de alimentação (entre 3,3 V a 5 V) à placa de ensaio, usei uma pequena bateria LiPo de uma célula, mas qualquer uma servirá, desde que esteja na faixa de potência

Por favor, verifique as fotos acima para mais detalhes

Etapa 5: Emparelhe o HC-05 Bluetooth com o Microcar

Emparelhe o HC-05 Bluetooth com o Microcar
Emparelhe o HC-05 Bluetooth com o Microcar
Emparelhe o HC-05 Bluetooth com o Microcar
Emparelhe o HC-05 Bluetooth com o Microcar
Emparelhe o HC-05 Bluetooth com o Microcar
Emparelhe o HC-05 Bluetooth com o Microcar

Para isso você vai precisar de um telefone Android, do módulo bluetooth HC-05 e do adaptador serial FTDI com fios. Também usaremos o IDE Arduino para nos comunicarmos com o módulo bluetooth.

Primeiro, precisamos descobrir o endereço bluetooth do microcarro:

- habilite o bluetooth no seu telefone

- ligue o carro e vá para a seção de bluetooth de suas configurações no Android

- procure por novos dispositivos e algum dispositivo chamado "Microcar" deve aparecer

- parear com este dispositivo

- em seguida, para extrair o MAC bluetooth, usei este aplicativo do Google Play Serial Bluetooth Terminal

Depois de instalar este aplicativo, vá ao menu -> dispositivos e lá você terá uma lista com todos os dispositivos bluetooth emparelhados. Estamos interessados apenas no código abaixo da mina "Microcar" é 00: 06: 66: 49: A0: 4B

Em seguida, conecte o adaptador FTDI ao módulo bluetooth. Primeiro os pinos VCC e GROUND e depois FTDI RX para bluetooth TX e FTDI TX para bluetooth RX. Além disso, deve haver um pino no módulo bluetooth que deve ser conectado ao VCC. Ao fazer isso, o módulo bluetooth entra em um "modo programável". Meu módulo tem um botão que conecta o VCC a esse pino especial. Quando você conecta o FTDI ao USB, deve estar com o pino conectado / pressionado para entrar neste modo programável especial. O bluetooth confirma a entrada neste modo de operação piscando lentamente a cada 2 segundos.

No IDE do Arduino, selecione a porta serial e, em seguida, abra o monitor serial (NL e CR com taxa de transmissão de 9600). Digite AT e o módulo deve confirmar com "OK".

Digite "AT + ROLE = 1" para colocar o módulo no modo mestre. Para emparelhar com seu módulo bluetooh, escreva: "AT + BIND = 0006, 66, 49A04B", observe como nosso "00: 06: 66: 49: A0: 4B" é transformado em "0006, 66, 49A04B". Bem, você deve fazer a mesma transformação para o seu bluetooh MAC.

Agora ligue o carro Zenwheels, desconecte o FTDI e conecte-o novamente sem o botão pressionado / pino especial conectado. Depois de um tempo, ele deve se conectar ao carro e você notará o carro fazendo um som específico de conexão bem-sucedida.

Solução de problemas:

- Descobri que de todos os módulos Bluetooth que tinha, apenas o que tinha um botão funcionava como mestre!

- certifique-se de que o carro está totalmente carregado

- certifique-se de que o carro não está conectado ao telefone

- se o Bluetooth entrar no modo AT (pisca lentamente), mas não responde ao comando, certifique-se de que você tem AMBOS NL e CR e também experimente outras taxas de BAUD

- verifique se o RX está conectado ao TX e vice-versa

- tente este tutorial

Etapa 6: Código e uso

Primeiro você precisa baixar e instalar duas bibliotecas:

1. Biblioteca MPU6050 para o giroscópio

2. Fonte da biblioteca I2CDev

Em seguida, baixe e instale minha biblioteca aqui ou copie abaixo:

/ ** * Bibliotecas: * https://github.com/jrowberg/i2cdevlib * https://github.com/jrowberg/i2cdevlib * / #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #include "Wire.h "#include" SoftwareSerial.h"

const int MAX_ANGLE = 45;

const byte commandStering = 129; const byte commandSpeed = 130;

inicialização bool = falso; // 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 Quaternion q; // [w, x, y, z] contêiner de quatérnio VectorFloat gravity; // [x, y, z] vetor de gravidade float ypr [3]; // [yaw, pitch, roll] yaw / pitch / roll container e vetor de gravidade volátil bool mpuInterrupt = false; // indica se o pino de interrupção MPU foi alto

não assinado long lastPrintTime, lastMoveTime = 0;

SoftwareSerial BTserial (10, 11);

MPU6050 mpu;

void setup ()

{Serial.begin (9600); BTserial.begin (38400); Serial.println ("Programa iniciado"); inicialização = inicializarGiroscópio (); }

void loop () {

if (! inicialização) {return; } mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus (); fifoCount = mpu.getFIFOCount (); if (hasFifoOverflown (mpuIntStatus, fifoCount)) {mpu.resetFIFO (); Retorna; } if (mpuIntStatus & 0x02) {while (fifoCount <packetSize) {fifoCount = mpu.getFIFOCount (); } mpu.getFIFOBytes (fifoBuffer, packetSize); fifoCount - = tamanho do pacote; mpu.dmpGetQuaternion (& q, fifoBuffer); mpu.dmpGetGravity (& gravity, & q); mpu.dmpGetYawPitchRoll (ypr, & q, & gravity); boi (ypr [0] * 180 / M_PI, ypr [1] * 180 / M_PI, ypr [2] * 180 / M_PI); }}

/*

* Recebe ângulo de 0 a 180 onde 0 é máximo à esquerda e 180 é máximo à direita * Recebe velocidade de -90 a 90 onde -90 é máximo para trás e 90 é máximo para frente * / void moveZwheelsCar (ângulo de byte, velocidade interna) {if (millis () - lastMoveTime = 90) {resultAngle = map (ângulo, 91, 180, 1, 60); } else if (ângulo 0) {resultSpeed = map (speed, 0, 90, 0, 60); } else if (speed <0) {resultSpeed = map (speed, 0, -90, 120, 60); } Serial.print ("actualAngle ="); Serial.print (ângulo); Serial.print (";"); Serial.print ("actualSpeed ="); Serial.print (resultSpeed); Serial.println (";"); BTserial.write (commandStering); BTserial.write (resultAngle); BTserial.write (commandSpeed); BTserial.write ((byte) resultSpeed); lastMoveTime = millis (); }

void steer (int x, int y, int z)

{x = restrição (x, -1 * MAX_ANGLE, MAX_ANGLE); y = restrição (y, -1 * MAX_ANGLE, MAX_ANGLE); z = restrição (z, -MAX_ANGLE, MAX_ANGLE); ângulo interno = mapa (y, -MAX_ANGLE, MAX_ANGLE, 0, 180); velocidade interna = mapa (z, -MAX_ANGLE, MAX_ANGLE, 90, -90); printDebug (x, y, z, ângulo, velocidade); moveZwheelsCar (ângulo, velocidade); }

void printDebug (int x, int y, int z, ângulo interno, velocidade interna)

{if (millis () - lastPrintTime <1000) {return; } Serial.print ("z ="); Serial.print (x); Serial.print (";"); Serial.print ("y ="); Serial.print (y); Serial.print (";"); Serial.print ("z ="); Serial.print (z); Serial.print (";"); Serial.print ("ângulo ="); Serial.print (ângulo); Serial.print (";"); Serial.print ("velocidade ="); Serial.print (velocidade); Serial.println (";"); lastPrintTime = millis (); }

bool initializeGyroscope ()

{Wire.begin (); mpu.initialize (); Serial.println (mpu.testConnection ()? F ("MPU6050 conexão bem-sucedida"): F ("MPU6050 conexão falhou")); devStatus = mpu.dmpInitialize (); mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1788); if (devStatus! = 0) {Serial.print (F ("Falha na inicialização do DMP (código")); Serial.println (devStatus); retornar falso;} mpu.setDMPEnabled (true); Serial.println (F ("Ativando detecção de interrupção (interrupção externa do Arduino 0)… ")); attachInterrupt (0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus (); Serial.println (F (" DMP pronto! Aguardando a primeira interrupção… ")); Tamanho do pacote = mpu.dmpGetFIFOPacketSize (); retornar verdadeiro;}

void dmpDataReady ()

{mpuInterrupt = true; }

boolean hasFifoOverflown (int mpuIntStatus, int fifoCount)

{return mpuIntStatus & 0x10 || fifoCount == 1024; }

Carregue o código usando o adaptador FTDI para o arduino e conecte as baterias.

Usando o controle remoto:

Depois que o arduino for ligado, ligue também o carro. O módulo HC-05 deve ser conectado ao carro, quando isso acontecer o carro emitirá um som. Se não funcionar, verifique a etapa anterior e a seção de solução de problemas.

Se você inclinar a placa de ensaio para a frente, o carro deve se mover para a direita, e o carro deve se mover para a direita. Ele também executa movimentos mais graduais, como inclinar um pouco para a frente e um pouco para a esquerda, neste caso o carro iria lentamente para a esquerda.

Se o carro seguir por um caminho diferente ao inclinar a placa de ensaio, primeiro segure a placa de ensaio em direções diferentes.

Como funciona:

O esboço obtém as coordenadas do giroscópio a cada 100 ms, faz cálculos e depois transmite por bluetooth os comandos do carro. Primeiro, há um método "orientar" que é chamado com os ângulos x, y e z brutos. Este método transforma a direção entre 0 e 180 graus e a aceleração entre -90 e 90. Este método chama

void moveZwheelsCar (ângulo de byte, velocidade interna) que converte a direção e a aceleração para as especificações do ZenWheels e, em seguida, transmite os comandos usando bluetooth.

A razão pela qual fiz a transformação em duas etapas é a reutilização. se eu precisasse adaptar este esboço para controlar remotamente algum outro dispositivo, eu começaria a partir do método básico "direção" que já mapeia a velocidade e direção para alguns valores úteis.

Etapa 7: Alternativas

Uma alternativa à "engenharia reversa". Falei sobre como fazer a engenharia reversa do projeto começando com o aplicativo Android. Mas há uma alternativa para isso, você pode configurar um escravo serial FTDI + bluetooth (HC-05 regular sem especificar as configurações principais). A partir do aplicativo ZenWheels, conecte-se ao HC-05 em vez do "microcar".

Para decodificar os comandos, você precisará segurar o volante em alguma posição e, em seguida, usar um script python para analisar a comunicação serial. Estou sugerindo um script python porque há caracteres não imprimíveis e o IDE do Arduino não é adequado para isso. Você observará que, se segurar a roda em uma posição, o aplicativo transmitirá regularmente os mesmos dois bytes. Se você variar a posição da roda, o primeiro byte permanecerá o mesmo e o segundo mudará. Depois de muitas tentativas, você pode criar o algoritmo de direção e, em seguida, fazer a engenharia reversa do acelerador, etc.

Uma alternativa ao controle remoto baseado em Arduino seria um controle remoto RaspberryPi. O raspberry pi tem um módulo bluetooth embutido que é fácil de configurar no modo "master" e a biblioteca bluetooth python funciona perfeitamente. Além disso, alguns projetos mais interessantes são possíveis, como controlar o carro usando Alexa echo:)

Espero que tenham gostado do projeto e por favor, deixe comentários abaixo!

Recomendado: