Talaan ng mga Nilalaman:

Self Balancing Robot Mula sa Magicbit: 6 na Hakbang
Self Balancing Robot Mula sa Magicbit: 6 na Hakbang

Video: Self Balancing Robot Mula sa Magicbit: 6 na Hakbang

Video: Self Balancing Robot Mula sa Magicbit: 6 na Hakbang
Video: How to Make a Self Balancing Robot at Home Make Electrical Engineering Electric Electricity 2024, Nobyembre
Anonim

Ipinapakita ng tutorial na ito kung paano gumawa ng isang self balancing robot gamit ang Magicbit dev board. Gumagamit kami ng magicbit bilang development board sa proyektong ito na batay sa ESP32. Samakatuwid ang anumang ESP32 development board ay maaaring magamit sa proyektong ito.

Mga Pantustos:

  • magicbit
  • Dual driver ng motor na H-tulay L298
  • Linear Regulator (7805)
  • Lipo 7.4V 700mah na baterya
  • Inertial Measurement Unit (IMU) (6 deg ng kalayaan)
  • gear motor 3V-6V DC

Hakbang 1: Kwento

Kwento
Kwento
Kwento
Kwento

Hey guys, ngayon sa tutorial na ito matututunan natin ang tungkol sa maliit na kumplikadong bagay. Iyon ay tungkol sa self balancing robot gamit ang Magicbit na may Arduino IDE. Kaya't magsimula na.

Una sa lahat, hahanapin natin kung ano ang self balancing robot. Ang self robot sa pagbalanse ay dalawang robot na may gulong. Ang espesyal na tampok ay ang robot ay maaaring pagbabalanse ng sarili nito nang hindi gumagamit ng anumang panlabas na suporta. Kapag ang lakas ay nasa robot ay tatayo at pagkatapos ay patuloy itong balansehin sa pamamagitan ng paggamit ng mga paggalaw ng oscillation. Kaya ngayon lahat ng mayroon ka ng ilang magaspang na ideya tungkol sa sarili na robot sa pagbabalanse.

Hakbang 2: Teorya at Pamamaraan

Teorya at Pamamaraan
Teorya at Pamamaraan

Upang balansehin ang robot, kumuha muna kami ng data mula sa ilang sensor upang sukatin ang anggulo ng robot sa patayong eroplano. Para sa hangaring iyon ginamit namin ang MPU6050. Matapos makuha ang data mula sa sensor kinakalkula namin ang ikiling sa patayong eroplano. Kung ang robot sa tuwid at balanseng posisyon, pagkatapos ang anggulo ng ikiling ay zero. Kung hindi, kung gayon ang anggulo ng ikiling ay positibo o negatibong halaga. Kung ang robot ay ikiling sa harap na bahagi, kung gayon ang robot ay dapat lumipat sa direksyon sa harap. Gayundin kung ang robot ay ikiling upang baligtarin ang gilid pagkatapos ay dapat lumipat ang robot upang baligtarin ang direksyon. Kung ang anggulo ng ikiling na ito ay mataas kung gayon ang bilis ng pagtugon ay dapat na mataas. Sa kabaligtaran ang anggulo ng ikiling ay mababa pagkatapos ang bilis ng reaksyon ay dapat na mababa. Upang makontrol ang prosesong ito, gumamit kami ng tiyak na teorama na tinatawag na PID. Ang PID ay isang control system na ginagamit upang makontrol ang maraming proseso. Ang PID ay nangangahulugang 3 proseso.

  • P- proporsyonal
  • Ako- integral
  • D- nagmula

Ang bawat system ay may input at output. Sa parehong paraan ang control system na ito ay mayroon ding ilang input. Sa control system na ito ay ang paglihis mula sa matatag na estado. Tinawag namin iyon bilang isang error. Sa aming robot, ang error ay ang pagkiling ng anggulo mula sa patayong eroplano. Kung ang robot ay balansehin pagkatapos ang anggulo ng ikiling ay zero. Kaya't ang halaga ng error ay magiging zero. Dahil dito ang output ng PID system ay zero. Kasama sa sistemang ito ang tatlong magkakahiwalay na proseso ng matematika.

Una ay i-multiply ang error mula sa nakuha sa bilang. Ang pakinabang na ito ay karaniwang tinatawag bilang Kp

P = error * Kp

Pangalawa isa ay bumuo ng integral ng error sa domain ng oras at i-multiply ito mula sa ilang mga nakuha. Ang nakuha na ito ay tinawag bilang Ki

I = Integral (error) * Ki

Pangatlo isa ay nagmula sa error sa time domain at i-multiply ito sa pamamagitan ng ilang halaga ng kita. Ang pakinabang na ito ay tinawag bilang Kd

D = (d (error) / dt) * kd

Matapos idagdag ang mga pagpapatakbo sa itaas nakukuha namin ang aming huling output

OUTPUT = P + I + D

Dahil sa bahagi ng P robot ay maaaring makakuha ng matatag na posisyon na proporsyonal sa paglihis. Kinakalkula ko ang bahagi ng lugar ng error kumpara sa time graph. Kaya't sinusubukan nitong makuha ang robot sa matatag na posisyon na laging tumpak. Sinusukat ng bahagi ng D ang slope sa time vs error graph. Kung ang error ay tumataas ang halagang ito ay positibo. Kung ang error ay bumababa ang halagang ito ay negatibo. Dahil dito, kapag ang robot ay gumagalaw sa matatag na posisyon kung gayon ang bilis ng reaksyon ay mababawasan at makakatulong ito na alisin ang hindi kinakailangang mga overshoot. Maaari mong malaman ang tungkol sa higit pa tungkol sa teorya ng PID mula sa link na ito na ipinakita sa ibaba.

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

Ang output ng pagpapaandar ng PID ay limitado sa saklaw na 0-255 (8 bit na resolusyon ng PWM) at magpapakain ito sa mga motor bilang signal ng PWM.

Hakbang 3: Pag-setup ng Hardware

Pag-setup ng Hardware
Pag-setup ng Hardware

Ngayon ito ay bahagi ng pag-setup ng hardware. Ang disenyo ng robot ay nakasalalay sa iyo. Kapag dinisenyo mo ang katawan ng robot kailangan mong isaalang-alang ang simetriko tungkol sa patayong axis na nakasalalay sa axis ng motor. Ang baterya pack na matatagpuan sa ibaba. Kung gayon ang robot ay madaling balansehin. Sa aming disenyo inaayos namin ang Magicbit board nang patayo sa katawan. Gumamit kami ng dalawang 12V gear motor. Ngunit maaari kang gumamit ng anumang uri ng mga motor na pang-gear. nakasalalay iyon sa mga sukat ng iyong robot.

Kapag tinatalakay namin ang tungkol sa circuit ay pinalakas ito ng 7.4V Lipo na baterya. Gumamit ang Magicbit ng 5V para sa powering. Dahil doon ginamit namin ang 7805 regulator upang makontrol ang boltahe ng baterya sa 5V. Sa mga susunod na bersyon ng Magicbit na regulator ay hindi kailangan. Dahil ito ay nagpapatakbo ng hanggang sa 12V. Direkta kaming naghahatid ng 7.4V para sa driver ng motor.

Ikonekta ang lahat ng mga bahagi ayon sa diagram sa ibaba.

Hakbang 4: Pag-setup ng Software

Sa code ginamit namin ang PID library para makalkula ang output ng PID.

Pumunta sa sumusunod na link upang i-download ito.

www.arduinolibraries.info/libraries/pid

I-download ang pinakabagong bersyon nito.

Upang makakuha ng mas mahusay na mga pagbabasa ng sensor ginamit namin ang DMP library. Ang DMP ay nangangahulugang proseso ng digital na paggalaw. Ito ay built-in na tampok ng MPU6050. Ang chip na ito ay may pinagsamang yunit ng proseso ng paggalaw. Kaya't kinakailangan ng pagbabasa at pag-aralan. Matapos itong makabuo ng walang ingay na tumpak na output sa microcontroller (sa kasong ito Magicbit (ESP32)). Ngunit maraming mga gawa sa bahagi ng microcontroller upang gawin ang mga pagbabasa at kalkulahin ang anggulo. Kaya't sa simpleng paggamit ng MPU6050 DMP library. I-download ito sa pamamagitan ng goint sa sumusunod na link.

github.com/ElectronicCats/mpu6050

Upang mai-install ang mga aklatan, sa menu ng Arduino pumunta sa mga tool-> isama ang library-> add.zip library at piliin ang file ng library na iyong na-download.

Sa code kailangan mong baguhin nang tama ang anggulo ng setpoint. Ang pare-pareho na halaga ng PID ay magkakaiba mula sa robot hanggang sa robot. Kaya sa pag-tune nito, itakda muna ang Ki at Kd na halaga ng zero at pagkatapos ay taasan ang Kp hanggang sa makuha mo ang mas mahusay na bilis ng reaksyon. Mas maraming mga sanhi ng Kp para sa maraming mga overshoot. Pagkatapos taasan ang halaga ng Kd. Taasan ito ng palaging sa napakakaunting halaga. Ang halagang ito sa pangkalahatan ay mababa kaysa sa iba pang mga halaga. Ngayon dagdagan ang Ki hanggang sa magkaroon ka ng napakahusay na katatagan.

Piliin ang tamang COM port at i-type ang board ang. i-upload ang code Ngayon ay maaari mong i-play sa iyong DIY robot.

Hakbang 5: Mga Skema

Mga Skema
Mga Skema

Hakbang 6: Code

# isama

# isama ang "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #kung I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE # isama ang "Wire.h" #endif MPU6050 mpu; bool dmpReady = false; // set true kung matagumpay ang DMP init uint8_t mpuIntStatus; // humahawak ng aktwal na byte ng pagkaantala ng katayuan mula sa MPU uint8_t devStatus; // status ng pagbabalik pagkatapos ng bawat pagpapatakbo ng aparato (0 = tagumpay,! 0 = error) uint16_t packetSize; // inaasahang laki ng packet ng DMP (ang default ay 42 bytes) uint16_t fifoCount; // count ng lahat ng byte na kasalukuyang nasa FIFO uint8_t fifoBuffer [64]; // FIFO storage buffer Quaternion q; // [w, x, y, z] lalagyan ng quaternion na VectorFloat gravity; // [x, y, z] gravity vector float ypr [3]; // [yaw, pitch, roll] yaw / pitch / roll container at gravity vector na dobleng orihinalSetpoint = 172.5; dobleng setpoint = orihinalSetpoint; dobleng paglipatAngleOffset = 0.1; doble na input, output; int ilipatState = 0; doble Kp = 23; // itakda ang P unang dobleng Kd = 0.8; // ang halagang ito sa pangkalahatan maliit na dobleng Ki = 300; // ang halagang ito ay dapat na mataas para sa mas mahusay na katatagan PID pid (& input, & output, & setpoint, Kp, Ki, Kd, DIRECT); // pid initialize int motL1 = 26; // 4 pins for motor drive int motL2 = 2; int motR1 = 27; int motR2 = 4; pabagu-bago ng isip bool mpuInterrupt = false; // nagpapahiwatig kung MPU makagambala pin ay naging mataas na walang bisa 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); // pinmode ng mga motor ledcAttachPin (motL2, 1); ledcAttachPin (motR1, 2); ledcAttachPin (motR2, 3); // sumali sa I2C bus (hindi awtomatiko itong ginagawa ng I2Cdev library) #kung I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin (); Wire.setClock (400000); // 400kHz I2C na orasan. Komento sa linyang ito kung nagkakaroon ng mga paghihirap sa pagtitipon #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire:: setup (400, true); #endif Serial.println (F ("Inisyal ang mga aparato ng I2C …")); pinMode (14, INPUT); // ipasimuno ang serial komunikasyon // (115200 ang napili dahil kinakailangan ito para sa Teapot Demo output, ngunit ito ay // talagang nasa iyo depende sa iyong proyekto) Serial.begin (9600); habang (! Serial); // wait for Leonardo enumeration, ang iba ay nagpatuloy kaagad // pinasimulan ang aparato Serial.println (F ("Initializing I2C device …")); mpu.initialize (); // verify koneksyon Serial.println (F ("Mga koneksyon sa aparato sa pagsubok …")); Serial.println (mpu.testConnection ()? F ("Matagumpay ang koneksyon sa MPU6050"): F ("Nabigo ang koneksyon sa MPU6050")); // load and configure the DMP Serial.println (F ("Initializing DMP…")); devStatus = mpu.dmpInitialize (); // supply your own gyro offset here, scaled for min sensitivity mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1788); // 1688 factory default para sa aking test chip // tiyaking gumana ito (ibabalik ang 0 kung gayon) kung (devStatus == 0) {// i-on ang DMP, ngayong handa na itong Serial.println (F ("Enabling DMP… ")); mpu.setDMPEn pinagana (totoo); // paganahin ang Arduino makagambala ng pagtuklas Serial.println (F ("Pagpapagana ng pag-detect ng abala (Arduino panlabas na makagambala 0) …")); attachInterrupt (14, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus (); // itakda ang aming DMP Ready flag kaya alam ng pangunahing pag-andar ng loop na) okay na gamitin ito Serial.println (F ("Handa na ang DMP! Naghihintay para sa unang makagambala …")); dmpReady = totoo; // makakuha ng inaasahang laki ng packet ng DMP para sa paglaon sa paghahambing packetSize = mpu.dmpGetFIFOPacketSize (); // setup PID pid. SetMode (AUTOMATIC); pid. SetSampleTime (10); pid. SetOutputLimits (-255, 255); } iba pa {// ERROR! // 1 = Nabigo ang paunang pag-load ng memorya // 2 = Nabigo ang mga pag-update ng pagsasaayos ng DMP // (kung masisira ito, karaniwang ang code ay magiging 1) Serial.print (F ("Nabigo ang Initialization ng DMP (code")); Serial. i-print (devStatus); Serial.println (F (")")); }} void loop () {// kung nabigo ang programa, huwag subukang gumawa ng anumang bagay kung bumalik (! dmpReady); // maghintay para sa MPU makagambala o labis na (mga) packet na magagamit habang (! mpuInterrupt && fifoCount <packetSize) {pid. Compute (); // ang panahong ito ay ginagamit upang mai-load ang data, kaya maaari mo itong magamit para sa iba pang mga kalkulasyon motorSpeed (output); } // reset interrupt flag at makakuha ng INT_STATUS byte mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus (); // get current FIFO count fifoCount = mpu.getFIFOCount (); // check for overflow (hindi ito dapat mangyari maliban kung ang aming code ay masyadong episyente) kung ((mpuIntStatus & 0x10) || fifoCount == 1024) {// reset upang makapagpatuloy kaming malinis mpu.resetFIFO (); Serial.println (F ("FIFO overflow!")); // kung hindi man, suriin ang data ng DMP na handa nang magambala (dapat itong mangyari nang madalas)} kung iba pa (mpuIntStatus & 0x02) {// maghintay para sa tamang magagamit na haba ng data, dapat ay isang napaka-maikling paghihintay habang (magagamit ang fifoCount 1 packet // (ito hinahayaan kaagad kaming magbasa nang higit pa nang hindi naghihintay para sa isang makagambala) fifoCount - = packetSize; mpu.dmpGetQuaternion (& q, fifoBuffer); mpu.dmpGetGravity (& gravity, & q); mpu.dmpGetYawPitchRoll (ypr, & q, & gravity); #if LOG_INPUT i-print ("ypr / t"); Serial.print (ypr [0] * 180 / M_PI); // euler angles 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;}} walang bisa ang motorSpeed (int PWM) {float L1, L2, R1, R2; kung (PWM> = 0) {// forward direction L2 = 0; L1 = abs (PWM); R2 = 0; R1 = abs (PWM); if (L1> = 255) { L1 = R1 = 255;}} iba pa {// paatras na direksyon L1 = 0; L2 = abs (PWM); R1 = 0; R2 = abs (PWM); kung (L2> = 255) {L2 = R2 = 255; }} // motor drive ledcWrite (0, L1); ledcWrite (1, L2); ledcWrite (2, R1 * 0.97); // 0.97 ay bilis ng katotohanan o, dahil ang kanang motor ay may mataas na bilis kaysa sa kaliwang motor, kaya binawasan natin ito hanggang sa ang mga bilis ng motor ay pantay na ledcWrite (3, R2 * 0.97);

}

Inirerekumendang: