Inhaltsverzeichnis:

Hackbare Fernbedienung für ZenWheels Microcar - Gunook
Hackbare Fernbedienung für ZenWheels Microcar - Gunook

Video: Hackbare Fernbedienung für ZenWheels Microcar - Gunook

Video: Hackbare Fernbedienung für ZenWheels Microcar - Gunook
Video: efox erfahrungen,Iphone RC Car , iW500 2024, Juni
Anonim
Image
Image
Montage
Montage

In diesem Tutorial bauen wir eine benutzerdefinierte Fernbedienung für das ZenWheels-Mikroauto. Das ZenWheels Microcar ist ein 5 cm großes Spielzeugauto, das über eine Android- oder Iphone-Anwendung gesteuert werden kann. Ich werde Ihnen zeigen, wie Sie die Android-Anwendung zurückentwickeln, um mehr über das Kommunikationsprotokoll zu erfahren und wie Sie eine Fernbedienung mit Arduino und einem Gyroskop erstellen können.

Schritt 1: Komponenten & Werkzeuge

Teile:

1. Das Mikroauto von ZenWheels

2. Arduino pro mini 328p

3. Steckbrett

4. MPU6050-Gyroskop

5. Stromquelle <=5 V (einige Batterie, die wir an das Steckbrett anschließen können)

6. U-förmige Überbrückungskabel (optional). Ich habe diese Überbrückungskabel verwendet, weil sie auf dem Steckbrett besser aussehen. Stattdessen können normale Überbrückungskabel verwendet werden

7. HC-05 Bluetooth-Modul (mit einer Taste zum Aufrufen des AT-Modus)

Werkzeuge:

1. USB zu Seriell FTDI Adapter FT232RL zum Programmieren des Arduino pro mini

2. Arduino-IDE

3. Android-Telefon

4. Android Studio [Optional]

Schritt 2: Reverse Engineering der ZenWheels Android-Anwendung [optional]

Um diesen Teil zu verstehen, sind einige Java- und Android-Kenntnisse erforderlich.

Das Projektziel ist die Steuerung des Kleinstwagens mit einem Gyroskop. Dazu müssen wir mehr über die Bluetooth-Kommunikation zwischen diesem Spielzeug und der Android-App herausfinden.

In diesem Schritt werde ich erklären, wie man das Kommunikationsprotokoll zwischen dem Microcar und der Android-App zurückentwickelt. Wenn Sie nur die Fernbedienung erstellen möchten, ist dieser Schritt nicht erforderlich. Eine Möglichkeit, das Protokoll zu entdecken, besteht darin, sich den Quellcode anzusehen. Hmm, aber das ist nicht einfach, Android-Anwendungen werden kompiliert und man kann die APK über Google Play installieren.

Also habe ich eine grundlegende Anleitung dazu erstellt:

1. Laden Sie die APK herunter. Ein Android Package Kit (kurz APK) ist das Paketdateiformat, das vom Android-Betriebssystem für die Verteilung und Installation von mobilen Apps verwendet wird

Suchen Sie zuerst die Anwendung im Google Play Store, in unserem Fall suchen Sie nach "Zenwheels" und Sie erhalten den Anwendungslink

Suchen Sie dann bei Google nach "Online-APK-Downloader" und verwenden Sie einen, um die APK herunterzuladen. Normalerweise werden sie nach dem Bewerbungslink fragen (den wir zuvor erhalten haben), dann drücken wir einen Download-Button und speichern ihn auf unserem Computer.

2. Dekompilieren Sie das APK. Ein Decompiler in unserer Situation ist ein Tool, das das APK nimmt und Java-Quellcode erzeugt.

Die einfachste Lösung besteht darin, einen Online-Decompiler zu verwenden, um die Aufgabe zu erledigen. Ich habe bei Google nach "online decompliler" gesucht und https://www.javadecompilers.com/ gewählt. Sie müssen nur die APK, die Sie zuvor erhalten haben, hochladen und

drücke auf dekompilieren. Dann laden Sie einfach die Quellen herunter.

3. Versuchen Sie, den Code durch Reverse Engineering zu durchsuchen

Zum Öffnen des Projekts benötigen Sie einen Texteditor oder besser eine IDE (integrierte Entwicklungsumgebung). Die Standard-IDE für Android-Projekte ist Android Studio (https://developer.android.com/studio). Nachdem Sie das Android Studio installiert haben, öffnen Sie den Projektordner.

Da unser Auto über Bluetooth gesteuert wird, habe ich meine Suche im dekompilierten Code mit dem Schlüsselwort "Bluetooth" gestartet, von den Vorkommen, die ich gefunden habe, war "BluetoothSerialService" für die Kommunikation zuständig. Wenn diese Klasse die Kommunikation abwickelt, muss sie eine Sendebefehlsmethode haben. Es stellte sich heraus, dass es eine Schreibmethode gibt, die Daten über den Bluetooth-Kanal sendet:

public void write(byte out)

Dies ist ein guter Anfang, ich habe nach der.write(-Methode gesucht, die verwendet wird, und es gibt eine Klasse "ZenWheelsMicrocar", die unseren "BluetoothSerialService" erweitert. Diese Klasse enthält den größten Teil der Logik unserer Kommunikation über Bluetooth. Der andere Teil von die Logik steckt in den Controllern: BaseController und StandardController.

Im BaseController haben wir die Dienstinitialisierung und auch Definitionen der Lenk- und Drosselkanäle, Kanäle sind in der Tat Befehlspräfixe, um anzugeben, dass eine Art von Befehl folgt:

geschütztes ZenWheelsMicrocar microcar = new ZenWheelsMicrocar(this, this.btHandler);

geschützte ChannelOutput-Ausgänge = {new TrimChannelOutput(ZenWheelsMicrocar. STEERING_CHANNEL), new TrimChannelOutput(ZenWheelsMicrocar. THROTTLE_CHANNEL)};

Im StandardController erfolgt die Steuerung in:

public void handleSteering(TouchEvent touchEvent) {

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

Bei der Analyse der Methode hat SteeringOutput.channel den Wert 129 (Kanal wird zum Steuern verwendet) und SteeringOutput.resolveValue() kann einen Wert zwischen -90 und 90 haben. Der Kanalwert (129) wird direkt gesendet und der Lenkwert wird modifiziert durch Anwendung bitweiser Operationen:

private final int value_convert_out(int value) {

boolesch negativ = falsch; wenn (Wert < 0) { negativ = f6D; } int Wert2 = Wert & 63; if (negativ) { Rückgabewert2 | 64; } Rückgabewert2; }

Es gibt eine ähnliche Methode im StandardController namens

public void handleThrottle(TouchEvent touchEvent)

Schritt 3: Komponenten

Teile:

1. Arduino pro mini 328p 2 $

2. Steckbrett

3. MPU6050 Gyroskop 1.2$

4. HC-05 Master-Slave 6-Pin-Modul 3$

5. 4 x AA Batteriepack mit 4 Batterien

6. U-förmige Überbrückungskabel (optional). Ich habe diese Überbrückungskabel verwendet, weil sie auf dem Steckbrett besser aussehen und die LEDs auf diese Weise besser sichtbar sind. Wenn Sie diese Kabel nicht haben, können Sie sie durch Dupont-Kabel ersetzen.

Die oben genannten Preise stammen von eBay.

Werkzeuge:

1. USB-zu-Seriell-FTDI-Adapter FT232RL zum Programmieren des Arduino Pro Mini

2. Arduino-IDE

3. Android Studio (optional, wenn Sie sich selbst zurückentwickeln möchten)

Schritt 4: Montage

Montage
Montage

Die Montage ist sehr einfach, weil wir es auf einem Steckbrett machen:)

- Zuerst platzieren wir unsere Komponenten auf dem Steckbrett: den Mikrocontroller, das Bluetooth-Modul und das Gyroskop

- Verbinden Sie die HC-05 Bluetooth RX- und TX-Pins mit den Arduino 10- und 11-Pins. Das Gyroskop SDA und SCL sollten an die Arduino-Pins A4 und A5 angeschlossen werden

- Verbinden Sie die Power-Pins mit Bluetooth, Gyro und dem Arduino. die Pins sollten mit + und - an der Seite des Steckbretts verbunden werden

- Schließen Sie zuletzt ein Netzteil (zwischen 3,3 V bis 5 V) an das Steckbrett an, ich habe einen kleinen LiPo-Akku mit einer Zelle verwendet, aber jeder reicht aus, solange er im Leistungsbereich liegt

Bitte überprüfen Sie die Bilder oben, um weitere Informationen zu erhalten

Schritt 5: Koppeln Sie das HC-05 Bluetooth mit dem Microcar

Koppeln Sie das HC-05 Bluetooth mit dem Microcar
Koppeln Sie das HC-05 Bluetooth mit dem Microcar
Koppeln Sie das HC-05 Bluetooth mit dem Microcar
Koppeln Sie das HC-05 Bluetooth mit dem Microcar
Koppeln Sie das HC-05 Bluetooth mit dem Microcar
Koppeln Sie das HC-05 Bluetooth mit dem Microcar

Dazu benötigen Sie ein Android-Telefon, das Bluetooth HC-05-Modul und den seriellen FTDI-Adapter mit Kabeln. Außerdem werden wir die Arduino IDE verwenden, um mit dem Bluetooth-Modul zu kommunizieren.

Zuerst müssen wir die Bluetooth-Adresse des Microcars herausfinden:

- Bluetooth auf Ihrem Telefon aktivieren

- Schalten Sie das Auto ein und gehen Sie zum Bluetooth-Bereich Ihrer Einstellungen in Android

- Suche nach neuen Geräten und ein Gerät namens "Microcar" sollte erscheinen

- mit diesem Gerät koppeln

- Um den Bluetooth-MAC zu extrahieren, habe ich diese App von Google Play Serial Bluetooth Terminal verwendet

Nach der Installation dieser App gehen Sie zu Menü -> Geräte und dort haben Sie eine Liste mit allen Bluetooth-gekoppelten Geräten. Uns interessiert nur der Code unter der Mine "Microcar" 00:06:66:49:A0:4B

Als nächstes verbinden Sie den FTDI-Adapter mit dem Bluetooth-Modul. Zuerst VCC- und GROUND-Pins und dann FTDI RX an Bluetooth TX und FTDI TX an Bluetooth RX. Außerdem sollte sich am Bluetooth-Modul ein Pin befinden, der mit dem VCC verbunden werden sollte. Dabei geht das Bluetooth-Modul in einen "programmierbaren Modus". Mein Modul hat eine Taste, die den VCC mit diesem speziellen Pin verbindet. Wenn Sie das FTDI an den USB anschließen, sollte es mit dem angeschlossenen Pin / gedrückter Taste sein, um in diesen speziellen programmierbaren Modus zu gelangen. Das Bluetooth bestätigt den Eintritt in diesen Betriebsmodus, indem es alle 2 Sekunden langsam blinkt.

Wählen Sie in der Arduino IDE den seriellen Port aus und öffnen Sie dann den seriellen Monitor (sowohl NL als auch CR mit 9600 Baudrate). Geben Sie AT ein und das Modul sollte mit "OK" bestätigen.

Geben Sie "AT+ROLE=1" ein, um das Modul in den Master-Modus zu versetzen. Um mit Ihrem Bluetooth-Modul zu koppeln, schreiben Sie: "AT+BIND=0006, 66, 49A04B", Beachten Sie, wie unser "00:06:66:49:A0:4B" in "0006, 66, 49A04B" umgewandelt wird. Nun, Sie sollten die gleiche Transformation für Ihren Bluetooth-MAC durchführen.

Schalten Sie nun das Zenwheels-Auto ein, ziehen Sie dann den FTDI ab und stecken Sie ihn wieder ein, ohne dass die Taste gedrückt / der spezielle Pin angeschlossen ist. Nach einer Weile sollte es sich mit dem Auto verbinden und Sie werden feststellen, dass das Auto eine bestimmte Verbindung erfolgreich ertönt.

Fehlerbehebung:

- Ich habe festgestellt, dass von allen Bluetooth-Modulen, die ich hatte, nur das mit einer Taste als Master funktionierte!

- Stellen Sie sicher, dass das Auto vollständig aufgeladen ist

- Stellen Sie sicher, dass das Auto nicht mit dem Telefon verbunden ist

- Wenn das Bluetooth in den AT-Modus wechselt (langsam blinkt), aber nicht auf den Befehl reagiert, stellen Sie sicher, dass Sie BEIDE NL & CR haben, und experimentieren Sie auch mit anderen BAUD-Raten

- Überprüfen Sie, ob der RX mit dem TX verbunden ist und umgekehrt

- Probieren Sie dieses Tutorial aus

Schritt 6: Code & Verwendung

Zuerst müssen Sie zwei Bibliotheken herunterladen und installieren:

1. MPU6050-Bibliothek für das Gyroskop

2. I2CDev-Bibliotheksquelle

Dann laden Sie meine Bibliothek von hier herunter und installieren Sie sie oder kopieren Sie sie von unten:

/** * Bibliotheken: * 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 Befehlsgeschwindigkeit = 130;

bool Initialisierung = false; // setze true, wenn die DMP-Init erfolgreich war

uint8_t mpuIntStatus; // hält das aktuelle Interrupt-Statusbyte von der MPU uint8_t devStatus; // Status nach jeder Geräteoperation zurückgeben (0 = Erfolg, !0 = Fehler) uint16_t packetSize; // erwartete DMP-Paketgröße (Standard ist 42 Byte) uint16_t fifoCount; // Anzahl aller Bytes, die sich derzeit im FIFO befinden uint8_t fifoBuffer[64]; // FIFO-Speicherpuffer Quaternion q; // [w, x, y, z] Quaternion-Container VectorFloat Gravitation; // [x, y, z] Schwerkraftvektor float ypr[3]; // [Gieren, Nicken, Rollen] Gieren/Neigen/Rollen Container und Gravitationsvektor volatile bool mpuInterrupt = false; // zeigt an, ob der MPU-Interrupt-Pin hoch gegangen ist

unsigned long lastPrintTime, lastMoveTime = 0;

SoftwareSerial BTserial(10, 11);

MPU6050 mpu;

Void-Setup ()

{ Serial.begin (9600); BTserial.begin(38400); Serial.println ("Programm gestartet"); Initialisierung = initializeGyroscope(); }

Leere Schleife () {

if (!Initialisierung) { return; } mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus(); fifoCount = mpu.getFIFOCount(); if (hasFifoOverflown(mpuIntStatus, fifoCount)) {mpu.resetFIFO(); Rückkehr; } if (mpuIntStatus & 0x02) { while (fifoCount < Paketgröße) { fifoCount = mpu.getFIFOCount (); } mpu.getFIFOBytes(fifoBuffer, Paketgröße); fifoCount -= Paketgröße; mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); lenken(ypr[0] * 180/M_PI, ypr[1] * 180/M_PI, ypr[2] * 180/M_PI); } }

/*

* Empfängt Winkel von 0 bis 180, wobei 0 maximal links und 180 maximal rechts ist * Empfängt Geschwindigkeit von -90 bis 90, wobei -90 maximal rückwärts und 90 maximal vorwärts ist */ void moveZwheelsCar(byte angle, int speed) { if (millis () - lastMoveTime = 90) { resultAngle = map (Winkel, 91, 180, 1, 60); aufrechtzuerhalten. Sonst if (Winkel 0) { resultSpeed = map (speed, 0, 90, 0, 60); aufrechtzuerhalten. Sonst if (Geschwindigkeit < 0) { ErgebnisGeschwindigkeit = Karte (Geschwindigkeit, 0, -90, 120, 60); } Serial.print ("actualAngle = "); Serial.print (Winkel); Serial.print ("; "); Serial.print ("actualSpeed="); Serial.print (resultSpeed); Serial.println ("; "); BTserial.write(commandStering); BTserial.write (resultAngle); BTserial.write (Befehlsgeschwindigkeit); BTserial.write ((Byte) resultSpeed); lastMoveTime = millis(); }

Leere steuern(int x, int y, int z)

{ x = einschränken(x, -1 * MAX_ANGLE, MAX_ANGLE); y = einschränken(y, -1 * MAX_ANGLE, MAX_ANGLE); z = einschränken(z, -MAX_ANGLE, MAX_ANGLE); int angle = map(y, -MAX_ANGLE, MAX_ANGLE, 0, 180); int speed = map(z, -MAX_ANGLE, MAX_ANGLE, 90, -90); printDebug(x, y, z, Winkel, Geschwindigkeit); moveZwheelsCar(Winkel, Geschwindigkeit); }

void printDebug(int x, int y, int z, int Winkel, int Geschwindigkeit)

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

bool initializeGyroscope()

{ Draht.begin(); mpu.initialize(); Serial.println (mpu.testConnection () ? F ("MPU6050-Verbindung erfolgreich"): F ("MPU6050-Verbindung fehlgeschlagen")); 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.") Interrupt-Erkennung (Arduino externer Interrupt 0)…")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); Serial.println(F("DMP ready! Waiting for first interrupt…")); packetSize = mpu.dmpGetFIFOPacketSize(); true zurückgeben; }

void dmpDataReady()

{ mpuInterrupt = wahr; }

boolean hasFifoOverflown(int mpuIntStatus, int fifoCount)

{ mpuIntStatus & 0x10 zurückgeben || fifoCount == 1024; }

Laden Sie den Code mit dem FTDI-Adapter auf das Arduino hoch und schließen Sie die Batterien an.

Verwenden der Fernbedienung:

Nachdem das Arduino eingeschaltet ist, schalten Sie auch das Auto ein. Das HC-05-Modul sollte mit dem Auto verbunden sein, wenn das passiert, gibt das Auto einen Ton aus. Wenn es nicht funktioniert, überprüfen Sie bitte den vorherigen Schritt und den Abschnitt zur Fehlerbehebung.

Wenn Sie das Steckbrett nach vorne neigen, sollte sich das Auto vorwärts bewegen, nach rechts und das Auto sollte sich nach rechts bewegen. Es führt auch langsamere Bewegungen aus, wie z. B. ein bisschen nach vorne und ein bisschen nach links, in diesem Fall würde das Auto langsam nach links fahren.

Wenn das Auto beim Neigen des Steckbretts einen anderen Weg fährt, halten Sie zuerst das Steckbrett in verschiedene Richtungen.

Wie es funktioniert:

Die Skizze erhält alle 100 ms die Gyroskop-Koordinaten, führt Berechnungen durch und überträgt dann über Bluetooth die Autobefehle. Zuerst gibt es eine "Steer"-Methode, die mit den rohen x-, y- und z-Winkeln aufgerufen wird. Diese Methode transformiert die Lenkung zwischen 0 und 180 Grad und die Beschleunigung zwischen -90 und 90. Diese Methode ruft

void moveZwheelsCar(byte angle, int speed), das die Lenkung und Beschleunigung in ZenWheels-Spezifikationen umwandelt und dann die Befehle per Bluetooth überträgt.

Der Grund, warum ich die Transformation in zwei Schritten durchgeführt habe, ist die Wiederverwendbarkeit. Wenn ich diese Skizze an die Fernbedienung eines anderen Geräts anpassen müsste, würde ich von der Basismethode "Steer" ausgehen, die die Geschwindigkeit und Lenkung bereits auf einige nützliche Werte abbildet.

Schritt 7: Alternativen

Eine Alternative zum „Reverse Engineering“. Ich habe darüber gesprochen, wie man das Projekt zurückentwickelt, indem man mit der Android-Anwendung beginnt. Aber alternativ dazu können Sie einen seriellen FTDI + Bluetooth-Slave einrichten (regulärer HC-05 ohne Angabe der Master-Einstellungen). Verbinden Sie sich dann von der ZenWheels-App aus mit dem HC-05 anstelle des "Microcar".

Um die Befehle zu entschlüsseln, müssen Sie das Lenkrad in einer bestimmten Position halten und dann mit einem Python-Skript die serielle Kommunikation analysieren. Ich schlage ein Python-Skript vor, da es nicht druckbare Zeichen gibt und die Arduino IDE dafür nicht geeignet ist. Sie werden feststellen, dass die App regelmäßig die gleichen zwei Byte überträgt, wenn Sie das Rad in einer Position halten. Wenn Sie die Radposition ändern, bleibt das erste Byte gleich, das zweite ändert sich. Nach vielen Versuchen können Sie den Lenkalgorithmus entwickeln, dann das Gas umkehren usw.

Eine Alternative zur arduino-basierten Fernbedienung wäre eine RaspberryPi-Fernbedienung. Der Himbeer-Pi verfügt über ein eingebettetes Bluetooth-Modul, das im "Master" -Modus problemlos eingerichtet werden kann, und die Python-Bluetooth-Bibliothek funktioniert wie ein Zauber. Auch einige weitere interessante Projekte sind möglich, wie die Steuerung des Autos mit Alexa Echo:)

Ich hoffe, Ihnen hat das Projekt gefallen und hinterlassen Sie bitte unten Kommentare!

Empfohlen: