Turinys:

„Hackable“nuotolinio valdymo pultas „ZenWheels Microcar“: 7 žingsniai
„Hackable“nuotolinio valdymo pultas „ZenWheels Microcar“: 7 žingsniai

Video: „Hackable“nuotolinio valdymo pultas „ZenWheels Microcar“: 7 žingsniai

Video: „Hackable“nuotolinio valdymo pultas „ZenWheels Microcar“: 7 žingsniai
Video: 4 Channel RF Transmitter | How to make a Remote controller #jlcpcb 2024, Birželis
Anonim
Image
Image
Surinkimas
Surinkimas

Šioje pamokoje mes sukursime individualų „ZenWheels“mikroautobuso nuotolinio valdymo pultą. „ZenWheels“mikroautobusas yra 5 cm žaislinis automobilis, kurį galima valdyti naudojant „Android“arba „iPhone“programą. Aš jums parodysiu, kaip pakeisti „Android“programą, kad sužinotumėte apie ryšio protokolą ir kaip galite sukurti nuotolinio valdymo pultą naudodami arduino ir giroskopą.

1 žingsnis: komponentai ir įrankiai

Dalys:

1. „ZenWheels“mikroautobusas

2. Arduino pro mini 328p

3. Duonos lenta

4. MPU6050 giroskopas

5. maitinimo šaltinis <= 5 v (kai kuri baterija, kurią galime prijungti prie duonos lentos)

6. U formos jungiamieji kabeliai (neprivaloma). Aš naudoju šiuos trumpiklius, nes jie geriau atrodo ant lentos. Vietoj to galima naudoti įprastus trumpiklius

7. „Bluetooth“modulis HC-05 (su mygtuku įjungti AT režimą)

Įrankiai:

1. USB į nuoseklųjį FTDI adapterį FT232RL „Arduino pro mini“programavimui

2. „Arduino IDE“

3. „Android“telefonas

4. „Android Studio“[pasirenkama]

2 veiksmas: atvirkštinė „ZenWheels“„Android“programos kūrimas [neprivaloma]

Norint suprasti šią dalį, reikia šiek tiek išmanyti „Java“ir „Android“.

Projekto tikslas - valdyti mikroautobusą naudojant giroskopą. Norėdami tai padaryti, turime daugiau sužinoti apie „Bluetooth“ryšį tarp šio žaislo ir „Android“programos.

Šiame žingsnyje paaiškinsiu, kaip pakeisti mikrokomandos ir „Android“programos ryšio protokolą. Jei norite sukurti nuotolinio valdymo pultą, šis žingsnis nėra būtinas. Vienas iš būdų atrasti protokolą yra pažvelgti į šaltinio kodą. Hmm, bet tai nėra tiesiai į priekį, „Android“programos yra sukompiliuotos ir galima įdiegti apk per „Google Play“.

Taigi aš padariau pagrindinį vadovą, kaip tai padaryti:

1. Atsisiųskite APK. „Android“paketų rinkinys (trumpai APK) yra paketo failo formatas, kurį „Android“operacinė sistema naudoja platindama ir diegdama programas mobiliesiems

Pirmiausia ieškokite programos „Google Play“parduotuvėje, mūsų atveju ieškokite „zenwheels“ir gausite programos nuorodą

Tada „Google“ieškokite „online apk downloader“ir naudokite jį, kad atsisiųstumėte apk. Paprastai jie paprašys programos nuorodos (tos, kurią gavome anksčiau), tada paspausime atsisiuntimo mygtuką ir išsaugosime jį savo kompiuteryje.

2. Išpakuoti APK. Mūsų situacijoje dekompiliatorius yra įrankis, kuris paima APK ir sukuria „Java“šaltinio kodą.

Paprasčiausias sprendimas yra naudoti internetinį dekompiliatorių. „Google“ieškojau „internetinio dekomplikatoriaus“ir pasirinkau https://www.javadecompilers.com/. Jums tereikia įkelti anksčiau gautą APK ir

paspauskite dekompiliuoti. Tada tiesiog atsisiųskite šaltinius.

3. Pabandykite pakeisti inžinieriaus kodą

Norėdami atidaryti projektą, jums reikia teksto redaktoriaus arba geresnio IDE (integruotos kūrimo aplinkos). Numatytoji „Android“projektų IDE yra „Android Studio“(https://developer.android.com/studio). Įdiegę „Android Studio“, atidarykite projekto aplanką.

Kadangi mūsų automobilis valdomas „Bluetooth“ryšiu, pradėjau paiešką dekompiliuotu kodu su raktiniu žodžiu „bluetooth“, iš įvykių, kuriuos radau, „BluetoothSerialService“palaikė ryšį. Jei ši klasė tvarko ryšį, ji turi turėti siuntimo komandos metodą. Pasirodo, yra vienas rašymo būdas, kuris siunčia duomenis per „Bluetooth“kanalą:

public void write (baitas out)

Tai gera pradžia, ieškojau.write (naudojamas metodas ir yra klasė „ZenWheelsMicrocar“, kuri praplečia mūsų „BluetoothSerialService“. Šioje klasėje yra dauguma mūsų bendravimo per „Bluetooth“logikos. Kita dalis logika yra valdikliuose: „BaseController“ir „StandardController“.

„BaseController“turime paslaugų inicijavimą, taip pat vairo ir droselio kanalų apibrėžimus, kanalai iš tikrųjų yra komandų priešdėliai, nurodantys, kad bus vykdomas tam tikras komandų tipas:

apsaugotas „ZenWheelsMicrocar“mikroautobusas = naujas „ZenWheelsMicrocar“(šis, šis.btHandleris);

apsaugotas „ChannelOutput išėjimas = {naujas„ TrimChannelOutput “(„ ZenWheelsMicrocar. STEERING_CHANNEL “), naujas„ TrimChannelOutput “(„ ZenWheelsMicrocar. THROTTLE_CHANNEL “}});

„StandardController“valdymas valdomas taip:

public void handleValdymas („TouchEvent touchEvent“) {

… This.microcar.setChannel (ohjausOutput.channel, }

Analizuodamas metodą, „ohjausOutput.channel“turi reikšmę 129 (kanalas, naudojamas vairui), o „ohjausOutput.resolveValue“() reikšmė gali būti nuo –90 iki 90. Kanalo reikšmė (129) siunčiama tiesiogiai, o vairo vertė keičiama taikant operacijas bitinėmis operacijomis:

private final int value_convert_out (int value) {

loginis neigiamas = klaidingas; jei (reikšmė <0) {neigiama = f6D; } int vertė2 = vertė & 63; jei (neigiamas) {grąžinimo vertė2 | 64; } grąžinimo vertė2; }

„StandardController“yra panašus metodas, vadinamas

viešoji tuštumos rankena Droselis („TouchEvent touchEvent“)

3 žingsnis: komponentai

Dalys:

1. „Arduino pro mini 328p 2 $“

2. Duonos lenta

3. MPU6050 giroskopas 1,2 $

4. HC-05 pagrindinis-valdomas 6 kontaktų modulis 3 $

5. 4 x AA baterijų paketas su 4 baterijomis

6. U formos jungiamieji kabeliai (neprivaloma). Aš naudoju šiuos trumpiklius, nes jie geriau atrodo ant duonos lentos, o šviesos diodai yra labiau matomi. Jei neturite šių kabelių, galite juos pakeisti dupontiniais laidais.

Aukščiau pateiktos kainos yra paimtos iš „eBay“.

Įrankiai:

1. USB į nuoseklųjį FTDI adapterį FT232RL, skirtą programuoti arduino pro mini

2. „Arduino IDE“

3. „Android Studio“(neprivaloma, jei norite pakeisti inžineriją patys)

4 žingsnis: Surinkimas

Surinkimas
Surinkimas

Surinkimas yra labai paprastas, nes mes tai darome ant duonos lentos:)

- Pirmiausia mes dedame savo komponentus ant duonos lentos: mikrovaldiklį, „Bluetooth“modulį ir giroskopą

- prijunkite „HC-05“„Bluetooth“RX ir TX kaiščius prie „arduino“10 ir 11 kontaktų. Giroskopas SDA ir SCL turi būti prijungtas prie arduino A4 ir A5 kaiščių

- prijunkite maitinimo kaiščius prie „Bluetooth“, giroskopo ir arduino. kaiščiai turi būti prijungti prie + ir - duonos lentos šono

- paskutinį kartą prie maitinimo plokštės prijunkite maitinimo šaltinį (nuo 3,3 V iki 5 V), aš naudojau mažą vieno elemento „LiPo“bateriją, bet bet kuri veiks tol, kol bus maitinimo diapazone

Norėdami gauti daugiau informacijos, patikrinkite aukščiau esančias nuotraukas

5 veiksmas: suporuokite „HC-05 Bluetooth“su „Microcar“

Suporuokite „HC-05 Bluetooth“su „Microcar“
Suporuokite „HC-05 Bluetooth“su „Microcar“
Suporuokite „HC-05 Bluetooth“su „Microcar“
Suporuokite „HC-05 Bluetooth“su „Microcar“
Suporuokite „HC-05 Bluetooth“su „Microcar“
Suporuokite „HC-05 Bluetooth“su „Microcar“

Tam jums reikės „Android“telefono, „Bluetooth“HC-05 modulio ir nuoseklaus FTDI adapterio su laidais. Be to, mes naudosime „Arduino IDE“, kad galėtume bendrauti su „Bluetooth“moduliu.

Pirmiausia turime išsiaiškinti mikroautobuso „Bluetooth“adresą:

- įjunkite „Bluetooth“savo telefone

- įjunkite automobilį ir eikite į „Android“nustatymų „Bluetooth“skyrių

- ieškokite naujų įrenginių ir turėtų pasirodyti koks nors įrenginys, pavadintas „Microcar“

- suporuoti su šiuo prietaisu

- tada norėdamas išgauti „Bluetooth“MAC, aš naudoju šią programą iš „Google Play“serijinio „Bluetooth“terminalo

Įdiegę šią programą, eikite į meniu -> įrenginiai ir ten turėsite sąrašą su visais „Bluetooth“suporuotais įrenginiais. Mus domina tik kodas, esantis žemiau „Microcar“kasyklos, 00: 06: 66: 49: A0: 4B

Tada prijunkite FTDI adapterį prie „Bluetooth“modulio. Pirmiausia VCC ir GROUND kaiščiai, o tada FTDI RX į „Bluetooth TX“ir FTDI TX į „Bluetooth RX“. Be to, „Bluetooth“modulyje turėtų būti kaištis, kuris turėtų būti prijungtas prie VCC. Tai darydamas „Bluetooth“modulis pereina į „programuojamą režimą“. Mano modulyje yra mygtukas, jungiantis VCC su tuo specialiu kaiščiu. Kai prijungiate FTDI prie USB, jis turi būti prijungtas prie kaiščio / mygtuko, kad įeitumėte į šį specialų programuojamą režimą. „Bluetooth“patvirtina, kad įjungia šį veikimo režimą, lėtai mirksėdamas kas 2 sekundes.

„Arduino IDE“pasirinkite nuoseklųjį prievadą, tada atidarykite nuoseklųjį monitorių (tiek NL, tiek CR su 9600 baudų greičiu). Įveskite AT ir modulis turėtų patvirtinti „Gerai“.

Norėdami įjungti pagrindinį režimą, įveskite „AT+ROLE = 1“. Norėdami susieti su „bluetooh“moduliu, parašykite: „AT+BIND = 0006, 66, 49A04B“, atkreipkite dėmesį, kaip mūsų „00: 06: 66: 49: A0: 4B“paverčiamas į „0006, 66, 49A04B“. Na, jūs turėtumėte padaryti tą pačią transformaciją ir savo bluetooh MAC.

Dabar įjunkite „Zenwheels“automobilį, tada atjunkite FTDI ir vėl prijunkite jį, nepaspaudę mygtuko / prijungto specialaus kaiščio. Po kurio laiko jis turėtų prisijungti prie automobilio ir pastebėsite, kad automobilis skleidžia konkretų ryšį.

Problemų sprendimas:

- Radau, kad iš visų turimų „Bluetooth“modulių tik vienas su mygtuku veikė kaip meistras!

- įsitikinkite, kad automobilis yra visiškai įkrautas

- įsitikinkite, kad automobilis nėra prijungtas prie telefono

- jei „Bluetooth“įjungia AT režimą (lėtai mirksi), bet nereaguoja į komandą, įsitikinkite, kad turite abu NL ir CR, taip pat eksperimentuokite su kitais BAUD dažniais

- dar kartą patikrinkite, ar RX yra prijungtas prie TX, ir atvirkščiai

- Išbandykite šią pamoką

6 žingsnis: kodas ir naudojimas

Pirmiausia turite atsisiųsti ir įdiegti dvi bibliotekas:

1. MPU6050 biblioteka giroskopui

2. I2CDev bibliotekos šaltinis

Tada atsisiųskite ir įdiekite mano biblioteką iš čia arba nukopijuokite ją iš apačios:

/** * Bibliotekos: * 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 baitų komandaStering = 129; const baitų komandaSpeed = 130;

bool inicializacija = klaidinga; // nustatyti true, jei DMP inicijavimas buvo sėkmingas

uint8_t mpuIntStatus; // turi faktinį pertraukimo būsenos baitą iš MPU uint8_t devStatus; // grąžinti būseną po kiekvienos įrenginio operacijos (0 = sėkmė,! 0 = klaida) uint16_t packetSize; // numatomas DMP paketo dydis (numatytasis yra 42 baitai) uint16_t fifoCount; // visų baitų skaičius šiuo metu FIFO uint8_t fifoBuffer [64]; // FIFO saugojimo buferis Quaternion q; // [w, x, y, z] kvaterniono konteineris VectorFloat gravity; // [x, y, z] gravitacijos vektoriaus plūdė ypr [3]; // [posūkis, žingsnis, ritinys] posūkis/žingsnis/ritininis konteineris ir gravitacijos vektorius nepastovus bool mpuInterrupt = false; // rodo, ar MPU pertraukimo kaištis pakilo aukštai

unsigned long lastPrintTime, lastMoveTime = 0;

SoftwareSerial BTserial (10, 11);

MPU6050 mpu;

negaliojanti sąranka ()

{Serial.begin (9600); BTserial.begin (38400); Serial.println („Programa paleista“); inicializacija = initializeGyroscope (); }

void loop () {

if (! inicializacija) {return; } mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus (); fifoCount = mpu.getFIFOCount (); if (hasFifoOverflown (mpuIntStatus, fifoCount)) {mpu.resetFIFO (); grįžti; } if (mpuIntStatus & 0x02) {while (fifoCount <packetSize) {fifoCount = mpu.getFIFOCount (); } mpu.getFIFOBytes (fifoBuffer, packetSize); fifoCount -= packetSize; mpu.dmpGetQuaternion (& q, fifoBuffer); mpu.dmpGetGravity (& gravitacija, & q); mpu.dmpGetYawPitchRoll (ypr, & q, & gravity); vairuoti (ypr [0] * 180/M_PI, ypr [1] * 180/M_PI, ypr [2] * 180/M_PI); }}

/*

* Gaunamas kampas nuo 0 iki 180, kur 0 yra maksimalus kairysis ir 180 yra maksimalus dešinysis * Gauna greitį nuo -90 iki 90, kai -90 yra maksimalus atgal ir 90 yra didžiausias į priekį */ void moveZwheelsCar (baitų kampas, vidinis greitis) {if (millis () - lastMoveTime = 90) {resultAngle = žemėlapis (kampas, 91, 180, 1, 60); } else if (kampas 0) {resultSpeed = žemėlapis (greitis, 0, 90, 0, 60); } else if (greitis <0) {resultSpeed = žemėlapis (greitis, 0, -90, 120, 60); } Serijinis atspaudas ("faktinisAnglis ="); Serijinis atspaudas (kampas); Serijinis atspaudas (";"); Serial.print ("factSpeed ="); Serial.print (resultSpeed); Serial.println (";"); BTserial.write (commandStering); BTserial.write (resultAngle); BTserial.write (commandSpeed); BTserial.write ((baitas) resultSpeed); lastMoveTime = milis (); }

tuščias vairas (int x, int y, int z)

{x = apriboti (x, -1 * MAX_ANGLE, MAX_ANGLE); y = apriboti (y, -1 * MAX_ANGLE, MAX_ANGLE); z = apriboti (z, -MAX_ANGLE, MAX_ANGLE); int kampas = žemėlapis (y, -MAX_ANGLE, MAX_ANGLE, 0, 180); int greitis = žemėlapis (z, -MAX_ANGLE, MAX_ANGLE, 90, -90); printDebug (x, y, z, kampas, greitis); moveZwheelsCar (kampas, greitis); }

void print Debug (int x, int y, int z, int kampas, int greitis)

{if (millis () - lastPrintTime <1000) {return; } Serial.print ("z ="); Serial.print (x); Serial.print (";"); Serijinis atspaudas ("y ="); Serijinis atspaudas (y); Serijos spausdinimas (";"); Serial.print ("z ="); Serial.print (z); Serial.print (";"); Serial.print ("kampas ="); Serial.print (kampas); Serial.print (";"); Serial.print ("speed ="); Serial.print (sparta); Serial.println (";"); lastPrintTime = milis (); }

bool inicializuotiGiroskopas ()

{Wire.begin (); mpu.initialize (); Serial.println (mpu.testConnection ()? F ("MPU6050 ryšys sėkmingas"): F ("MPU6050 ryšys nepavyko")); devStatus = mpu.dmpInitialize (); mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1788); if (devStatus! = 0) {Serial.print (F ("DMP inicijavimas nepavyko (kodas))); Serial.println (devStatus); return false;} mpu.setDMPEnabled (true); Serial.println (F (" Įjungiama pertraukimo aptikimas („Arduino“išorinis pertraukimas 0)… "")); attachInterrupt (0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus (); Serial.println (F („DMP paruoštas! Laukiama pirmo pertraukimo …“)); packetSize = mpu.dmpGetFIFOPacketSize (); return true;}

void dmpDataReady ()

{mpuInterrupt = tiesa; }

loginis hasFifoOverflown (int mpuIntStatus, int fifoCount)

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

Įkelkite kodą naudodami FTDI adapterį į arduino, tada prijunkite baterijas.

Naudojant nuotolinio valdymo pultą:

Įjungus arduino, taip pat įjunkite automobilį. HC-05 modulis turėtų būti prijungtas prie automobilio, kai tai atsitiks, automobilis skleis garsą. Jei tai neveikia, patikrinkite ankstesnį veiksmą ir trikčių šalinimo skyrių.

Jei pakreipiate duonos lentą į priekį, automobilis turėtų judėti į priekį, į dešinę, o automobilis - į dešinę. Jis taip pat atlieka laipsniškesnius judesius, pavyzdžiui, šiek tiek pasviręs į priekį ir šiek tiek į kairę, tokiu atveju automobilis lėtai eitų į kairę.

Jei automobilis važiuoja kitaip, kai jis pasviręs, pirmiausia laikykite jį skirtingomis kryptimis.

Kaip tai veikia:

Eskizas gauna giroskopo koordinates kas 100 ms, atlieka skaičiavimus ir tada per „Bluetooth“perduoda automobilio komandas. Pirmiausia yra „vairavimo“metodas, kuris vadinamas neapdorotais x, y ir z kampais. Šis metodas vairą keičia nuo 0 iki 180 laipsnių, o pagreitis -nuo -90 iki 90. Šis metodas reikalauja

void moveZwheelsCar (baitų kampas, vidinis greitis), kuris vairą ir pagreitį paverčia „ZenWheels“specifikacijomis, o tada perduoda komandas naudodamas „Bluetooth“.

Priežastis, kodėl aš padariau pertvarką dviem etapais, yra pakartotinis naudojimas. jei man reiktų pritaikyti šį eskizą nuotolinio valdymo pultui kokiam nors kitam įrenginiui, pradėčiau nuo pagrindinio metodo „vairuoti“, kuris jau susieja greitį ir vairavimą su kai kuriomis naudingomis vertėmis.

7 žingsnis: alternatyvos

Alternatyva „atvirkštinei inžinerijai“. Aš kalbėjau apie tai, kaip pakeisti projektą, pradedant nuo „Android“programos. Tačiau yra alternatyva, galite nustatyti serijinį FTDI + „Bluetooth“vergą (įprastą HC-05, nenurodydami pagrindinių nustatymų). Tada iš „ZenWheels“programos prisijunkite prie „HC-05“, o ne „mikroautobuso“.

Norėdami iššifruoti komandas, turėsite laikyti vairą tam tikroje padėtyje, tada naudodami python scenarijų išanalizuokite nuoseklųjį ryšį. Aš siūlau „python“scenarijų, nes yra nespausdinamų simbolių, o „Arduino IDE“tam netinka. Pastebėsite, kad jei laikysite ratą vienoje padėtyje, programa reguliariai perduos tuos pačius du baitus. Jei pakeisite rato padėtį, kumštinis baitas išliks toks pats, kaip ir antrasis. Po daugelio bandymų galite sugalvoti vairavimo algoritmą, tada atvirkštinio inžinieriaus droselį ir pan.

Arduino pagrindu veikiančio nuotolinio valdymo pulto alternatyva būtų „RaspberryPi“nuotolinio valdymo pultas. „Raspberry pi“turi įterptą „Bluetooth“modulį, kurį nesudėtinga nustatyti „pagrindiniame“režime, o „python“„Bluetooth“biblioteka veikia kaip žavesys. Taip pat galimi keli įdomesni projektai, pavyzdžiui, automobilio valdymas naudojant „Alexa“aidą:)

Tikiuosi, kad jums patiko projektas ir palikite komentarus žemiau!

Rekomenduojamas: