Inhoudsopgave:

Hackbare afstandsbediening voor ZenWheels Microcar - Ajarnpa
Hackbare afstandsbediening voor ZenWheels Microcar - Ajarnpa

Video: Hackbare afstandsbediening voor ZenWheels Microcar - Ajarnpa

Video: Hackbare afstandsbediening voor ZenWheels Microcar - Ajarnpa
Video: Tiny R/C Car for iPhone and Android - ZenWheels 2024, November
Anonim
Image
Image
samenkomst
samenkomst

In deze tutorial gaan we een aangepaste afstandsbediening bouwen voor de ZenWheels-microcar. De Microcar ZenWheels is een speelgoedauto van 5 cm die bestuurbaar is via een Android- of Iphone-applicatie. Ik ga je laten zien hoe je de Android-applicatie reverse engineert om meer te weten te komen over het communicatieprotocol en hoe je een afstandsbediening kunt bouwen met behulp van Arduino en een gyroscoop.

Stap 1: Componenten & Gereedschap

Onderdelen:

1. De ZenWheels-microwagen

2. Arduino pro mini 328p

3. Broodplank

4. MPU6050-gyroscoop

5. stroombron <=5 v (een batterij die we aan het breadboard kunnen bevestigen)

6. U-vormige startkabels (optioneel). Ik heb deze startkabels gebruikt omdat ze er beter uitzien op het breadboard. In plaats daarvan kunnen gewone startkabels worden gebruikt

7. HC-05 bluetooth-module (met een knop om de AT-modus in te gaan)

Gereedschap:

1. USB naar seriële FTDI-adapter FT232RL om de Arduino pro mini te programmeren

2. Arduino-IDE

3. Android-telefoon

4. Android Studio [Optioneel]

Stap 2: Reverse-engineering van de ZenWheels Android-applicatie [optioneel]

Enige kennis van Java en Android is vereist om dit onderdeel te begrijpen.

Het doel van het project is om de brommobiel te besturen met behulp van een gyroscoop. Hiervoor moeten we meer te weten komen over de bluetooth-communicatie tussen dit speelgoed en de Android-app.

In deze stap zal ik uitleggen hoe je het communicatieprotocol tussen de microcar en de Android-app reverse engineert. Als u alleen de afstandsbediening wilt bouwen, is deze stap niet nodig. Een manier om het protocol te ontdekken, is door naar de broncode te kijken. Hmm maar dit is niet eenvoudig, android applicaties worden gecompileerd en men kan de apk installeren via google play.

Dus ik heb een basisgids gemaakt om dit te doen:

1. Download de APK. Een Android Package Kit (kortweg APK) is de pakketbestandsindeling die door het Android-besturingssysteem wordt gebruikt voor de distributie en installatie van mobiele apps

Zoek eerst de applicatie in de Google Play Store, zoek in ons geval "zenwheels" en je krijgt de applicatielink

Zoek vervolgens op google naar " online apk downloader " en gebruik er een om de apk te downloaden. Meestal zullen ze om de applicatielink vragen (degene die we eerder hebben verkregen), dan drukken we op een downloadknop en slaan deze op onze computer op.

2. Decompileer de APK. Een decompiler in onze situatie is een tool die de APK neemt en Java-broncode produceert.

De eenvoudigste oplossing is om een online decompiler te gebruiken om het werk te doen. Ik heb op google gezocht naar " online decompliler " en ik heb gekozen voor https://www.javadecompilers.com/. Je hoeft alleen maar de APK te uploaden die je eerder hebt verkregen en

druk op decompileren. Dan download je gewoon de bronnen.

3. Probeer reverse-engineering door de code te kijken

Om het project te openen heb je een teksteditor nodig of beter nog een IDE (geïntegreerde ontwikkelomgeving). De standaard-IDE voor Android-projecten is Android Studio (https://developer.android.com/studio). Nadat je Android Studio hebt geïnstalleerd, open je de projectmap.

Omdat onze auto wordt bestuurd door bluetooth, begon ik mijn zoektocht in de gedecompileerde code met het trefwoord "bluetooth", van de gebeurtenissen die ik heb gevonden, was "BluetoothSerialService" in behandeling van de communicatie. Als deze klasse de communicatie afhandelt, moet deze een verzendopdrachtmethode hebben. Blijkt dat er één schrijfmethode is die gegevens via het Bluetooth-kanaal verzendt:

public void schrijven (byte uit)

Dit is een goed begin, ik heb gezocht naar de.write (methode die wordt gebruikt en er is een klasse "ZenWheelsMicrocar" die onze "BluetoothSerialService" uitbreidt. Deze klasse bevat de meeste logica van onze communicatie via Bluetooth. Het andere deel van de logica zit in de controllers: BaseController en StandardController.

In de BaseController hebben we de service-initialisatie, en ook definities van de stuur- en gaskanalen, kanalen zijn in feite commando-prefixen om aan te geven dat een bepaald type commando zal volgen:

beschermde ZenWheelsMicrocar microcar = nieuwe ZenWheelsMicrocar(this, this.btHandler);

beveiligde ChannelOutput uitgangen = {nieuwe TrimChannelOutput (ZenWheelsMicrocar. STEERING_CHANNEL), nieuwe TrimChannelOutput (ZenWheelsMicrocar. THROTTLE_CHANNEL)};

In de StandardController wordt de besturing verzorgd in:

public void handleSteering (TouchEvent touchEvent) {

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

Als we de methode analyseren, heeft steeringOutput.channel de waarde 129 (kanaal gebruikt voor besturing) en steeringOutput.resolveValue() kan een waarde hebben tussen -90 en 90. De kanaalwaarde (129) wordt direct verzonden en de stuurwaarde wordt gewijzigd door bitsgewijze bewerkingen toe te passen:

privé finale int value_convert_out(int value) {

booleaans negatief = onwaar; if (waarde < 0) { negatief = f6D; } int waarde2 = waarde & 63; if (negatief) { retourwaarde2 | 64; } retourwaarde2; }

Er is een vergelijkbare methode in de StandardController genaamd

public void handleThrottle (TouchEvent touchEvent)

Stap 3: Componenten

Onderdelen:

1. Arduino pro mini 328p 2 $

2. Broodplank

3. MPU6050-gyroscoop 1.2 $

4. HC-05 master-slave 6-pins module 3 $

5. 4 x AA-batterijpakket met 4 batterijen

6. U-vormige startkabels (optioneel). Ik heb deze startkabels gebruikt omdat ze er beter uitzien op het breadboard en de leds op deze manier beter zichtbaar zijn. Als je deze kabels niet hebt, kun je ze vervangen door dupont-draden.

Bovenstaande prijzen zijn afkomstig van eBay.

Gereedschap:

1. USB naar seriële FTDI-adapter FT232RL om de arduino pro mini te programmeren

2. Arduino-IDE

3. Android Studio (optioneel als je zelf reverse engineering wilt toepassen)

Stap 4: Montage

samenkomst
samenkomst

De montage is heel eenvoudig omdat we het op een breadboard doen:)

- eerst plaatsen we onze componenten op het breadboard: de microcontroller, bluetooth-module en gyroscoop

- verbind de HC-05 bluetooth RX- en TX-pinnen met arduino 10 en 11 pinnen. De gyroscoop SDA en SCL moeten worden aangesloten op de arduino A4- en A5-pinnen

- sluit de stroompinnen aan op de bluetooth, gyro en de arduino. de pinnen moeten worden aangesloten op de + en - aan de zijkant van het breadboard

- sluit als laatste een voeding (tussen 3,3 V tot 5 V) aan op het breadboard, ik heb een kleine LiPo-batterij met één cel gebruikt, maar elke batterij zal het doen zolang deze zich in het vermogensbereik bevindt

Controleer de foto's hierboven voor meer details!

Stap 5: Koppel de HC-05 Bluetooth aan de Microcar

Koppel de HC-05 Bluetooth aan de Microcar
Koppel de HC-05 Bluetooth aan de Microcar
Koppel de HC-05 Bluetooth aan de Microcar
Koppel de HC-05 Bluetooth aan de Microcar
Koppel de HC-05 Bluetooth aan de Microcar
Koppel de HC-05 Bluetooth aan de Microcar

Hiervoor heb je een Android telefoon, de bluetooth HC-05 module en de seriële FTDI adapter met draadjes nodig. We zullen ook de Arduino IDE gebruiken om te communiceren met de Bluetooth-module.

Eerst moeten we het Bluetooth-adres van de microcar achterhalen:

- Bluetooth inschakelen op je telefoon

- zet de auto aan en ga naar het bluetooth-gedeelte van je instellingen in Android

- zoek naar nieuwe apparaten en er zou een apparaat met de naam "Microcar" moeten verschijnen

- koppel met dit apparaat

- om vervolgens de Bluetooth MAC te extraheren, heb ik deze app gebruikt van google play Serial Bluetooth Terminal

Ga na het installeren van deze app naar menu -> apparaten en daar heb je een lijst met alle bluetooth-gekoppelde apparaten. We zijn alleen geïnteresseerd in de code onder de "Microcar"-mijn is 00:06:66:49:A0:4B

Sluit vervolgens de FTDI-adapter aan op de bluetooth-module. Eerst VCC en GROUND pinnen en dan FTDI RX naar bluetooth TX en FTDI TX naar bluetooth RX. Er moet ook een pin op de Bluetooth-module zitten die op de VCC moet worden aangesloten. Als u dit doet, gaat de Bluetooth-module in een "programmeerbare modus". Mijn module heeft een knop die de VCC verbindt met die speciale pin. Wanneer u de FTDI op de USB aansluit, moet deze met de pin aangesloten / knop ingedrukt zijn om naar deze speciale programmeerbare modus te gaan. De bluetooth bevestigt het invoeren van deze bedrijfsmodus door elke 2 seconden langzaam te knipperen.

Selecteer in de Arduino IDE de seriële poort, open vervolgens de seriële monitor (zowel NL als CR met 9600 baudrate). Typ AT en de module moet bevestigen met "OK".

Typ "AT+ROLE=1" om de module in de mastermodus te zetten. Om te koppelen met uw bluetooh-module schrijft u: "AT+BIND=0006, 66, 49A04B", Merk op hoe onze "00:06:66:49:A0:4B" wordt omgezet in "0006, 66, 49A04B". Nou, je zou dezelfde transformatie moeten doen voor je bluetooh MAC.

Schakel nu de Zenwheels-auto in, koppel de FTDI los en sluit hem opnieuw aan zonder dat de knop is ingedrukt / speciale pin is aangesloten. Na een tijdje zou het verbinding moeten maken met de auto en je zult merken dat de auto een specifiek succesvol verbindingsgeluid maakt.

Probleemoplossen:

- Ik ontdekte dat van alle Bluetooth-modules die ik had, alleen degene met een knop als master werkte!

- zorg ervoor dat de auto volledig is opgeladen

- zorg ervoor dat de auto niet is aangesloten op de telefoon

- als de Bluetooth in de AT-modus komt (langzaam knippert) maar niet reageert op het commando, zorg er dan voor dat je BEIDE NL & CR hebt, en experimenteer ook met andere BAUD-snelheden

- controleer nogmaals of de RX is aangesloten op TX en vice versa

- probeer deze tutorial

Stap 6: Code & gebruik

Eerst moet je twee bibliotheken downloaden en installeren:

1. MPU6050-bibliotheek voor de gyroscoop

2. I2CDev bibliotheekbron

Download en installeer dan mijn bibliotheek vanaf hier of kopieer het van onderaf:

/** * 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 commando Snelheid = 130;

bool initialisatie = false; // set true als DMP init succesvol was

uint8_t mpuIntStatus; // bevat actuele interruptstatusbyte van MPU uint8_t devStatus; // retourstatus na elke apparaatbewerking (0 = geslaagd, !0 = fout) uint16_t packetSize; // verwachte DMP-pakketgrootte (standaard is 42 bytes) uint16_t fifoCount; // telling van alle bytes die momenteel in FIFO zijn uint8_t fifoBuffer [64]; // FIFO-opslagbuffer Quaternion q; // [w, x, y, z] quaternioncontainer VectorFloat-zwaartekracht; // [x, y, z] zwaartekracht vector float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container en zwaartekracht vector vluchtige bool mpuInterrupt = false; // geeft aan of de MPU-interrupt-pin hoog is geworden

niet-ondertekend lang lastPrintTime, lastMoveTime = 0;

SoftwareSerial BTserial(10, 11);

MPU6050mpu;

ongeldige setup()

{ Serieel.begin (9600); BTserial.begin(38400); Serial.println("Programma gestart"); initialisatie = initialiserenGyroscope(); }

lege lus() {

if (!initialisatie) { return; } mpuInterrupt = onwaar; mpuIntStatus = mpu.getIntStatus(); fifoCount = mpu.getFIFOCount(); if (hasFifoOverflown(mpuIntStatus, fifoCount)) { mpu.resetFIFO(); opbrengst; } if (mpuIntStatus & 0x02) { while (fifoCount < packetSize) { fifoCount = mpu.getFIFOCount(); } mpu.getFIFOBytes(fifoBuffer, pakketgrootte); fifoCount -= pakketgrootte; mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &zwaartekracht); sturen (ypr[0] * 180/M_PI, ypr[1] * 180/M_PI, ypr[2] * 180/M_PI); } }

/*

* Ontvangt een hoek van 0 tot 180 waarbij 0 max links is en 180 max rechts * Ontvangt snelheid van -90 tot 90 waarbij -90 max achteruit is en 90 max vooruit */ void moveZwheelsCar (byte angle, int speed) { if (millis () - lastMoveTime = 90) { resultAngle = kaart (hoek, 91, 180, 1, 60); } else if (hoek 0) { resultaatSnelheid = kaart (snelheid, 0, 90, 0, 60); } else if (snelheid < 0) { resultSpeed = kaart (snelheid, 0, -90, 120, 60); } Serial.print("actualAngle=");Serial.print(hoek);Serial.print("; "); Serial.print("actualSpeed=");Serial.print(resultSpeed);Serial.println("; "); BTserial.write(commandStering); BTserial.write (resultaathoek); BTserial.write (commandoSnelheid); BTserial.write ((byte) resultaatsnelheid); lastMoveTime = millis(); }

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

{ x = beperking (x, -1 * MAX_ANGLE, MAX_ANGLE); y = beperking (y, -1 * MAX_ANGLE, MAX_ANGLE); z = beperking (z, -MAX_ANGLE, MAX_ANGLE); int-hoek = kaart (y, -MAX_ANGLE, MAX_ANGLE, 0, 180); int snelheid = kaart (z, -MAX_ANGLE, MAX_ANGLE, 90, -90); printDebug(x, y, z, hoek, snelheid); moveZwheelsCar (hoek, snelheid); }

void printDebug(int x, int y, int z, int hoek, int snelheid)

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

bool initializeGyroscope()

{ Draad.begin(); mpu.initialiseren(); Serial.println(mpu.testConnection() ? F("MPU6050 verbinding succesvol"): F("MPU6050 verbinding mislukt")); devStatus = mpu.dmpInitialize(); mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset (1788); if (devStatus != 0) { Serial.print(F("DMP-initialisatie mislukt (code"));Serial.println(devStatus); return false;} mpu.setDMPEnabled(true); Serial.println(F("Inschakelen interruptdetectie (Arduino externe interrupt 0)…")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); Serial.println(F("DMP gereed! Wachten op eerste onderbreking…")); packetSize = mpu.dmpGetFIFOPacketSize(); return true; }

void dmpDataReady()

{ mpuInterrupt = waar; }

boolean hasFifoOverflown(int mpuIntStatus, int fifoCount)

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

Upload de code met behulp van de FTDI-adapter naar de arduino en sluit vervolgens de batterijen aan.

De afstandsbediening gebruiken:

Nadat de Arduino is ingeschakeld, schakelt u ook de auto in. De HC-05-module moet verbinding maken met de auto, wanneer dat gebeurt, zal de auto een geluid produceren. Als het niet werkt, controleer dan de vorige stap en het gedeelte over het oplossen van problemen.

Als je het breadboard naar voren kantelt, moet de auto naar voren bewegen, naar rechts en de auto naar rechts. Het voert ook meer geleidelijke bewegingen uit, zoals een beetje naar voren hellen en een beetje naar links, in dit geval zou de auto langzaam naar links gaan.

Als de auto een andere kant op gaat bij het hellen van het breadboard, houd het breadboard dan eerst in verschillende richtingen.

Hoe het werkt:

De schets haalt elke 100 ms de gyroscoopcoördinaten op, maakt berekeningen en zendt vervolgens via bluetooth de autocommando's uit. Ten eerste is er een "stuur"-methode die wordt aangeroepen met de onbewerkte x-, y- en z-hoeken. Deze methode transformeert de besturing tussen 0 en 180 graden en de versnelling tussen -90 en 90. Deze methode roept

void moveZwheelsCar (byte-hoek, int-snelheid) die de besturing en versnelling converteert naar ZenWheels-specificaties en vervolgens de opdrachten verzendt met behulp van bluetooth.

De reden dat ik de transformatie in twee stappen heb gedaan, is herbruikbaarheid. als ik deze schets zou moeten aanpassen aan de afstandsbediening van een ander apparaat, zou ik beginnen met de basismethode "sturen" die de snelheid en besturing al in kaart brengt met enkele bruikbare waarden.

Stap 7: Alternatieven

Een alternatief voor de "reverse engineering". Ik heb het gehad over het reverse-engineeren van het project door te beginnen met de Android-applicatie. Maar er is een alternatief hiervoor, je kunt een seriële FTDI + bluetooth-slave instellen (gewone HC-05 zonder de masterinstellingen op te geven). Maak vervolgens vanuit de ZenWheels-app verbinding met de HC-05 in plaats van de "microcar".

Om de commando's te decoderen, moet je het stuur in een bepaalde positie houden en vervolgens een pythonscript gebruiken om de seriële communicatie te analyseren. Ik stel een python-script voor omdat er niet-afdrukbare tekens zijn en Arduino IDE is daar niet geschikt voor. U zult zien dat als u het wiel in één positie houdt, de app regelmatig dezelfde twee bytes verzendt. Als u de wielpositie verandert, blijft de eerste byte hetzelfde, de tweede verandert. Na veel testen kun je het stuuralgoritme bedenken, vervolgens de gashendel reverse engineeren, enz.

Een alternatief voor de op Arduino gebaseerde afstandsbediening zou een RaspberryPi-afstandsbediening zijn. De raspberry pi heeft een ingebouwde bluetooth-module die pijnloos is in te stellen in de "master" -modus en de python bluetooth-bibliotheek werkt als een tierelier. Er zijn ook enkele interessantere projecten mogelijk, zoals het besturen van de auto met Alexa echo:)

Ik hoop dat je het project leuk vond en laat hieronder een reactie achter!

Aanbevolen: