Mündəricat:

Neopixel Üzüklü Gyroscope Əyləncə: 4 Addım (Şəkillərlə)
Neopixel Üzüklü Gyroscope Əyləncə: 4 Addım (Şəkillərlə)

Video: Neopixel Üzüklü Gyroscope Əyləncə: 4 Addım (Şəkillərlə)

Video: Neopixel Üzüklü Gyroscope Əyləncə: 4 Addım (Şəkillərlə)
Video: Yüzük Kickstarter Projesi 2024, Noyabr
Anonim
Image
Image

Bu təlimatda, meyl açısına uyğun olan LEDləri işıqlandıran bir cihaz qurmaq üçün MPU6050 jiroskopu, bir neopiksel üzük və bir arduino istifadə edəcəyik.

Bu sadə və əyləncəli bir layihədir və çörək taxtasına yığılacaq. Adımlara əməl etsəniz, videoda gördüklərinizi quracaqsınız. Gyroscope və neopixel üzük haqqında öyrənmək üçün yaxşı bir dərslikdir.

Buradakı ilk təlimatımda gördüyüm maraq səbəbiylə bu dərsliyi qururam (Arduino ilə Gyroscope Led Control). Bu təlimatda sadə ledləri bir neopiksel üzüklə əvəz etdim. Adafruit kitabxanasından istifadə etmək daha asandır və daha möhtəşəmdir.

Beləliklə, bu komponentlər varsa, onlardan istifadə etmək üçün əla bir yoldur, cihazı qurmaqla addım -addım keçməyə çalışacağam və son addımda necə işlədiyini izah edəcəyəm.

Addım 1: Lazım olan şeylər

Məclis
Məclis

Hissələri

1. Arduino pro mini 328p (eBay) 2 $

2. Çörək lövhəsi

3. MPU6050 giroskopu (eBay) 1.2 $

4. 24 neopixel led üzük (Adafruit) 17 $

5. 4 ədəd 4 ədəd AA batareya paketi

6. U formalı tullanan kabellər (isteğe bağlı). Çörək taxtasında daha yaxşı göründükləri üçün bu keçid kabellərini istifadə etdim və ledlər bu şəkildə daha çox görünür. Təxminən 4 dollara ebayda 140 qutu tapa bilərsiniz. Bu kabellər yoxdursa, onları dupont telləri ilə əvəz edə bilərsiniz.

Alətlər:

1. Arduino pro mini proqramlaşdırmaq üçün FT232RL seriyalı FTDI adapterindən USB

2. Arduino IDE

Bacarıqlar: 1. Lehimləmə, bu təlimatı yoxlayın

3. Əsas arduino proqramlaşdırma, bu dərs faydalı ola bilər

Addım 2: Quraşdırma

Məclis
Məclis

Əlaqələri asan görmək üçün fzz formatında fritzing sxemini və şəklini əlavə etdim

1. Şəkildə göstərildiyi kimi neopixel halqanın arxasına 3 ədəd kişi sancağı lehimləməlisiniz

- pozitiv pimi lehimləyin

- torpağı lehimləyin

- məlumat giriş pinini lehimləyin

2. Sonra 4x batareya tutucusunun çörək taxtasına qoşulma yolu olmalıdır, asan bir həll iki kişi dupont telini öz terminallarına lehimləməkdir.

3. Çörək taxtasını hazırlayın.

- şəkildəki kimi çörək taxtasına neopixel üzük, mikrokontrolör və giroskop qoyun

- bütün mənfi telləri yerləşdirin: mikro nəzarətçiyə, neopiksel halqasına, girroya

- bütün müsbət telləri yerləşdirin: mikro nəzarətçiyə, neopiksel halqasına, girroya

- bütün məlumat tellərini yerləşdirin:

* SDA və SCL mikrokontrolördən girroya qədər

* D6 mikrokontrolördən neopixel halqasına qədər

- Güc verməzdən əvvəl bütün əlaqələri iki dəfə yoxlayın

- İsteğe bağlı olaraq yapışqan lentdən istifadə edərək batareya paketini bradboardun arxasına bərkidin və daha portativ hala gətirin.

Addım 3: Kod və Kalibrləmə

Əvvəlcə iki kitabxananı yükləməli və quraşdırmalısınız:

1. Neopikseli idarə edən Adafruit neopixel kitabxanası

2. Giroskop üçün MPU6050 kitabxanası

3. I2CDev kitabxana mənbəyi

Ağır yükü qaldıracaq iki böyük kitabxanadır!

Neopiksellər haqqında daha ətraflı məlumat burada

Sonra kitabxanamı buradan yükləyin və quraşdırın və ya aşağıdan kopyalayın:

#"I2Cdev.h" daxil edin

#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 şeridi = Adafruit_NeoPixel (NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG + NEO_KHZ800); imzasız uzun lastPrintTime = 0; bool başlatma = yanlış; // DMP init uğurlu uint8_t mpuIntStatus olsaydı doğru təyin edin; // MPU uint8_t devStatus -dan faktiki fasilə statusu baytını saxlayır; // hər cihaz əməliyyatından sonra vəziyyəti qaytarın (0 = uğur,! 0 = səhv) uint16_t packetSize; // gözlənilən DMP paket ölçüsü (standart 42 baytdır) uint16_t fifoCount; // hazırda FIFO -da olan bütün baytların sayı uint8_t fifoBuffer [64]; // FIFO saxlama buferi Quaternion q; // [w, x, y, z] quaternion konteyner VectorFloat çəkisi; // [x, y, z] cazibə vektoru float ypr [3]; // [yaw, pitch, roll] yaw/pitch/roll konteyner və cazibə vektoru uçucu bool mpuInterrupt = false; // MPU kəsmə pininin yüksək olub olmadığını göstərir

boş quraşdırma ()

{Serial.begin (9600); Serial.println ("Proqram başladı"); başlatma = başlatmaGiroskop (); strip.begin (); } void loop () {if (! initialization) {return; } mpuInterrupt = yanlış; mpuIntStatus = mpu.getIntStatus (); fifoCount = mpu.getFIFOCount (); if (hasFifoOverflown (mpuIntStatus, fifoCount)) {mpu.resetFIFO (); qayıtmaq; } if (mpuIntStatus & 0x02) {while (fifoCount <packetSize) {fifoCount = mpu.getFIFOCount (); } mpu.getFIFOBytes (fifoBuffer, packetSize); fifoCount -= paket ölçüsü; mpu.dmpGetQuaternion (& q, fifoBuffer); mpu.dmpGetGravity (& cazibə qüvvəsi, & q); mpu.dmpGetYawPitchRoll (ypr, & q, & cazibə qüvvəsi); redrawLeds (ypr [0] * 180/M_PI, ypr [1] * 180/M_PI, ypr [2] * 180/M_PI); }} boolean hasFifoOverflown (int mpuIntStatus, int fifoCount) {return mpuIntStatus & 0x10 || fifoCount == 1024; } void redrawLeds (int x, int y, int z) {x = constrain (x, -1 * MAX_ANGLE, MAX_ANGLE); y = məhdudlaşdır (y, -1 * MAX_ANGLE, MAX_ANGLE); if (y 0) {lightLeds (y, z, 0, 5, 0, 89); } başqa if (y <0 və z 0 və z 0 və z> 0) {lightLeds (y, z, 20, 24, 89, 0); }} void lightLeds (int x, int y, int fromLedPosition, int toLedPosition, int fromAngle, int toAngle) {cüt açı = (atan ((ikiqat) abs (x) / (ikiqat) abs (y)) * 4068) / 71; int ledNr = xəritə (bucaq, FromAngle, toAngle, fromLedPosition, toLedPosition); printDebug (x, y, ledNr, bucaq); uint32_t rəng; for (int i = 0; i mövqe + LED_OFFSET) {qaytarma mövqeyi + LED_OFFSET; } dönüş mövqeyi + LED_OFFSET - NUM_LEDS; } void printDebug (int y, int z, int lightLed, int bucağı) {if (millis () - lastPrintTime <500) {return; } Serial.print ("a ="); Serial.print (bucaq); 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 ("MPU6050 bağlantısı uğurlu"): F ("MPU6050 bağlantısı uğursuz oldu")); Serial.println (F ("DMP başlatılır …")); devStatus = mpu.dmpInitialize (); mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1788); if (devStatus! = 0) {Serial.print (F ("DMP Başlanğıcı başarısız oldu (kod")); Serial.println (devStatus); yanlış qaytar;} mpu.setDMPEnabled (doğru); Serial.println (F ("Aktivləşdirmə) kəsilmə aşkarlanması (Arduino xarici müdaxilə 0)… ")); attachInterrupt (0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus (); Serial.println (F (" DMP hazırdır! İlk kəsilmə gözləyir … ")); packetSize = mpu.dmpGetFIFOPacketSize (); doğruya qayıt;} void dmpDataReady () {mpuInterrupt = true;}

Kodu yükləyin:

FTDI adapterindən istifadə edərək kodu arduinoya yükləyin.

Güc mənbəyini bağlayın (batareyalar)

Kalibrləmə:

Burada kalibrləmə üçün ən vacib şey "LED_OFFSET" sabitidir. Mənim nümunəmdə 12 -dir. Bunu 0 -dan 23 -ə düzəltməlisiniz ki, lövhəyə elektrik verildikdən sonra lövhəni əydiyiniz istiqamətə doğru yanacaq.

Necə işlədiyini daha ətraflı öyrənmək istəyirsinizsə, son addımı yoxlayın

Addım 4: Necə Çalışır (isteğe bağlı)

Necə işləyir (isteğe bağlı)
Necə işləyir (isteğe bağlı)

Əvvəlcə MPU6050 jiroskopu haqqında bir az məlumat. Bu MEMS giroskopudur (MEMS Mikroelektromekanik sistemləri ifadə edir).

Hər bir MEM giroskopu, bir növ salınma komponentinə malikdir və buradan tələffüz və buna görə də istiqamət dəyişikliyi aşkar edilə bilər. Bunun səbəbi, hərəkət qanununun qorunmasına görə, titrəyən bir cisim eyni müstəvidə titrəməyə davam etməyi sevir və istiqamətdə bir dəyişiklik əldə etmək üçün hər hansı bir vibrasiya sapması istifadə edilə bilər.

Gyro, bəzi fantastik riyazi hesablamaları, meydançaları və yawları hesablamaq üçün özünə məxsus bir mikro nəzarətçini də ehtiva edir.

Ancaq gyro xam məlumatları səs -küydən və sürüşmədən əziyyət çəkir, buna görə hər şeyi düzəltmək və bizə təmiz istifadə edilə bilən məlumatlar vermək üçün xarici bir kitabxanadan istifadə etdik.

Neopixel, ayrı -ayrılıqda ünvanlı və bantlara və üzüklərə zəncirlənmiş RGB LED -lərdir. 5V -də işləyirlər və öz sxemlərinə malikdirlər, buna görə yalnız neopikselləri gücləndirmək və məlumat xəttini istifadə edərək onlarla ünsiyyət qurmaq lazımdır. Əlaqə saatı və məlumatları ehtiva edən tək bir məlumat xətti ilə aparılır (daha ətraflı burada). Adafruit, neopiksel üzüklərlə qarşılıqlı əlaqə qurmaq üçün təmiz bir kitabxana təmin edir.

Kod

L oop () funksiyasının içərisində MPU6050_6Axis_MotionApps20 kitabxanası adlanır. Kitabxanada gyroscpe -dən yeni məlumatlar olduqda, yaw, pitch və roll -u təmsil edən 3 arqumentlə redrawLeds (x, y, z) adlandırır.

İçəridə redrawLeds ():

- iki oxa diqqət yetiririk: y, z

- hər iki oxu -MAX_ANGLE -dən +MAX_ANGLE -ə məhdudlaşdırırıq, maksimum bucağı 45 -ə təyin etdik və dəyişdirilə bilər

- 360 dərəcə 4 kadrana bölürük və hər biri üçün lightLeds () funksiyalarını aşağıdakı kimi çağırırıq:

* y mənfi, z pozitiv birinci kvadrant ledləri 0 -dan 5 -ə qədər idarə edəcək, bucaq 0 -dan 89 -a qədər olacaq

* y mənfi, z mənfi ikinci kvadrant nəzarət ledləri 6 -dan 12 -yə, açı 89 -dan 0 -a qədər olacaq

*… Və s

- LightLeds funksiyasının içərisində

* Arktangensdən istifadə edərək iki oxa əsaslanan bir açı hesablayıram (əlavə olunan şəkli yoxlayın)

* Arduino xəritəsi funksiyasından istifadə edərək nəyə səbəb olduğunu hesablayıram

* Led şeridini iki LEDdən başqa hamısını sıfırlayıram, əvvəllər hesabladığım led mövqeyinə və daha əvvəl bir led mövqeyinə uyğun gəlir (solma effekti göstərmək üçün)

* Neopixel kalibrini nəzərə almaq üçün normalizeLedPosition () adlı bir funksiyadan istifadə edirəm. Kalibrləmə faydalıdır, çünki neopixel halqası istədiyi kimi dönə bilər və giroskopla hizalanmalıdır.

* Mən də çəkmə oxunu çap edirəm, ledin işığı və bucağı var

Riyaziyyat

Led üzük və bucağı təyin etmək üçün istifadə olunan trigonometrik funksiyası olan bir şəkil əlavə etdim.

Tövsiyə: