Satura rādītājs:

Pašbalansējošs robots no Magicbit: 6 soļi
Pašbalansējošs robots no Magicbit: 6 soļi

Video: Pašbalansējošs robots no Magicbit: 6 soļi

Video: Pašbalansējošs robots no Magicbit: 6 soļi
Video: Magicbit - Learning Tool for Coding, Electronics, Robotics & IoT 2024, Novembris
Anonim

Šī apmācība parāda, kā izveidot pašbalansējošu robotu, izmantojot Magicbit dev dēli. Šajā projektā, kura pamatā ir ESP32, mēs izmantojam magicbit. Tāpēc šajā projektā var izmantot jebkuru ESP32 izstrādes plati.

Piegādes:

  • burvju bits
  • Divu H-tilta L298 motora vadītājs
  • Lineārais regulators (7805)
  • Lipo 7.4V 700mAh akumulators
  • Inerciālās mērīšanas vienība (IMU) (6 grādu brīvības)
  • pārnesumu motori 3V-6V DC

1. darbība: stāsts

Stāsts
Stāsts
Stāsts
Stāsts

Čau, šodien šajā apmācībā mēs uzzināsim par mazliet sarežģītu lietu. Tas ir par pašbalansējošu robotu, izmantojot Magicbit ar Arduino IDE. Tātad, sāksim.

Vispirms apskatīsim, kas ir pašbalansējošs robots. Pašbalansējošais robots ir divriteņu robots. Īpašā iezīme ir tā, ka robots var līdzsvarot sevi, neizmantojot ārēju atbalstu. Kad barošana ir ieslēgta, robots pieceļas kājās un pēc tam nepārtraukti līdzsvarojas, izmantojot svārstību kustības. Tātad tagad jums ir aptuvens priekšstats par pašbalansējošu robotu.

2. darbība: teorija un metodoloģija

Teorija un metodika
Teorija un metodika

Lai līdzsvarotu robotu, vispirms mēs iegūstam datus no kāda sensora, lai izmērītu robota leņķi pret vertikālo plakni. Šim nolūkam mēs izmantojām MPU6050. Pēc datu iegūšanas no sensora mēs aprēķinām slīpumu uz vertikālo plakni. Ja robots atrodas taisnā un līdzsvarotā stāvoklī, tad slīpuma leņķis ir nulle. Ja nē, tad slīpuma leņķis ir pozitīva vai negatīva vērtība. Ja robots ir noliekts uz priekšpusi, tad robotam jāpāriet uz priekšējo virzienu. Arī tad, ja robots ir noliekts atpakaļgaitā, robotam jāpārvietojas pretējā virzienā. Ja šis slīpuma leņķis ir augsts, reakcijas ātrumam jābūt lielam. Un otrādi, slīpuma leņķis ir zems, tad reakcijas ātrumam jābūt zemam. Lai kontrolētu šo procesu, mēs izmantojām īpašu teorēmu ar nosaukumu PID. PID ir kontroles sistēma, ko izmantoja daudzu procesu kontrolei. PID apzīmē 3 procesus.

  • P- proporcionāls
  • Es- neatņemama
  • D- atvasinājums

Katrai sistēmai ir ieeja un izeja. Tādā pašā veidā šai vadības sistēmai ir arī daži ievadi. Šajā kontroles sistēmā tā ir novirze no stabila stāvokļa. Mēs to saucām par kļūdu. Mūsu robotā kļūda ir slīpuma leņķis no vertikālās plaknes. Ja robots ir līdzsvarots, slīpuma leņķis ir nulle. Tātad kļūdas vērtība būs nulle. Tāpēc PID sistēmas izeja ir nulle. Šī sistēma ietver trīs atsevišķus matemātiskos procesus.

Pirmais ir reizināšanas kļūda no skaitliskā pieauguma. Šo ieguvumu parasti sauc par Kp

P = kļūda*Kp

Otrais ir ģenerēt kļūdas integrāli laika domēnā un reizināt to ar daļu no ieguvumiem. Šo ieguvumu sauca par Ki

I = integrālis (kļūda)*Ki

Trešais ir atvasinājums no kļūdas laika jomā un reiziniet to ar zināmu ieguvumu. Šo pieaugumu sauc par Kd

D = (d (kļūda)/dt)*kd

Pēc iepriekš minēto darbību pievienošanas mēs iegūstam galīgo rezultātu

Izeja = P+I+D

P daļas dēļ robots var iegūt stabilu stāvokli, kas ir proporcionāls novirzei. I daļa aprēķina kļūdu apgabalu un laika grafiku. Tādējādi tas vienmēr cenšas panākt robota stabilu stāvokli. D daļa mēra slīpumu laikā pret kļūdu grafiku. Ja kļūda palielinās, šī vērtība ir pozitīva. Ja kļūda samazinās, šī vērtība ir negatīva. Tāpēc, kad robots tiek pārvietots stabilā stāvoklī, reakcijas ātrums samazināsies, un tas palīdzēs novērst nevajadzīgus pārsniegumus. Jūs varat uzzināt vairāk par PID teoriju, izmantojot šo saiti, kas parādīta zemāk.

www.arrow.com/en/research-and-events/articles/pid-controller-basics-and-tutorial-pid-implementation-in-arduino

PID funkcijas izeja ir ierobežota līdz 0-255 diapazonam (8 bitu PWM izšķirtspēja), un tā tiks padota motoriem kā PWM signāls.

3. darbība. Aparatūras iestatīšana

Aparatūras iestatīšana
Aparatūras iestatīšana

Tagad šī ir aparatūras iestatīšanas daļa. Robota dizains ir atkarīgs no jums. Izstrādājot robota ķermeni, jāņem vērā tā simetriskā attiecība pret vertikālo asi, kas atrodas motora asī. Akumulatora bloks atrodas zemāk. Tāpēc robotu ir viegli līdzsvarot. Savā dizainā mēs piestiprinām Magicbit dēli vertikāli pie korpusa. Mēs izmantojām divus 12V pārnesumu motorus. Bet jūs varat izmantot jebkāda veida pārnesumu motorus. tas ir atkarīgs no jūsu robota izmēriem.

Kad mēs apspriežam ķēdi, to darbina 7,4 V Lipo akumulators. Barošanai Magicbit izmantoja 5V. Tāpēc mēs izmantojām 7805 regulatoru, lai regulētu akumulatora spriegumu līdz 5 V. Vēlākajās Magicbit versijās šis regulators nav nepieciešams. Tā kā tas baro līdz 12 V. Mēs tieši piegādājam 7.4V motora vadītājam.

Pievienojiet visas sastāvdaļas saskaņā ar zemāk redzamo diagrammu.

4. solis: programmatūras iestatīšana

Kodā mēs izmantojām PID bibliotēku, lai aprēķinātu PID izvadi.

Dodieties uz šo saiti, lai to lejupielādētu.

www.arduinolibraries.info/libraries/pid

Lejupielādējiet tās jaunāko versiju.

Lai iegūtu labākus sensora rādījumus, mēs izmantojām DMP bibliotēku. DMP apzīmē ciparu kustības procesu. Šī ir iebūvēta MPU6050 funkcija. Šai mikroshēmai ir integrēta kustības procesa vienība. Tāpēc ir jālasa un jāanalizē. Pēc tam tas mikrokontrolleram (šajā gadījumā Magicbit (ESP32)) ģenerē precīzus skaņas signālus. Bet mikrokontrollera pusē ir daudz darbu, lai ņemtu šos rādījumus un aprēķinātu leņķi. Vienkārši, ka mēs izmantojām MPU6050 DMP bibliotēku. Lejupielādējiet to, dodoties uz šo saiti.

github.com/ElectronicCats/mpu6050

Lai instalētu bibliotēkas, Arduino izvēlnē dodieties uz rīkiem-> iekļaut bibliotēku-> add.zip bibliotēku un atlasiet lejupielādēto bibliotēkas failu.

Kodā pareizi jāmaina uzdotās vērtības leņķis. PID konstantu vērtības katram robotam ir atšķirīgas. Noskaņojot to, vispirms iestatiet Ki un Kd vērtības nullei un pēc tam palieliniet Kp, līdz iegūstat labāku reakcijas ātrumu. Vairāk Kp izraisa vairāk pārsniegumu. Pēc tam palieliniet Kd vērtību. Palieliniet to vienmēr ļoti nelielā daudzumā. Šī vērtība parasti ir zema nekā citas vērtības. Tagad palieliniet Ki, līdz iegūstat ļoti labu stabilitāti.

Izvēlieties pareizo COM portu un tāfeles tipu. augšupielādējiet kodu. Tagad jūs varat spēlēt ar savu DIY robotu.

5. darbība. Shēmas

Shēmas
Shēmas

6. darbība: kods

#iekļaut

#include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif MPU6050 mpu; bool dmpReady = nepatiess; // iestatīt patiesu, ja DMP init bija veiksmīgs uint8_t mpuIntStatus; // satur faktisko pārtraukšanas statusa baitu no MPU uint8_t devStatus; // atgriešanās statuss pēc katras ierīces darbības (0 = veiksme,! 0 = kļūda) uint16_t packetSize; // paredzamais DMP paketes izmērs (noklusējums ir 42 baiti) uint16_t fifoCount; // visu baitu skaits, kas pašlaik atrodas FIFO uint8_t fifoBuffer [64]; // FIFO krātuves buferis Quaternion q; // [w, x, y, z] kvaterniona konteiners VectorFloat gravity; // [x, y, z] gravitācijas vektora pludiņš ypr [3]; // [pagrieziens, slīpums, pagrieziens] satricinājums/slīpuma/ruļļa konteiners un smaguma vektors double originalSetpoint = 172,5; dubultā uzdotā vērtība = originalSetpoint; dubultā kustībaAngleOffset = 0,1; dubultā ieeja, izeja; int moveState = 0; dubultā Kp = 23; // iestatiet P pirmo dubulto Kd = 0,8; // šai vērtībai parasti ir mazs dubultā Ki = 300; // šai vērtībai vajadzētu būt lielai, lai nodrošinātu labāku stabilitāti PID pid (& ievade, & izvade, & iestatītā vērtība, Kp, Ki, Kd, DIRECT); // pid inicializēt int motL1 = 26; // 4 tapas motora piedziņai int motL2 = 2; int motR1 = 27; int motR2 = 4; gaistošs bool mpuInterrupt = false; // norāda, vai MPU pārtraukšanas pin ir kļuvis liels void dmpDataReady () {mpuInterrupt = true; } void setup () {ledcSetup (0, 20000, 8); // pwm setup ledcSetup (1, 20000, 8); ledcSetup (2, 20000, 8); ledcSetup (3, 20000, 8); ledcAttachPin (motL1, 0); // motoru pinmode ledcAttachPin (motL2, 1); ledcAttachPin (motR1, 2); ledcAttachPin (motR2, 3); // pievienoties I2C kopnei (I2Cdev bibliotēka to nedara automātiski) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin (); Wire.setClock (400000); // 400 kHz I2C pulkstenis. Komentējiet šo rindiņu, ja rodas apkopošanas grūtības #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire:: setup (400, true); #endif Serial.println (F ("I2C ierīču inicializēšana …")); pinMode (14, INPUT); // inicializēt seriālo komunikāciju // (115200 izvēlēts, jo tas ir nepieciešams tējkannas demonstrācijas izvadei, bet tas ir // patiešām atkarīgs no jūsu projekta) Serial.begin (9600); kamēr (! Seriāls); // gaidiet Leonardo uzskaitījumu, citi tūlīt turpina // inicializēt ierīci Serial.println (F ("I2C ierīču inicializēšana …")); mpu.initialize (); // pārbaudīt savienojumu Serial.println (F ("Ierīču savienojumu pārbaude …")); Serial.println (mpu.testConnection ()? F ("MPU6050 savienojums izdevies"): F ("MPU6050 savienojums neizdevās")); // ielādēt un konfigurēt DMP Serial.println (F ("DMP inicializēšana …")); devStatus = mpu.dmpInitialize (); // šeit ievadiet savus žiroskopu nobīdes, pielāgojot minimālajai jutībai mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1788); // 1688 rūpnīcas noklusējuma iestatījums manai testa mikroshēmai // pārliecinieties, vai tā darbojās (ja tā atgriež 0), ja (devStatus == 0) {// ieslēdziet DMP tagad, kad tas ir gatavs Serial.println (F ("Iespējojot DMP … ")); mpu.setDMPEnabled (true); // iespējot Arduino pārtraukuma noteikšanu Serial.println (F ("Pārtraukuma noteikšanas iespējošana (Arduino ārējais pārtraukums 0)…")); attachInterrupt (14, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus (); // iestatiet mūsu DMP Ready karodziņu, lai galvenā cilpa () funkcija zinātu, ka ir pareizi to izmantot Serial.println (F ("DMP gatavs! Gaida pirmo pārtraukumu …")); dmpReady = true; // iegūt paredzamo DMP paketes izmēru vēlākai salīdzināšanai packetSize = mpu.dmpGetFIFOPacketSize (); // iestatīšana PID pid. SetMode (AUTOMATIC); pid. SetSampleTime (10); pid. SetOutputLimits (-255, 255); } cits {// KĻŪDA! // 1 = sākotnējā atmiņas ielāde neizdevās // 2 = DMP konfigurācijas atjauninājumi neizdevās // (ja tas pārtrauks, parasti kods būs 1) Serial.print (F ("DMP inicializācija neizdevās (kods))); Seriāls. print (devStatus); Serial.println (F (")")); }} void loop () {// ja programmēšana neizdevās, nemēģiniet neko darīt, ja (! dmpReady) atgriežas; // gaidiet MPU pārtraukumu vai papildu paketi (-es), kamēr (! mpuInterrupt && fifoCount <packetSize) {pid. Compute (); // šis laika periods tiek izmantots datu ielādei, lai to varētu izmantot citiem aprēķiniem motorSpeed (izvade); } // atiestatīt pārtraukuma karodziņu un iegūt INT_STATUS baitu mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus (); // iegūt pašreizējo FIFO skaitu fifoCount = mpu.getFIFOCount (); // pārbaudiet, vai nav pārplūdes (tam nekad nevajadzētu notikt, ja vien mūsu kods nav pārāk neefektīvs), ja ((mpuIntStatus & 0x10) || fifoCount == 1024) {// atiestatiet, lai mēs varētu turpināt tīri mpu.resetFIFO (); Serial.println (F ("FIFO pārpilde!")); // pretējā gadījumā pārbaudiet, vai DMP dati ir gatavi pārtraukt (tam vajadzētu notikt bieži)} else if (mpuIntStatus & 0x02) {// gaidīt pareizo pieejamo datu garumu, jāgaida ĻOTI īsi, kamēr (fifoCount 1 pakete pieejama // (šī ļaujiet mums nekavējoties lasīt vairāk, negaidot pārtraukumu) print ("ypr / t"); Serial.print (ypr [0] * 180/M_PI); // euler leņķi Serial.print ("\ t"); Serial.print (ypr [1] * 180/M_PI); Serial.print ("\ t"); Serial.println (ypr [2] * 180/M_PI); #endif input = ypr [1] * 180/M_PI + 180;}} void motorSpeed (int PWM) {float L1, L2, R1, R2; ja (PWM> = 0) {// virziens uz priekšu L2 = 0; L1 = abs (PWM); R2 = 0; R1 = abs (PWM); ja (L1> = 255) { L1 = R1 = 255;}} cits {// atpakaļgaitas virziens L1 = 0; L2 = abs (PWM); R1 = 0; R2 = abs (PWM); ja (L2> = 255) {L2 = R2 = 255; }} // motora piedziņa ledcWrite (0, L1); ledcWrite (1, L2); ledcWrite (2, R1*0,97); // 0,97 ir ātruma fakts vai tāpēc, ka labajam motoram ir liels ātrums nekā kreisajam motoram, tāpēc mēs to samazinām, līdz motora ātrums ir vienāds ledcWrite (3, R2*0,97);

}

Ieteicams: