İçindekiler:

Neopiksel Halkalı Jiroskop Eğlencesi: 4 Adım (Resimlerle)
Neopiksel Halkalı Jiroskop Eğlencesi: 4 Adım (Resimlerle)

Video: Neopiksel Halkalı Jiroskop Eğlencesi: 4 Adım (Resimlerle)

Video: Neopiksel Halkalı Jiroskop Eğlencesi: 4 Adım (Resimlerle)
Video: EP20 HW Build - Измерение ВЧ-мощности своими руками 2024, Kasım
Anonim
Image
Image

Bu derste, eğim açısına karşılık gelen ledleri aydınlatan bir cihaz oluşturmak için MPU6050 jiroskop, bir neopiksel halka ve bir arduino kullanacağız.

Bu basit ve eğlenceli bir proje ve bir breadboard üzerinde toplanacak. Adımları takip ederseniz, videoda gördüğünüzü oluşturacaksınız. Jiroskop ve neopiksel halkası hakkında bilgi edinmek için iyi bir öğretici.

Bu öğreticiyi, buradaki ilk talimatımda gördüğüm ilgiden dolayı yapıyorum (Arduino ile Jiroskop Led Kontrolü). Bu talimatta, basit led'leri bir neopiksel halka ile değiştirdim. Bir Adafruit kütüphanesi aracılığıyla kullanımı daha kolay olan yüzük, kesinlikle daha muhteşem.

Bu nedenle, bu bileşenlere sahipseniz, bunlardan yararlanmanın harika bir yolu varsa, sizi adım adım cihazı oluşturmaya ve ayrıca son adımda nasıl çalıştığını açıklamaya çalışacağım.

Adım 1: Gerekli Şeyler

toplantı
toplantı

Parçalar

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

2. Ekmek tahtası

3. MPU6050 jiroskop (eBay) 1.2$

4. 24 neopiksel led halka (Adafruit) 17 $

5. 4 pil ile 4 x AA pil paketi

6. U-şekilli atlama kabloları (isteğe bağlı). Bu jumper kabloları devre tahtasında daha iyi göründüğü ve ledler bu şekilde daha görünür olduğu için kullandım. 140'lık bir kutuyu ebay'de 4$ civarında bulabilirsiniz. Bu kablolara sahip değilseniz, bunları dupont kablolarla değiştirebilirsiniz.

Aletler:

1. arduino pro mini'yi programlamak için USB'den seri FTDI adaptörü FT232RL'ye

2. Arduino IDE'si

Beceriler:1. Lehimleme, bu öğreticiyi kontrol edin

3. Temel arduino programlama, bu eğitim faydalı olabilir

2. Adım: Montaj

toplantı
toplantı

Bağlantıların kolay görselleştirilmesi için fritzing şemasını fzz formatında ve bir resmini ekledim

1. Resimde gösterildiği gibi neopiksel halkasının arkasındaki 3 erkek pimi lehimlemeniz gerekir.

- pozitif pimi lehimleyin

- zemini lehimlemek

- veri giriş pinini lehimleyin

2. O zaman 4x pil tutucunun breadboard'a bir bağlantı yolu olmalıdır, kolay bir çözüm iki erkek dupont kabloyu terminallerine lehimlemektir.

3. Breadboard'u hazırlayın.

- neopiksel halkasını, mikrodenetleyiciyi ve jiroskopu resimdeki gibi breadboard üzerine yerleştirin

- tüm negatif kabloları yerleştirin: mikrodenetleyiciye, neopiksel halkasına, jiroskopa

- tüm pozitif kabloları yerleştirin: mikrodenetleyiciye, neopiksel halkasına, jiroskopa

- tüm veri kablolarını yerleştirin:

* Mikrodenetleyiciden cayroya kadar SDA ve SCL

* mikrodenetleyiciden neopiksel halkasına pin D6

- güç vermeden önce tüm bağlantıları iki kez kontrol edin

- isteğe bağlı olarak koli bandı kullanarak, pil takımını yerinde tutmak ve daha taşınabilir hale getirmek için bradboard'un arkasına bantlayın

Adım 3: Kod ve Kalibrasyon

İlk önce iki kitaplık indirip kurmanız gerekir:

1. Neopixel'i kontrol eden Adafruit neopixel kitaplığı köknar

2. Jiroskop için MPU6050 kütüphanesi

3. I2CDev kitaplığı kaynağı

Ağır yükleri kaldıracak iki harika kütüphane!

Neopikseller hakkında daha fazla ayrıntı burada

Ardından kitaplığımı buradan indirip yükleyin veya aşağıdan kopyalayın:

#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 şeridi = Adafruit_NeoPixel(NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG + NEO_KHZ800); imzasız uzun lastPrintTime = 0; bool başlatma = yanlış; // DMP başlatma başarılıysa true olarak ayarla uint8_t mpuIntStatus; // MPU uint8_t devStatus'tan gelen gerçek kesme durumu baytını tutar; // her cihaz işleminden sonra durumu döndür (0 = başarı, !0 = hata) uint16_t packageSize; // beklenen DMP paket boyutu (varsayılan 42 bayttır) uint16_t fifoCount; // şu anda FIFO'da bulunan tüm baytların sayısı uint8_t fifoBuffer[64]; // FIFO depolama arabelleği Quaternion q; // [w, x, y, z] dörtlü kap VectorFloat yerçekimi; // [x, y, z] yerçekimi vektörü kayan nokta ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll konteyner ve yerçekimi vektörü uçucu bool mpuInterrupt = false; // MPU kesme pininin yükselip yükselmediğini gösterir

geçersiz kurulum()

{ Serial.başlangıç(9600); Serial.println("Program başladı"); başlatma = initializeGyroscope(); strip.begin(); } void loop() { if (!initialization) { return; } mpuInterrupt = yanlış; mpuIntStatus = mpu.getIntStatus(); fifoCount = mpu.getFIFOCount(); if (hasFifoOverflown(mpuIntStatus, fifoCount)) { mpu.resetFIFO(); dönüş; } if (mpuIntStatus & 0x02) { while (fifoCount < packageSize) { fifoCount = mpu.getFIFOCount(); } mpu.getFIFOBytes(fifoBuffer, packageSize); fifoCount -= paketSize; mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&yerçekimi, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); 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 = kısıtlama(y, -1 * MAX_ANGLE, MAX_ANGLE); if (y 0) { ışıkLed'leri(y, z, 0, 5, 0, 89); } else if (y < 0 ve z 0 ve z 0 ve z > 0) { lightLed'ler(y, z, 20, 24, 89, 0); } } void lightLeds(int x, int y, int fromLedPosition, int toLedPosition, int fromAngle, int toAngle) { double angle = (atan((double) abs(x) / (double) abs (y)) * 4068) / 71; int ledNr = map(açı, fromAngle, toAngle, fromLedPosition, toLedPosition); printDebug(x, y, ledNr, açı); uint32_t renk; for (int i=0; i pozisyonu + LED_OFFSET) { dönüş pozisyonu + LED_OFFSET; } dönüş konumu + LED_OFFSET - NUM_LEDS; } void printDebug(int y, int z, int lightLed, int angle) { if (millis() - lastPrintTime < 500) { dönüş; } Serial.print("a=");Serial.print(açı);Serial.print("; "); Serial.print("ll=");Serial.print(lightLed);Serial.print("; "); Seri.print("y=");Serial.print(y);Serial.print("; "); Serial.print("z=");Serial.print(z);Serial.println("; "); lastPrintTime = millis(); } bool initializeGyroscope() { Wire.begin(); TWBR = 24; mpu.initialize(); Serial.println(mpu.testConnection() ? F("MPU6050 bağlantısı başarılı"): F("MPU6050 bağlantısı başarısız")); Serial.println(F("DMP Başlatılıyor…")); devStatus = mpu.dmpInitialize(); mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); if (devStatus != 0) { Serial.print(F("DMP Başlatma başarısız (kod "));Serial.println(devStatus); false döndür; } mpu.setDMPEnabled(true); Serial.println(F("Etkinleştiriliyor) kesme algılama (Arduino harici kesme 0)…")); AttachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); Serial.println(F("DMP hazır! İlk kesme bekleniyor…")); packageSize = mpu.dmpGetFIFOPacketSize(); true döndür; } void dmpDataReady() { mpuInterrupt = true; }

Kodu yükleyin:

FTDI adaptörünü kullanarak kodu arduino'ya yükleyin.

Güç kaynağını (piller) bağlayın

Kalibrasyon:

Burada kalibre edilmesi gereken en önemli şey "LED_OFFSET" sabitidir. Örneğimde 12. Bunu 0'dan 23'e ayarlamanız gerekiyor, böylece tahtaya güç verdikten sonra led, tahtayı yatırdığınız yönde yanacak.

Nasıl çalıştığı hakkında daha fazla ayrıntı öğrenmek istiyorsanız, son adıma göz atın.

4. Adım: Nasıl Çalışır (isteğe bağlı)

Nasıl Çalışır (isteğe bağlı)
Nasıl Çalışır (isteğe bağlı)

Önce MPU6050 jiroskopu hakkında biraz bilgi. Bu bir MEMS jiroskopudur (MEMS, Mikroelektromekanik sistemler anlamına gelir).

Her tip MEM jiroskopu, ivmenin ve dolayısıyla yön değişiminin tespit edilebildiği bir tür salınım bileşenine sahiptir. Bunun nedeni, hareket yasasının korunumuna göre, titreşen bir nesne aynı düzlemde titreşmeye devam etmeyi sever ve herhangi bir titreşim sapması, yönde bir değişiklik elde etmek için kullanılabilir.

Gyro ayrıca, bazı fantezi matematiklerle yuvarlanma, eğim ve sapmayı hesaplamak için kendine ait bir mikro denetleyici içerir.

Ancak gyro ham verileri gürültü ve kaymadan muzdariptir, bu nedenle işleri düzeltmek ve bize temiz kullanılabilir veriler sağlamak için harici bir kitaplık kullandık.

Neopixel, ayrı ayrı adreslenebilen ve bantlara ve halkalara zincirlenmiş RGB ledlerdir. 5V üzerinde çalışırlar ve kendi devrelerini içerirler, bu nedenle sadece neopiksellere güç vermeniz ve veri hattını kullanarak onlarla iletişim kurmanız yeterlidir. İletişim, saat ve veri içeren tek bir veri hattı ile yapılır (daha fazla ayrıntı burada). Adafruit, neopiksel halkalarıyla etkileşim için temiz bir kitaplık sağlar.

kod

loop() işlevinin içinde MPU6050_6Axis_MotionApps20 kitaplığı çağrılır. Kütüphane gyroscpe'den yeni veriye sahip olduğunda, yaw, pitch ve roll'u temsil eden 3 argümanla redrawLeds(x, y, z) çağırır.

redrawLed'lerin içinde ():

- iki eksene odaklanıyoruz: y, z

- her iki ekseni de -MAX_ANGLE ile +MAX_ANGLE arasında sınırlandırıyoruz, maksimum açıyı 45 olarak tanımladık ve bu değiştirilebilir

- 360 dereceyi 4 çeyreğe bölüyoruz ve her biri için aşağıdaki gibi lightLeds() işlevlerini çağırıyoruz:

* y negatif, z pozitif birinci kadran 0'dan 5'e kadar ledleri kontrol edecek, açı 0'dan 89'a kadar olacak

* y negatif, z negatif ikinci kadran kontrol ledleri 6'dan 12'ye, açı 89'dan 0'a olacak

* …vesaire

- lightLeds işlevinin içinde

* arktanjant kullanarak iki eksene göre bir açı hesaplıyorum (ekteki resme bakın)

* arduino harita işlevini kullanarak neyin gösterilmesine yol açtığını hesaplıyorum

* led şeridini iki led hariç hepsini sıfırlıyorum, biri daha önce hesapladığım led pozisyonuna ve bir led pozisyonuna karşılık geliyor (solma efekti göstermek için)

* neopiksel kalibrasyonunu hesaba katmak için normalizeLedPosition() adlı bir işlev kullanıyorum. Kalibrasyon yararlıdır çünkü neopiksel halkası istenildiği gibi döndürülebilir ve jiroskop ile hizalanmalıdır.

* Ayrıca çekme eksenini de yazdırıyorum, ledin ışığı ve açısı var

Matematik

Açıyı belirlemek için kullanılan led halka ve trigonometrik fonksiyon ile bir resim ekledim.

Önerilen: