Daftar Isi:

Robot Penyeimbang Diri Dari Magicbit: 6 Langkah
Robot Penyeimbang Diri Dari Magicbit: 6 Langkah

Video: Robot Penyeimbang Diri Dari Magicbit: 6 Langkah

Video: Robot Penyeimbang Diri Dari Magicbit: 6 Langkah
Video: Осьминог Vs Подводный Лабиринт 2024, Juli
Anonim

Tutorial ini menunjukkan cara membuat robot self balancing menggunakan papan dev Magicbit. Kami menggunakan magicbit sebagai papan pengembangan dalam proyek ini yang didasarkan pada ESP32. Oleh karena itu, papan pengembangan ESP32 apa pun dapat digunakan dalam proyek ini.

Perlengkapan:

  • magicbit
  • Driver motor H-jembatan L298 ganda
  • Pengatur Linier (7805)
  • Baterai Lipo 7.4V 700mah
  • Unit Pengukuran Inersia (IMU) (6 derajat kebebasan)
  • motor roda gigi 3V-6V DC

Langkah 1: Cerita

Cerita
Cerita
Cerita
Cerita

Hai teman-teman, hari ini dalam tutorial ini kita akan belajar tentang hal-hal yang sedikit rumit. Itulah tentang robot self balancing menggunakan Magicbit dengan Arduino IDE. Jadi mari kita mulai.

Pertama-tama, mari kita lihat apa itu robot penyeimbang diri. Robot penyeimbang diri adalah robot beroda dua. Keistimewaannya adalah robot dapat menyeimbangkan dirinya sendiri tanpa menggunakan dukungan eksternal. Pada saat power menyala robot akan berdiri kemudian diseimbangkan secara terus menerus dengan menggunakan gerakan osilasi. Jadi sekarang Anda memiliki beberapa gambaran kasar tentang robot penyeimbang diri.

Langkah 2: Teori dan Metodologi

Teori dan Metodologi
Teori dan Metodologi

Untuk menyeimbangkan robot, pertama-tama kita mendapatkan data dari beberapa sensor untuk mengukur sudut robot terhadap bidang vertikal. Untuk itu kami menggunakan MPU6050. Setelah mendapatkan data dari sensor kami menghitung kemiringan ke bidang vertikal. Jika robot pada posisi lurus dan seimbang, maka sudut kemiringannya adalah nol. Jika tidak, maka sudut kemiringan bernilai positif atau negatif. Jika robot dimiringkan ke sisi depan, maka robot harus bergerak ke arah depan. Juga jika robot dimiringkan ke sisi sebaliknya maka robot harus bergerak ke arah sebaliknya. Jika sudut kemiringan ini tinggi maka kecepatan respons harus tinggi. Begitu pula sebaliknya sudut kemiringan rendah maka kecepatan reaksi harus rendah. Untuk mengontrol proses ini kami menggunakan teorema khusus yang disebut PID. PID adalah sistem kontrol yang digunakan untuk mengontrol banyak proses. PID adalah singkatan dari 3 proses.

  • P- proporsional
  • I- integral
  • D-turunan

Setiap sistem memiliki input dan output. Dengan cara yang sama sistem kontrol ini juga memiliki beberapa masukan. Pada sistem kendali inilah penyimpangan dari keadaan stabil. Kami menyebutnya sebagai kesalahan. Dalam robot kami, kesalahan adalah sudut kemiringan dari bidang vertikal. Jika robot seimbang maka sudut kemiringan adalah nol. Jadi nilai kesalahan akan menjadi nol. Oleh karena itu output dari sistem PID adalah nol. Sistem ini mencakup tiga proses matematika yang terpisah.

Yang pertama adalah kesalahan perkalian dari perolehan numerik. Gain ini biasa disebut Kp

P=kesalahan*Kp

Yang kedua adalah membangkitkan integral dari kesalahan dalam domain waktu dan mengalikannya dari beberapa keuntungan. Keuntungan ini disebut sebagai Ki

I= Integral(kesalahan)*Ki

Yang ketiga adalah turunan dari kesalahan dalam domain waktu dan mengalikannya dengan sejumlah keuntungan. Keuntungan ini disebut sebagai Kd

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

Setelah menambahkan operasi di atas, kami mendapatkan hasil akhir kami

KELUARAN=P+I+D

Karena robot bagian P bisa mendapatkan posisi stabil yang sebanding dengan deviasi. Bagian I menghitung area kesalahan vs grafik waktu. Jadi ia mencoba membuat robot ke posisi stabil selalu akurat. Bagian D mengukur kemiringan waktu vs grafik kesalahan. Jika kesalahan meningkat, nilai ini positif. Jika kesalahan berkurang, nilai ini negatif. Oleh karena itu, ketika robot bergerak ke posisi stabil maka kecepatan reaksi akan berkurang dan ini akan membantu untuk menghilangkan overshoot yang tidak perlu. Anda dapat mempelajari lebih lanjut tentang teori PID dari tautan yang ditunjukkan di bawah ini.

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

Output dari fungsi PID dibatasi hingga rentang 0-255 (resolusi 8 bit PWM) dan yang akan diumpankan ke motor sebagai sinyal PWM.

Langkah 3: Pengaturan Perangkat Keras

Pengaturan Perangkat Keras
Pengaturan Perangkat Keras

Sekarang ini adalah bagian pengaturan perangkat keras. Desain robot tergantung pada Anda. Saat merancang tubuh robot, Anda harus mempertimbangkan simetrisnya terhadap sumbu vertikal yang terletak pada sumbu motor. Paket baterai terletak di bawah. Oleh karena itu robot mudah untuk diseimbangkan. Dalam desain kami, kami memperbaiki papan Magicbit secara vertikal ke bodi. Kami menggunakan dua motor roda gigi 12V. Tetapi Anda dapat menggunakan semua jenis motor roda gigi. itu tergantung pada dimensi robot Anda.

Ketika kita membahas tentang rangkaian ini ditenagai oleh baterai Lipo 7.4V. Magicbit menggunakan 5V untuk menyalakan. Oleh karena itu kami menggunakan regulator 7805 untuk mengatur tegangan baterai menjadi 5V. Dalam versi Magicbit yang lebih baru, regulator itu tidak diperlukan. Karena itu memberi daya hingga 12V. Kami langsung menyediakan 7.4V untuk driver motor.

Hubungkan semua komponen sesuai dengan diagram di bawah ini.

Langkah 4: Pengaturan Perangkat Lunak

Dalam kode kami menggunakan pustaka PID untuk menghitung keluaran PID.

Buka tautan berikut untuk mengunduhnya.

www.arduinolibraries.info/libraries/pid

Unduh versi terbarunya.

Untuk mendapatkan pembacaan sensor yang lebih baik, kami menggunakan pustaka DMP. DMP adalah singkatan dari proses gerak digital. Ini adalah fitur bawaan MPU6050. Chip ini memiliki unit proses gerak yang terintegrasi. Jadi butuh membaca dan menganalisa. Setelah itu menghasilkan output akurat tanpa suara ke mikrokontroler (dalam hal ini Magicbit (ESP32)). Tetapi ada banyak pekerjaan di sisi mikrokontroler untuk mengambil bacaan itu dan menghitung sudut. Jadi secara sederhana kita menggunakan library MPU6050 DMP. Download dengan pergi ke link berikut.

github.com/ElectronicCats/mpu6050

Untuk menginstal perpustakaan, di menu Arduino pergi ke alat-> termasuk perpustakaan-> perpustakaan add.zip dan pilih file perpustakaan yang Anda unduh.

Dalam kode Anda harus mengubah sudut setpoint dengan benar. Nilai konstanta PID berbeda dari robot ke robot. Jadi dalam menyetel itu, pertama-tama atur nilai Ki dan Kd ke nol dan kemudian naikkan Kp sampai Anda mendapatkan kecepatan reaksi yang lebih baik. Lebih banyak Kp menyebabkan lebih banyak overshoot. Kemudian naikkan nilai Kd. Tingkatkan dengan selalu dalam jumlah yang sangat sedikit. Nilai ini umumnya lebih rendah dari nilai lainnya. Sekarang tingkatkan Ki sampai Anda memiliki stabilitas yang sangat baik.

Pilih port COM yang benar dan ketik papan. mengunggah kode. Sekarang Anda dapat bermain dengan robot DIY Anda.

Langkah 5: Skema

skema
skema

Langkah 6: Kode

#termasuk

#include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif MPU6050 mpu; bool dmpReady = salah; // set true jika DMP init berhasil uint8_t mpuIntStatus; // menyimpan byte status interupsi aktual dari MPU uint8_t devStatus; // mengembalikan status setelah setiap operasi perangkat (0 = sukses, !0 = error) uint16_t packetSize; // ukuran paket DMP yang diharapkan (default adalah 42 byte) uint16_t fifoCount; // jumlah semua byte saat ini di FIFO uint8_t fifoBuffer[64]; // buffer penyimpanan FIFO Quaternion q; // [w, x, y, z] quaternion container VectorFloat gravity; // [x, y, z] vektor gravitasi float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container dan vektor gravitasi double originalSetpoint = 172.5; setpoint ganda = setpoint asli; ganda movingAngleOffset = 0,1; masukan ganda, keluaran; int keadaan bergerak=0; double Kp = 23;//set P double pertama Kd = 0.8;//nilai ini umumnya kecil double Ki = 300;//nilai ini harus tinggi untuk stabilitas yang lebih baik PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);//pid menginisialisasi int motL1=26;//4 pin untuk penggerak motor int motL2=2; int motR1=27; int motR2=4; volatil bool mpuInterrupt = false; // menunjukkan apakah pin interupsi MPU telah menjadi tinggi 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);//pinmode motor ledcAttachPin(motL2, 1); ledcAttachPin(motR1, 2); ledcAttachPin(motR2, 3); // bergabung dengan bus I2C (library I2Cdev tidak melakukan ini secara otomatis) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); Kawat.setJam(400000); // 400kHz I2C jam. Beri komentar pada baris ini jika mengalami kesulitan kompilasi #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif Serial.println(F("Menginisialisasi perangkat I2C…")); pinMode (14, INPUT); // menginisialisasi komunikasi serial // (115200 dipilih karena diperlukan untuk keluaran Teapot Demo, tapi itu // terserah Anda tergantung pada proyek Anda) Serial.begin(9600); while (!Serial); // tunggu penghitungan Leonardo, yang lain segera melanjutkan // menginisialisasi perangkat Serial.println(F("Menginisialisasi perangkat I2C…")); mpu.initialize(); // verifikasi koneksi Serial.println(F("Menguji koneksi perangkat…")); Serial.println(mpu.testConnection() ? F("Koneksi MPU6050 berhasil"): F("Koneksi MPU6050 gagal")); // memuat dan mengkonfigurasi DMP Serial.println(F("Inisialisasi DMP…")); devStatus = mpu.dmpInitialize(); // berikan offset gyro Anda sendiri di sini, diskalakan untuk sensitivitas min mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); // 1688 default pabrik untuk chip pengujian saya // pastikan itu berfungsi (mengembalikan 0 jika demikian) if (devStatus == 0) { // nyalakan DMP, sekarang sudah siap Serial.println(F("Mengaktifkan DMP… ")); mpu.setDMPEnabled(benar); // aktifkan deteksi interupsi Arduino Serial.println(F("Mengaktifkan deteksi interupsi (interupsi eksternal Arduino 0)…")); attachInterrupt(14, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); // setel flag DMP Ready kita sehingga fungsi loop() utama tahu bahwa tidak apa-apa untuk menggunakannya Serial.println(F("DMP ready! Waiting for first interrupt…")); dmpSiap = benar; // dapatkan ukuran paket DMP yang diharapkan untuk perbandingan nanti packetSize = mpu.dmpGetFIFOPacketSize(); //setup PID pid. SetMode(OTOMATIS); pid. SetSampleTime(10); pid. SetOutputLimits(-255, 255); } lain { // GALAT! // 1 = gagal memuat memori awal // 2 = Pembaruan konfigurasi DMP gagal // (jika akan rusak, biasanya kodenya adalah 1) Serial.print(F("Inisialisasi DMP gagal (kode ")); Serial. print(devStatus); Serial.println(F(")")); } } void loop() { // jika pemrograman gagal, jangan mencoba melakukan apapun jika (!dmpReady) kembali; // tunggu interupsi MPU atau paket tambahan tersedia while (!mpuInterrupt && fifoCount < packetSize) { pid. Compute();//periode waktu ini digunakan untuk memuat data, jadi Anda dapat menggunakannya untuk perhitungan lain motorSpeed(keluaran); } // reset flag interupsi dan dapatkan INT_STATUS byte mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus(); // dapatkan jumlah FIFO saat ini fifoCount = mpu.getFIFOCount(); // periksa overflow (ini tidak boleh terjadi kecuali kode kita terlalu tidak efisien) if ((mpuIntStatus & 0x10) || fifoCount == 1024) { // reset sehingga kita dapat melanjutkan dengan bersih mpu.resetFIFO(); Serial.println(F("FIFO melimpah!")); // jika tidak, periksa interupsi siap data DMP (ini harus sering terjadi) } else if (mpuIntStatus & 0x02) { // menunggu panjang data yang tersedia benar, harus SANGAT menunggu sebentar (fifoCount 1 paket tersedia // (ini mari kita langsung membaca lebih lanjut tanpa menunggu interupsi) fifoCount -= packetSize; mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); #if LOG_INPUT Serial. print("ypr\t"); Serial.print(ypr[0] * 180/M_PI);//euler sudut 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; if(PWM>=0){//arah maju L2=0; L1=abs(PWM); R2=0; R1=abs(PWM); if(L1>=255){ L1=R1=255; } } else {//arah mundur L1=0; L2=abs(PWM); R1=0; R2=abs(PWM); if(L2>=255){ L2=R2=255; } } //penggerak motor ledcWrite(0, L1); ledcWrite(1, L2); ledcWrite(2, R1*0.97);//0.97 adalah fakta kecepatan atau, karena motor kanan memiliki kecepatan lebih tinggi daripada motor kiri, maka kita kurangi sampai kecepatan motor sama ledcWrite(3, R2*0.97);

}

Direkomendasikan: