Tentang proyek ini
Dalam tutorial ini, kita akan menggunakan MPU6050 giroskop, sebuah NeoPixel Cincin dan Arduino untuk membuat perangkat yang menyalakan LED sesuai dengan sudut kemiringan.
Ini adalah proyek yang sederhana dan menyenangkan dan akan dirakit di papan tempat memotong roti. Jika Anda mengikuti langkah-langkahnya, Anda akan membuat apa yang Anda lihat di video. Ini adalah tutorial yang bagus untuk mempelajari tentang giroskop dan Cincin NeoPixel.
Saya membangun tutorial ini karena minat yang saya lihat pada beberapa tutorial min. Dalam tutorial ini saya telah mengganti led sederhana dengan Cincin NeoPixel. Cincin itu lebih mudah digunakan melalui perpustakaan Adafruit dan itu pasti lebih spektakuler.
Jadi, jika Anda memiliki komponen-komponen ini, ini adalah cara yang bagus untuk memanfaatkannya, saya akan mencoba membawa Anda langkah demi langkah melalui pembuatan perangkat dan juga menjelaskan cara kerjanya di langkah terakhir.
Langkah 1:Hal yang Diperlukan
Suku cadang
1. Arduino Pro Mini 328P
2. Papan tempat memotong roti
3. Giroskop MPU6050
4. 24 Cincin LED NeoPixel
5. Paket baterai 4 x AA dengan 4 baterai
6. Kabel jumper berbentuk U (opsional). Saya telah menggunakan kabel jumper ini karena terlihat lebih baik di papan tempat memotong roti, dan led lebih terlihat dengan cara ini. Anda dapat menemukan sekotak 140 di ebay dengan harga sekitar $4. Jika Anda tidak memiliki kabel ini, Anda dapat menggantinya dengan kabel dupont.
Alat:
1. USB to serial FTDI adapter FT232RL untuk memprogram arduino pro mini
2. Arduino IDE
Keterampilan:
1. Menyolder
3. Pemrograman arduino dasar
Langkah 2:Perakitan
Saya telah melampirkan skema fritzing dalam format fzz dan gambarnya untuk visualisasi koneksi yang mudah.
1. Anda perlu menyolder 3 pin pria di bagian belakang cincin neopiksel seperti yang ditunjukkan pada gambar
- solder pin positif
- solder tanah
- solder pin input data
2. Kemudian dudukan baterai 4x harus memiliki cara menyambung ke breadboard, solusi mudahnya adalah dengan menyolder dua kabel male dupont ke terminalnya.
3. Siapkan papan tempat memotong roti.
- letakkan cincin neopiksel, mikrokontroler, dan giroskop di papan tempat memotong roti seperti pada gambar
- tempatkan semua kabel negatif:ke mikrokontroler, cincin neopiksel, gyro
- tempatkan semua kabel positif:ke mikrokontroler, cincin neopiksel, gyro
- tempatkan semua kabel data:
* SDA dan SCL dari ke mikrokontroler ke gyro
* pin D6 dari mikrokontroler ke cincin neopiksel
- periksa kembali semua koneksi sebelum menyalakan
- secara opsional menggunakan lakban, rekatkan unit baterai di bagian belakang bradboard untuk menahannya dan membuatnya lebih portabel
Langkah 3:Kode dan Kalibrasi
Pertama Anda perlu mengunduh dan menginstal dua pustaka:
1. Adafruit neopixel library yang mengontrol neopixel
2. Pustaka MPU6050 untuk giroskop
Mereka adalah dua perpustakaan hebat yang akan melakukan pekerjaan berat!
Detail lebih lanjut tentang neopiksel di sini
Lalu unduh dan instal perpustakaan saya dari sini atau salin dari bawah:
#include "I2Cdev.h" #include #include "MPU6050_6Axis_MotionApps20.h" #include "Wire.h" #define NEOPIXED_CONTROL_PIN 6 #define NUM_LEDS 24 const int MAX_ANGLE =45; const int LED_OFFSET =12; MPU6050 mpu; Adafruit_NeoPixel strip =Adafruit_NeoPixel(NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG + NEO_KHZ800); unsigned long lastPrintTime =0; inisialisasi bool =false; // 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 volatil bool mpuInterrupt =false; // menunjukkan apakah pin interupsi MPU menjadi tinggi
void setup() { Serial.begin(9600); Serial.println("Program dimulai"); inisialisasi =initializeGiroskop(); strip.mulai(); } void loop() { if (!inisialisasi) { kembali; } mpuInterrupt =salah; mpuIntStatus =mpu.getIntStatus(); fifoCount =mpu.getFIFOCount(); if (hasFifoOverflown(mpuIntStatus, fifoCount)) { mpu.resetFIFO(); kembali; } if (mpuIntStatus &0x02) { while (fifoCount 0) { lightLeds(y, z, 0, 5, 0, 89); } else if (y <0 dan z <0) { lightLeds(y, z, 6, 12, 89, 0); } else if (y> 0 dan z <0) { lightLeds(y, z, 13, 19, 0, 89); } else if (y> 0 dan z> 0) { lightLeds(y, z, 20, 24, 89, 0); } } void lightLeds(int x, int y, int fromLedPosition, int toLedPosition, int fromAngle, int toAngle) { sudut ganda =(atan((ganda) abs(x) / (ganda) abs (y)) * 4068) / 71; int ledNr =peta(sudut, dariSudut, keSudut, dariLedPosition, keLedPosition); printDebug(x, y, ledNr, sudut); warna uint32_t; for (int i=0; i position + LED_OFFSET) { mengembalikan posisi + LED_OFFSET; } kembali posisi + LED_OFFSET - NUM_LEDS; } void printDebug(int y, int z, int lightLed, int angle) { if (millis() - lastPrintTime <500) { kembali; } Serial.print("a=");Serial.print(angle);Serial.print("; "); Serial.print("ll=");Serial.print(lightLed);Serial.print("; "); Serial.print("y=");Serial.print(y);Serial.print("; "); Serial.print("z=");Serial.print(z);Serial.println("; "); lastPrintTime =milis(); } bool initializeGyroscope() { Wire.begin(); TWBR =24; mpu.initialize(); Serial.println(mpu.testConnection() ? F("Koneksi MPU6050 berhasil") :F("Koneksi MPU6050 gagal")); Serial.println(F("Inisialisasi DMP...")); devStatus =mpu.dmpInitialize(); mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); if (devStatus !=0) { Serial.print(F("Inisialisasi DMP gagal (kode "));Serial.println(devStatus); return false; } mpu.setDMPEnabled(true); Serial.println(F("Mengaktifkan deteksi interupsi (Arduino external interrupt 0)...")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus =mpu.getIntStatus(); Serial.println(F("DMP siap! Menunggu interupsi pertama..." )); packetSize =mpu.dmpGetFIFOPacketSize(); return true; } void dmpDataReady() { mpuInterrupt =true; }
Unggah kode:
Menggunakan adaptor FTDI, unggah kode ke arduino.
Hubungkan catu daya (baterai)
Kalibrasi:
Yang paling penting untuk dikalibrasi di sini adalah konstanta "LED_OFFSET". Dalam contoh saya adalah 12. Anda perlu menyesuaikan ini dari 0 hingga 23 sehingga setelah menyalakan papan, led akan menyala ke arah Anda memiringkan papan.
Jika Anda ingin mengetahui detail selengkapnya tentang cara kerjanya, lihat langkah selanjutnya
Langkah 4:Cara Kerjanya (opsional)
Pertama sedikit informasi tentang giroskop MPU6050. Ini adalah giroskop MEMS (MEMS singkatan dari Microelectromechanical systems).
Setiap jenis giroskop MEMs memiliki beberapa bentuk komponen berosilasi dari mana akselerasi, dan karenanya perubahan arah, dapat dideteksi. Ini karena, sesuai dengan hukum kekekalan gerak, benda yang bergetar suka terus bergetar pada bidang yang sama, dan setiap penyimpangan getaran dapat digunakan untuk mendapatkan perubahan arah.
Gyro juga berisi mikrokontroler sendiri untuk menghitung roll, pitch, dan yaw melalui beberapa matematika mewah.
Namun data mentah gyro mengalami gangguan dan penyimpangan, jadi kami menggunakan perpustakaan eksternal untuk memperlancar dan memberi kami data bersih yang dapat digunakan.
Neopiksel adalah LED RGB yang dapat dialamatkan secara individual dan dirantai menjadi pita dan cincin. Mereka bekerja pada 5V dan mengandung sirkuit mereka sendiri sehingga Anda hanya perlu memberi daya pada neopiksel dan berkomunikasi dengan mereka menggunakan jalur data. Komunikasi dilakukan dengan satu jalur data yang berisi jam dan data (lebih detail di sini). Adafruit menyediakan perpustakaan yang bersih untuk berinteraksi dengan cincin neopiksel.
Kode
Di dalam loop() fungsi perpustakaan MPU6050_6Axis_MotionApps20 dipanggil. Ketika perpustakaan memiliki data baru dari gyroscpe, ia memanggil redrawLeds(x, y, z) dengan 3 argumen yang mewakili yaw, pitch and roll
Di dalam redrawLeds ():
- kita fokus pada dua sumbu :y, z
- kami membatasi kedua sumbu dari -MAX_ANGLE ke +MAX_ANGLE, kami mendefinisikan sudut maksimum hingga 45 dan dapat diubah
- kita membagi 360 derajat menjadi 4 kuadran dan memanggil fungsi lightLeds() untuk masing-masing kuadran sebagai berikut:
* y negatif, z positif kuadran pertama akan mengontrol led dari 0 hingga 5, sudutnya akan dari 0 hingga 89
* y negatif, z negatif kuadran kedua mengontrol led dari 6 hingga 12, sudutnya akan dari 89 hingga 0
* ...dst
- di dalam lightLeds fungsi
* saya menghitung sudut berdasarkan dua sumbu menggunakan arctangent (cek gambar terlampir)
* saya menghitung apa yang ditampilkan menggunakan fungsi peta arduino
* saya mengatur ulang semua strip led kecuali dua led, yang sesuai dengan posisi led yang telah saya hitung sebelumnya dan posisi led sebelumnya (untuk menunjukkan efek fade)
* saya menggunakan fungsi yang disebut normalizeLedPosition() untuk memperhitungkan kalibrasi neopixel. Kalibrasi berguna karena cincin neopiksel dapat diputar sesuka hati, dan harus sejajar dengan giroskop
*saya juga sedang print tow axis, led apa ada cahaya dan sudutnya
Matematika
Saya telah melampirkan gambar dengan cincin led dan fungsi trigonometri yang digunakan untuk menentukan sudut.
Kode
Kode arduino
https://github.com/danionescu0/arduino/tree/master/projects/neopixel_ring_gyroscope Skema
sketch_gMlSrk3rCX.fzz