Spisu treści:

Zabawa żyroskopem z pierścieniem Neopixel: 4 kroki (ze zdjęciami)
Zabawa żyroskopem z pierścieniem Neopixel: 4 kroki (ze zdjęciami)

Wideo: Zabawa żyroskopem z pierścieniem Neopixel: 4 kroki (ze zdjęciami)

Wideo: Zabawa żyroskopem z pierścieniem Neopixel: 4 kroki (ze zdjęciami)
Wideo: 🎆 LEGO TOP 10 ZESTAWÓW 2023 🎆 2024, Listopad
Anonim
Image
Image

W tym samouczku użyjemy żyroskopu MPU6050, pierścienia neopikselowego i arduino do zbudowania urządzenia, które zaświeci diodami odpowiadającymi kątowi nachylenia.

Jest to prosty i zabawny projekt, który zostanie złożony na płytce stykowej. Jeśli będziesz postępować zgodnie z instrukcjami, zbudujesz to, co widziałeś w filmie. To dobry samouczek do nauki o żyroskopie i pierścieniu neopikselowym.

Buduję ten samouczek ze względu na zainteresowanie, które widziałem na moim pierwszym instruktażowym tutaj (sterowanie led żyroskopu z Arduino). W tej instrukcji zamieniłem proste diody led na pierścień neopikselowy. Pierścionek jest prostszy w użyciu poprzez bibliotekę Adafruit i jest zdecydowanie bardziej spektakularny.

Więc jeśli masz te komponenty leżące dookoła, jest to świetny sposób na ich wykorzystanie, postaram się przeprowadzić Cię krok po kroku przez budowę urządzenia, a także wyjaśnić, jak to działa w ostatnim kroku.

Krok 1: Rzeczy wymagane

montaż
montaż

Części

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

2. Deska do krojenia chleba

3. Żyroskop MPU6050 (eBay) 1,2 $

4. 24 neopikselowy pierścień led (Adafruit) 17 $

5. 4 x zestaw baterii AA z 4 bateriami

6. Kable rozruchowe w kształcie litery U (opcjonalne). Użyłem tych zworek, ponieważ lepiej wyglądają na płytce stykowej, a diody są w ten sposób bardziej widoczne. Możesz znaleźć pudełko 140 na eBayu za około 4 $. Jeśli nie masz tych kabli, możesz je zastąpić przewodami dupontowymi.

Narzędzia:

1. Adapter USB na szeregowy FTDI FT232RL do programowania arduino pro mini

2. IDE Arduino

Umiejętności:1. Lutowanie, sprawdź ten samouczek

3. Podstawowe programowanie arduino, ten samouczek może się przydać

Krok 2: Montaż

montaż
montaż

Dołączyłem schemat fritzowania w formacie fzz i jego zdjęcie w celu łatwej wizualizacji połączeń

1. Musisz przylutować 3 męskie piny z tyłu pierścienia neopikselowego, jak pokazano na zdjęciu

- wlutować pin dodatni

- przylutuj ziemię

- przylutuj pin wejściowy danych

2. Następnie uchwyt baterii 4x powinien mieć możliwość podłączenia do płytki stykowej, łatwym rozwiązaniem jest przylutowanie dwóch męskich przewodów dupont do jego zacisków.

3. Przygotuj płytkę stykową.

- umieść pierścień neopikselowy, mikrokontroler i żyroskop na płytce stykowej jak na obrazku

- umieść wszystkie ujemne przewody: do mikrokontrolera, pierścienia neopikselowego, żyroskopu

- umieść wszystkie przewody dodatnie: do mikrokontrolera, pierścienia neopixel, żyroskopu

- umieść wszystkie przewody danych:

* SDA i SCL od mikrokontrolera do żyroskopu

* pin D6 z mikrokontrolera do pierścienia neopixel

- przed włączeniem sprawdź dokładnie wszystkie połączenia

- opcjonalnie używając taśmy klejącej, przyklej akumulator z tyłu tablicy, aby utrzymać go na miejscu i uczynić go bardziej przenośnym

Krok 3: Kod i kalibracja

Najpierw musisz pobrać i zainstalować dwie biblioteki:

1. Biblioteka neopikseli Adafruit kontrolująca neopiksel

2. Biblioteka MPU6050 dla żyroskopu

3. Źródło biblioteki I2CDev

To dwie wspaniałe biblioteki, które podniosą ciężar!

Więcej szczegółów na temat neopikseli tutaj

Następnie pobierz i zainstaluj moją bibliotekę stąd lub skopiuj ją poniżej:

#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; Pasek Adafruit_NeoPixel = Adafruit_NeoPixel (NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG + NEO_KHZ800); unsigned long lastPrintTime = 0; inicjalizacja bool = fałsz; // ustaw true jeśli inicjowanie DMP powiodło się uint8_t mpuIntStatus; // przechowuje aktualny bajt stanu przerwania z MPU uint8_t devStatus; // zwróć status po każdej operacji urządzenia (0 = sukces, !0 = błąd) uint16_t packetSize; // oczekiwany rozmiar pakietu DMP (domyślnie 42 bajty) uint16_t fifoCount; // liczba wszystkich bajtów znajdujących się aktualnie w FIFO uint8_t fifoBuffer[64]; // bufor pamięci FIFO Quaternion q; // [w, x, y, z] kontener kwaternionowy VectorFloat grawitacja; // [x, y, z] wektor grawitacji float ypr[3]; // [odchylenie, skok, przechylenie] kontener zbaczania/pochylenia/przechylenia i wektor grawitacji volatile bool mpuInterrupt = false; // wskazuje, czy pin przerwania MPU osiągnął stan wysoki

pusta konfiguracja()

{ Szeregowy.początek(9600); Serial.println("Program uruchomiony"); inicjalizacja = InitializeGyroscope(); strip.początek(); } void loop() { if (!inicjalizacja) { return; } mpuInterrupt = fałsz; mpuIntStatus = mpu.getIntStatus(); fifoCount = mpu.getFIFOCount(); if (hasFifoOverflown(mpuIntStatus, fifoCount)) { mpu.resetFIFO(); powrót; } if (mpuIntStatus & 0x02) { while (fifoCount < rozmiar_pakietu) { fifoCount = mpu.getFIFOCount(); } mpu.getFIFOBytes(fifoBuffer, rozmiar_pakietu); fifoCount -= rozmiarpakietu; mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&grawitacja, &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 = ograniczenie(y, -1 * MAX_ANGLE, MAX_ANGLE); if (y 0) { lightLeds(y, z, 0, 5, 0, 89); } else if (y < 0 i z 0 oraz z 0 i z > 0) { lightLeds(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(angle, fromAngle, toAngle, fromLedPosition, toLedPosition); printDebug(x, y, ledNr, kąt); kolor uint32_t; for (int i=0; i pozycja + LED_OFFSET) { pozycja powrotu + LED_OFFSET; } pozycja powrotu + LED_OFFSET - NUM_LEDS; } void printDebug(int y, int z, int lightLed, int angle) { if (millis() - lastPrintTime < 500) { return; } Serial.print("a=");Serial.print(kąt);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 = millis(); } bool InitializeGyroscope() { Wire.begin(); TWBR = 24; mpu.initialize(); Serial.println(mpu.testConnection() ? F("Połączenie MPU6050 powiodło się"): F("Połączenie MPU6050 nie powiodło się")); Serial.println(F("Inicjowanie DMP…")); devStatus = mpu.dmpInitialize(); mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); if (devStatus != 0) { Serial.print(F("Inicjalizacja DMP nie powiodła się (kod "));Serial.println(devStatus); return false; } mpu.setDMPEnabled(true); Serial.println(F("Włączanie wykrywanie przerwań (zewnętrzne przerwanie Arduino 0)…")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); Serial.println(F("DMP gotowy! Oczekiwanie na pierwsze przerwanie…")); = mpu.dmpGetFIFOPacketSize(); return true; } void dmpDataReady() { mpuInterrupt = true; }

Prześlij kod:

Za pomocą adaptera FTDI wgraj kod do arduino.

Podłącz zasilanie (baterie)

Kalibrowanie:

Najważniejszą rzeczą do kalibracji jest tutaj stała „LED_OFFSET”. W moim przykładzie jest 12. Trzeba to wyregulować od 0 do 23, aby po włączeniu deski dioda zapalała się w kierunku, w którym pochylasz deskę.

Jeśli chcesz dowiedzieć się więcej o tym, jak to działa, sprawdź ostatni krok

Krok 4: Jak to działa (opcjonalnie)

Jak to działa (opcjonalnie)
Jak to działa (opcjonalnie)

Najpierw trochę informacji o żyroskopie MPU6050. Jest to żyroskop MEMS (MEMS oznacza systemy mikroelektromechaniczne).

Każdy typ żyroskopu MEM ma pewną formę elementu oscylacyjnego, z którego można wykryć przyspieszenie, a tym samym zmianę kierunku. Dzieje się tak, ponieważ zgodnie z zasadą zachowania ruchu wibrujący obiekt lubi nadal wibrować w tej samej płaszczyźnie, a każde odchylenie wibracyjne można wykorzystać do uzyskania zmiany kierunku.

Żyroskop zawiera również własny mikrokontroler do obliczania przechyłu, pochylenia i odchylenia za pomocą wymyślnej matematyki.

Ale surowe dane żyroskopowe cierpią z powodu szumu i dryfu, więc użyliśmy zewnętrznej biblioteki, aby wygładzić rzeczy i dać nam czyste, użyteczne dane.

Neopixel to diody LED RGB, które są indywidualnie adresowane i połączone w paski i pierścienie. Działają na 5V i zawierają własne obwody, więc wystarczy zasilić neopiksele i komunikować się z nimi za pomocą linii danych. Komunikacja odbywa się za pomocą pojedynczej linii danych zawierającej zegar i dane (więcej szczegółów tutaj). Adafruit zapewnia czystą bibliotekę do interakcji z pierścieniami neopikselowymi.

Kod

Wewnątrz funkcji loop() wywoływana jest biblioteka MPU6050_6Axis_MotionApps20. Gdy biblioteka ma nowe dane z żyroskopu, wywołuje redrawLeds(x, y, z) z 3 argumentami reprezentującymi odchylenie, pochylenie i przechylenie

Wewnątrz przerysowanych diod ():

- skupiamy się na dwóch osiach: y, z

- ograniczamy obie osie od -MAX_ANGLE do +MAX_ANGLE, maksymalny kąt zdefiniowaliśmy na 45 i jest zmienny

- dzielimy 360 stopni na 4 ćwiartki i wywołujemy funkcje lightLeds() dla każdego w następujący sposób:

* y ujemny, z dodatni pierwszy kwadrant będzie sterował diodami od 0 do 5, kąt będzie wynosił od 0 do 89

* y ujemne, z ujemne diody kontrolne drugiej ćwiartki od 6 do 12, kąt będzie wynosił od 89 do 0

* …itd.

- wewnątrz funkcji lightLeds

* obliczam kąt w oparciu o dwie osie za pomocą arctangensa (patrz załączony obrazek)

* obliczam, co doprowadziło do wyświetlenia za pomocą funkcji mapy arduino

* resetuję pasek led wszystkich oprócz dwóch diod led, jednej odpowiadającej pozycji led, którą obliczyłem wcześniej i pozycji led wcześniej (aby pokazać efekt zanikania)

* używam funkcji o nazwie normalizeLedPosition(), aby uwzględnić kalibrację neopixel. Kalibracja jest przydatna, ponieważ pierścień neopiksela można dowolnie obracać i powinien być wyrównany z żyroskopem

*drukuję też oś holowania, co dioda ma światło i kąt

Matematyka

Dołączyłem obrazek z pierścieniem led i funkcją trygonometryczną służącą do określenia kąta.

Zalecana: