Table des matières:

Télécommande piratable pour ZenWheels Microcar : 7 étapes
Télécommande piratable pour ZenWheels Microcar : 7 étapes

Vidéo: Télécommande piratable pour ZenWheels Microcar : 7 étapes

Vidéo: Télécommande piratable pour ZenWheels Microcar : 7 étapes
Vidéo: Arduino bluetooth Voitrue RC via APP Android 2024, Juin
Anonim
Image
Image
Assemblée
Assemblée

Dans ce didacticiel, nous allons créer une télécommande personnalisée pour la microcar ZenWheels. La microcar ZenWheels est une petite voiture de 5 cm contrôlable via une application Android ou Iphone. Je vais vous montrer comment désosser l'application Android pour découvrir le protocole de communication et comment construire une télécommande à l'aide d'arduino et d'un gyroscope.

Étape 1: Composants et outils

Les pièces:

1. La microvoiture ZenWheels

2. Arduino pro mini 328p

3. Planche à pain

4. Gyroscope MPU6050

5. source d'alimentation <=5 v (une batterie que nous pouvons attacher à la planche à pain)

6. Câbles de démarrage en forme de U (facultatif). J'ai utilisé ces câbles de démarrage parce qu'ils ont une meilleure apparence sur la planche à pain. Des câbles de démarrage réguliers peuvent être utilisés à la place

7. Module bluetooth HC-05 (avec un bouton pour entrer en mode AT)

Outils:

1. Adaptateur USB vers série FTDI FT232RL pour programmer l'Arduino pro mini

2. IDE Arduino

3. Téléphone Android

4. Android Studio [Facultatif]

Étape 2: rétro-ingénierie de l'application Android ZenWheels [facultatif]

Une certaine connaissance de Java et Android est nécessaire pour comprendre cette partie.

L'objectif du projet est de contrôler la microvoiture à l'aide d'un gyroscope. Pour cela, nous devons en savoir plus sur la communication Bluetooth entre ce jouet et l'application Android.

Dans cette étape, j'expliquerai comment procéder à l'ingénierie inverse du protocole de communication entre la microcar et l'application Android. Si vous voulez juste construire la télécommande, cette étape n'est pas nécessaire. Une façon de découvrir le protocole est de regarder le code source. Hmm mais ce n'est pas simple, les applications Android sont compilées et on peut installer l'apk via Google Play.

J'ai donc fait un guide de base pour faire ceci:

1. Téléchargez l'APK. Un kit de package Android (APK en abrégé) est le format de fichier de package utilisé par le système d'exploitation Android pour la distribution et l'installation d'applications mobiles

Recherchez d'abord l'application sur google play store, dans notre cas recherchez "zenwheels" et vous obtiendrez le lien de l'application

Ensuite, recherchez sur google " téléchargeur d'apk en ligne " et utilisez-en un pour télécharger l'apk. Habituellement, ils demanderont le lien de l'application (celui que nous avons obtenu plus tôt), puis nous appuierons sur un bouton de téléchargement et l'enregistrerons dans notre ordinateur.

2. Décompilez l'APK. Un décompilateur dans notre situation est un outil qui prend l'APK et produit le code source Java.

La solution la plus simple consiste à utiliser un décompilateur en ligne pour faire le travail. J'ai recherché sur google " décompilateur en ligne " et j'ai choisi https://www.javadecompilers.com/. Il vous suffit de télécharger l'APK que vous avez obtenu précédemment et

appuyez sur la décompilation. Ensuite, il vous suffit de télécharger les sources.

3. Essayez de faire de l'ingénierie inverse en parcourant le code

Pour ouvrir le projet, vous avez besoin d'un éditeur de texte ou mieux d'un IDE (environnement de développement intégré). L'IDE par défaut pour les projets Android est Android Studio (https://developer.android.com/studio). Après avoir installé Android Studio, ouvrez le dossier du projet.

Parce que notre voiture est contrôlée par Bluetooth, j'ai commencé ma recherche dans le code décompilé avec le mot-clé "bluetooth", à partir des occurrences que j'ai trouvées, "BluetoothSerialService" était en charge de la communication. Si cette classe gère la communication, elle doit avoir une méthode de commande d'envoi. Il s'avère qu'il existe une méthode d'écriture qui envoie des données via le canal Bluetooth:

public void write(byte out)

C'est un bon début, j'ai recherché la méthode.write (utilisée et il existe une classe "ZenWheelsMicrocar" qui étend notre "BluetoothSerialService". Cette classe contient la majeure partie de la logique de notre communication via Bluetooth. L'autre partie de la logique est dans les contrôleurs: BaseController et StandardController.

Dans le BaseController, nous avons l'initialisation du service, ainsi que les définitions des canaux de direction et d'accélérateur, les canaux sont en fait des préfixes de commande pour spécifier qu'un certain type de commande suivra:

protégé ZenWheelsMicrocar microcar = nouveau ZenWheelsMicrocar(this, this.btHandler);

sorties ChannelOutput protégées = {nouveau TrimChannelOutput(ZenWheelsMicrocar. STEERING_CHANNEL), nouveau TrimChannelOutput(ZenWheelsMicrocar. THROTTLE_CHANNEL)};

Dans le StandardController, la direction est gérée dans:

public void handleSteering(TouchEvent touchEvent) {

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

En analysant la méthode, le SteeringOutput.channel a la valeur 129 (canal utilisé pour le pilotage) et le SteeringOutput.resolveValue() peut avoir une valeur comprise entre -90 et 90. La valeur du canal (129) est envoyée directement, et la valeur du pilotage est modifiée en appliquant des opérations au niveau du bit:

valeur int finale privée_convert_out(valeur int) {

booléen négatif = faux; if (valeur < 0) { négatif = f6D; } valeur int2 = valeur & 63; if (négatif) { return value2 | 64; } valeur de retour2; }

Il existe une méthode similaire dans le StandardController appelée

public void handleThrottle(TouchEvent touchEvent)

Étape 3: Composants

Les pièces:

1. Arduino pro mini 328p 2 $

2. Planche à pain

3. Gyroscope MPU6050 1.2$

4. Module maître-esclave 6 broches HC-05 3$

5. 4 piles AA avec 4 piles

6. Câbles de démarrage en forme de U (facultatif). J'ai utilisé ces câbles de démarrage parce qu'ils ont une meilleure apparence sur la planche à pain et que les voyants sont plus visibles de cette façon. Si vous n'avez pas ces câbles, vous pouvez les remplacer par des fils dupont.

Les prix ci-dessus sont tirés d'eBay.

Outils:

1. Adaptateur USB vers série FTDI FT232RL pour programmer l'arduino pro mini

2. IDE Arduino

3. Android Studio (facultatif si vous souhaitez effectuer vous-même la rétro-ingénierie)

Étape 4: Assemblage

Assemblée
Assemblée

Le montage est très simple car on le fait sur une maquette:)

- nous plaçons d'abord nos composants sur la maquette: le microcontrôleur, le module bluetooth et le gyroscope

- connectez les broches RX et TX bluetooth HC-05 aux broches arduino 10 et 11. Le gyroscope SDA et SCL doit être connecté aux broches arduino A4 et A5

- connectez les broches d'alimentation au bluetooth, au gyroscope et à l'arduino. les broches doivent être connectées aux + et - sur le côté de la planche à pain

- branchez enfin une alimentation (entre 3,3 V à 5 V) à la planche à pain, j'ai utilisé une petite batterie LiPo à une cellule mais n'importe laquelle fera l'affaire tant qu'elle est dans la plage de puissance

S'il vous plaît vérifier les images ci-dessus pour plus de détails

Étape 5: Associez le Bluetooth HC-05 à la Microcar

Associez le Bluetooth HC-05 à la Microcar
Associez le Bluetooth HC-05 à la Microcar
Associez le Bluetooth HC-05 à la Microcar
Associez le Bluetooth HC-05 à la Microcar
Associez le Bluetooth HC-05 à la Microcar
Associez le Bluetooth HC-05 à la Microcar

Pour cela, vous aurez besoin d'un téléphone Android, du module bluetooth HC-05 et de l'adaptateur série FTDI avec fils. Nous utiliserons également l'IDE Arduino pour communiquer avec le module Bluetooth.

Nous devons d'abord trouver l'adresse Bluetooth de la microvoiture:

- activer le bluetooth sur votre téléphone

- allumez la voiture et allez dans la section bluetooth de vos paramètres sous Android

- recherchez de nouveaux appareils et un appareil appelé "Microcar" devrait apparaître

- jumeler avec cet appareil

- puis pour extraire le MAC Bluetooth, j'ai utilisé cette application à partir du terminal Bluetooth série google play

Après avoir installé cette application, allez dans le menu -> appareils et là vous aurez une liste avec tous les appareils Bluetooth couplés. Nous ne sommes intéressés que par le code sous la mine "Microcar" est 00:06:66:49:A0:4B

Connectez ensuite l'adaptateur FTDI au module Bluetooth. D'abord les broches VCC et GROUND, puis FTDI RX vers Bluetooth TX et FTDI TX vers Bluetooth RX. Il devrait également y avoir une broche sur le module Bluetooth qui devrait être connectée au VCC. En faisant cela, le module Bluetooth entre dans un "mode programmable". Mon module a un bouton qui connecte le VCC à cette broche spéciale. Lorsque vous branchez le FTDI dans l'USB, il doit être avec la broche connectée / le bouton enfoncé pour entrer dans ce mode programmable spécial. Le bluetooth confirme l'entrée dans ce mode de fonctionnement en clignotant lentement toutes les 2 secondes.

Dans l'IDE Arduino, sélectionnez le port série, puis ouvrez le moniteur série (à la fois NL et CR avec un débit en bauds de 9600). Tapez AT et le module doit confirmer avec "OK".

Tapez "AT+ROLE=1" pour mettre le module en mode maître. Pour jumeler avec votre module bluetooh écrivez: "AT+BIND=0006, 66, 49A04B", Remarquez comment notre "00:06:66:49:A0:4B" est transformé en "0006, 66, 49A04B". Eh bien, vous devriez faire la même transformation pour votre MAC bluetooh.

Allumez maintenant la voiture Zenwheels, puis débranchez le FTDI et rebranchez-le sans appuyer sur le bouton / broche spéciale connectée. Après un certain temps, il devrait se connecter à la voiture et vous remarquerez que la voiture émet un son de connexion spécifique.

Dépannage:

- J'ai trouvé que parmi tous les modules Bluetooth que j'avais, seul celui avec un bouton fonctionnait en maître !

- assurez-vous que la voiture est complètement chargée

- assurez-vous que la voiture n'est pas connectée au téléphone

- si le Bluetooth entre en mode AT (clignote lentement) mais qu'il ne répond pas à la commande, assurez-vous d'avoir les DEUX NL et CR, et expérimentez également avec d'autres débits en BAUD

- vérifiez que le RX est connecté au TX et vice versa

- essayez ce tutoriel

Étape 6: Code et utilisation

Vous devez d'abord télécharger et installer deux bibliothèques:

1. Bibliothèque MPU6050 pour le gyroscope

2. Source de la bibliothèque I2CDev

Ensuite, téléchargez et installez ma bibliothèque à partir d'ici ou copiez-la ci-dessous:

/** * Bibliothèques: * 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 entier MAX_ANGLE = 45;

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

bool initialisation = false; // défini sur true si l'initialisation DMP a réussi

uint8_t mpuIntStatus; // contient l'octet d'état d'interruption réel du MPU uint8_t devStatus; // renvoie l'état après chaque opération de périphérique (0 = succès, !0 = erreur) uint16_t packetSize; // taille de paquet DMP attendue (la valeur par défaut est de 42 octets) uint16_t fifoCount; // compte de tous les octets actuellement dans FIFO uint8_t fifoBuffer[64]; // Tampon de stockage FIFO Quaternion q; // [w, x, y, z] conteneur de quaternions VectorFloat Gravity; // [x, y, z] vecteur de gravité float ypr[3]; // [lacet, tangage, roulis] lacet/tangage/roulis conteneur et vecteur de gravité volatile bool mpuInterrupt = false; // indique si la broche d'interruption MPU est passée au niveau haut

non signé long lastPrintTime, lastMoveTime = 0;

SoftwareSerial BTserial (10, 11);

MPU6050 mpu;

void setup()

{ Serial.begin(9600); BTserial.begin(38400); Serial.println("Programme démarré"); initialisation = initializeGyroscope(); }

boucle vide() {

if (!initialisation) { return; } mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus(); fifoCount = mpu.getFIFOCount(); if (hasFifoOvervoln(mpuIntStatus, fifoCount)) { mpu.resetFIFO(); revenir; } if (mpuIntStatus & 0x02) { while (fifoCount < packetSize) { fifoCount = mpu.getFIFOCount(); } mpu.getFIFOBytes(fifoBuffer, packetSize); fifoCount -= packetSize; mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); steer(ypr[0] * 180/M_PI, ypr[1] * 180/M_PI, ypr[2] * 180/M_PI); } }

/*

* Reçoit l'angle de 0 à 180 où 0 est le maximum à gauche et 180 est le maximum à droite * Reçoit la vitesse de -90 à 90 où -90 est le maximum en arrière et 90 est le maximum en avant */ void moveZwheelsCar(byte angle, int speed) { if (millis() - lastMoveTime = 90) { resultAngle = map(angle, 91, 180, 1, 60); } else if (angle 0) { resultSpeed = map(speed, 0, 90, 0, 60); } else if (vitesse < 0) { resultSpeed = map(speed, 0, -90, 120, 60); } Serial.print("actualAngle=");Serial.print(angle);Serial.print("; "); Serial.print("actualSpeed=");Serial.print(resultSpeed);Serial.println("; "); BTserial.write(commandStering); BTserial.write(resultAngle); BTserial.write(commandeVitesse); BTserial.write((byte) resultSpeed); lastMoveTime = millis(); }

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

{ x = contrainte(x, -1 * MAX_ANGLE, MAX_ANGLE); y = contrainte(y, -1 * MAX_ANGLE, MAX_ANGLE); z = contrainte(z, -MAX_ANGLE, MAX_ANGLE); angle int = map(y, -MAX_ANGLE, MAX_ANGLE, 0, 180); vitesse int = map(z, -MAX_ANGLE, MAX_ANGLE, 90, -90); printDebug(x, y, z, angle, vitesse); moveZwheelsCar(angle, vitesse); }

void printDebug(int x, int y, int z, int angle, int speed)

{ 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("angle=");Serial.print(angle);Serial.print("; "); Serial.print("speed=");Serial.print(speed);Serial.println("; "); lastPrintTime = millis(); }

bool initializeGyroscope()

{ Fil.begin(); mpu.initialize(); Serial.println(mpu.testConnection() ? F("Connexion MPU6050 réussie"): F("Connexion MPU6050 échouée")); devStatus = mpu.dmpInitialize(); mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); if (devStatus != 0) { Serial.print(F("DMP Initialization failed (code "));Serial.println(devStatus); return false; } mpu.setDMPEnabled(true); Serial.println(F("Enabling détection d'interruption (interruption externe Arduino 0)…")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); Serial.println(F("DMP prêt! En attente de la première interruption…")); packetSize = mpu.dmpGetFIFOPacketSize(); renvoie vrai; }

void dmpDataReady()

{ mpuInterrupt = vrai; }

booléen hasFifoOverfwn(int mpuIntStatus, int fifoCount)

{ renvoie mpuIntStatus & 0x10 || Comptefifo == 1024; }

Téléchargez le code à l'aide de l'adaptateur FTDI sur l'arduino, puis connectez les batteries.

Utilisation de la télécommande:

Une fois l'arduino allumé, allumez également la voiture. Le module HC-05 doit se connecter à la voiture, lorsque cela se produit, la voiture émet un son. Si cela ne fonctionne pas, veuillez vérifier l'étape précédente et la section de dépannage.

Si vous inclinez la planche à pain vers l'avant, la voiture doit avancer vers la droite et la voiture doit se déplacer vers la droite. Il effectue également des mouvements plus progressifs comme s'incliner un peu vers l'avant et un peu à gauche dans ce cas, la voiture irait lentement vers la gauche.

Si la voiture va d'une manière différente lors de l'inclinaison de la planche à pain, tenez d'abord la planche à pain dans des directions différentes.

Comment ça fonctionne:

L'esquisse obtient les coordonnées du gyroscope toutes les 100 ms, effectue des calculs, puis transmet via Bluetooth les commandes de la voiture. D'abord, il y a une méthode "steer" qui est appelée avec les angles bruts x, y et z. Cette méthode transforme la direction entre 0 et 180 degrés et l'accélération entre -90 et 90. Cette méthode appelle

void moveZwheelsCar (byte angle, int speed) qui convertit la direction et l'accélération en spécifications ZenWheels, puis transmet les commandes via Bluetooth.

La raison pour laquelle j'ai fait la transformation en deux étapes, c'est la réutilisabilité. si j'avais besoin d'adapter ce croquis pour contrôler à distance un autre appareil, je commencerais à partir de la méthode de base "direction" qui mappe déjà la vitesse et la direction à certaines valeurs utiles.

Étape 7: Alternatives

Une alternative à la "reverse engineering". J'ai expliqué comment procéder à l'ingénierie inverse du projet en commençant par l'application Android. Mais il existe une alternative à cela, vous pouvez configurer un esclave série FTDI + bluetooth (HC-05 régulier sans spécifier les paramètres du maître). Ensuite, à partir de l'application ZenWheels, connectez-vous au HC-05 au lieu de la "microcar".

Pour décoder les commandes, vous devrez maintenir le volant dans une certaine position, puis, à l'aide d'un script python, analyser la communication série. Je suggère un script python car il y a des caractères non imprimables et Arduino IDE ce n'est pas adapté pour ça. Vous remarquerez que si vous maintenez la molette dans une position, l'application transmettra régulièrement les deux mêmes octets. Si vous modifiez la position de la roue, le premier octet restera le même, le second changera. Après de nombreux essais, vous pouvez proposer l'algorithme de direction, puis procéder à l'ingénierie inverse des gaz, etc.

Une alternative à la télécommande basée sur arduino serait une télécommande RaspberryPi. Le raspberry pi a un module bluetooth intégré qui est simple à configurer en mode "maître" et la bibliothèque bluetooth python fonctionne à merveille. Des projets plus intéressants sont également possibles, comme contrôler la voiture à l'aide d'Alexa echo:)

J'espère que vous avez apprécié le projet et s'il vous plaît laissez des commentaires ci-dessous!

Conseillé: