Cuprins:

Distracție cu giroscop cu inel Neopixel: 4 pași (cu imagini)
Distracție cu giroscop cu inel Neopixel: 4 pași (cu imagini)

Video: Distracție cu giroscop cu inel Neopixel: 4 pași (cu imagini)

Video: Distracție cu giroscop cu inel Neopixel: 4 pași (cu imagini)
Video: Bobiţă şi Buburuză compilaţie - ALFONZ ȘI DIMA 2024, Noiembrie
Anonim
Image
Image

În acest tutorial vom folosi giroscopul MPU6050, un inel de neopixel și un arduino pentru a construi un dispozitiv care luminează ledul corespunzător unghiului de înclinare.

Acesta este un proiect simplu și distractiv și va fi asamblat pe o placă de calcul. Dacă urmați pașii, veți construi ceea ce ați văzut în videoclip. Este un tutorial bun pentru a afla despre giroscop și inelul neopixel.

Construiesc acest tutorial din cauza interesului pe care l-am văzut la primul meu instructable aici (Gyroscope Led Control With Arduino). În acest instructiv am înlocuit ledurile simple cu un inel de neopixeli. Inelul este mai simplu de utilizat printr-o bibliotecă Adafruit și este cu siguranță mai spectaculos.

Deci, dacă aveți aceste componente în jurul valorii de aceasta, este o modalitate excelentă de a le folosi, voi încerca să vă trec pas cu pas prin construirea dispozitivului și, de asemenea, să explic cum funcționează în ultimul pas.

Pasul 1: Lucruri necesare

Asamblare
Asamblare

Părți

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

2. Pană de pâine

3. Giroscopul MPU6050 (eBay) 1,2 $

4. 24 inel led neopixel (Adafruit) 17 $

5. 4 x baterii AA cu 4 baterii

6. Cabluri jumper în formă de U (opțional). Am folosit aceste cabluri jumper pentru că arată mai bine pe panou, iar ledurile sunt mai vizibile în acest fel. Puteți găsi o cutie de 140 pe eBay la aproximativ 4 $. Dacă nu aveți aceste cabluri, le puteți înlocui cu fire dupont.

Instrumente:

1. Adaptor USB la serial FTDI FT232RL pentru a programa arduino pro mini

2. Arduino IDE

Abilități: 1. Lipire, verificați acest tutorial

3. Programare de bază arduino, acest tutorial ar putea fi util

Pasul 2: Asamblare

Asamblare
Asamblare

Am atașat schema fritzing în format fzz și o imagine a acestuia pentru vizualizarea ușoară a conexiunilor

1. Trebuie să lipiți 3 pini masculi pe partea din spate a inelului neopixel, așa cum se arată în imagine

- lipiți pinul pozitiv

- lipiți solul

- lipiți pinul de introducere a datelor

2. Apoi, suportul pentru baterie 4x ar trebui să aibă o modalitate de conectare la panou, o soluție ușoară este să lipiți două fire dupont masculine la terminalele sale.

3. Pregătiți panoul.

- așezați inelul de neopixel, microcontrolerul și giroscopul pe panoul de calcul ca în imagine

- plasați toate firele negative: la microcontroler, inel neopixel, giroscop

- amplasați toate firele pozitive: la microcontroler, inel neopixel, giroscop

- plasați toate firele de date:

* SDA și SCL de la microcontroler la giroscop

* pinul D6 de la microcontroler la inelul neopixel

- verificați dublu toate conexiunile înainte de alimentare

- opțional folosind bandă adezivă, lipiți pachetul de baterii pe partea din spate a plăcii pentru a-l ține în poziție și a-l face mai portabil

Pasul 3: Codul și calibrarea

Mai întâi trebuie să descărcați și să instalați două biblioteci:

1. Biblioteca Adafruit neopixel care controlează neopixelul

2. Biblioteca MPU6050 pentru giroscop

3. Sursa bibliotecii I2CDev

Sunt două mari biblioteci care vor face greutăți mari!

Mai multe detalii despre neopixeli aici

Apoi descărcați și instalați biblioteca de aici sau copiați-o de mai jos:

#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; initializare bool = falsa; // setați true dacă inițierea DMP a avut succes uint8_t mpuIntStatus; // deține octetul actual de stare de întrerupere de la MPU uint8_t devStatus; // returnează starea după fiecare operație a dispozitivului (0 = succes,! 0 = eroare) uint16_t pachet Dimensiune; // dimensiunea așteptată a pachetului DMP (implicit este de 42 de octeți) uint16_t fifoCount; // numărul tuturor octeților aflați în prezent în FIFO uint8_t fifoBuffer [64]; // buffer de stocare FIFO Quaternion q; // [w, x, y, z] cuaternion container VectorFloat gravity; // [x, y, z] vector de gravitație float ypr [3]; // [yaw, pitch, roll] yaw / pitch / roll container and gravity vector volatile bool mpuInterrupt = false; // indică dacă pinul de întrerupere MPU a crescut

configurare nulă ()

{Serial.begin (9600); Serial.println („Programul a început”); initialization = initializeGyroscope (); strip.begin (); } void loop () {if (! initialization) {return; } mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus (); fifoCount = mpu.getFIFOCount (); if (hasFifoOverflown (mpuIntStatus, fifoCount)) {mpu.resetFIFO (); întoarcere; } if (mpuIntStatus & 0x02) {while (fifoCount <packetSize) {fifoCount = mpu.getFIFOCount (); } mpu.getFIFOBytes (fifoBuffer, pachet Dimensiune); fifoCount - = pachet Dimensiune; mpu.dmpGetQuaternion (& q, fifoBuffer); mpu.dmpGetGravity (& gravitate, & 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 = constrângere (y, -1 * MAX_ANGLE, MAX_ANGLE); if (y 0) {lightLeds (y, z, 0, 5, 0, 89); } else if (y <0 și z 0 și 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 = hartă (unghi, de laAngle, laAngle, de laLedPosition, laLedPosition); printDebug (x, y, ledNr, angle); uint32_t culoare; for (int i = 0; i position + LED_OFFSET) {return position + LED_OFFSET; } poziție de întoarcere + LED_OFFSET - NUM_LEDS; } void printDebug (int y, int z, int lightLed, int angle) {if (millis () - lastPrintTime <500) {return; } Serial.print ("a ="); Serial.print (unghi); 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 ("conexiunea MPU6050 reușită"): F ("conexiunea MPU6050 a eșuat")); Serial.println (F ("Inițializarea DMP …")); devStatus = mpu.dmpInitialize (); mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1788); if (devStatus! = 0) {Serial.print (F ("DMP Initialization failed (code")); Serial.println (devStatus); return false;} mpu.setDMPEnabled (true); Serial.println (F ("Activare detectare întrerupere (întrerupere externă Arduino 0) … ")); attachInterrupt (0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus (); Serial.println (F (" DMP gata! Așteptare pentru prima întrerupere … ")); = mpu.dmpGetFIFOPacketSize (); return true;} void dmpDataReady () {mpuInterrupt = true;}

Încărcați codul:

Folosind adaptorul FTDI încărcați codul în arduino.

Conectați sursa de alimentare (baterii)

Calibrare:

Cel mai important lucru de calibrat aici este constanta „LED_OFFSET”. În exemplul meu este 12. Trebuie să reglați acest lucru de la 0 la 23, astfel încât, după alimentarea plăcii, ledul să se aprindă în direcția în care înclinați placa.

Dacă doriți să aflați mai multe detalii despre cum funcționează, consultați ultimul pas

Pasul 4: Cum funcționează (opțional)

Cum funcționează (opțional)
Cum funcționează (opțional)

Mai întâi câteva informații despre giroscopul MPU6050. Acesta este un giroscop MEMS (MEMS înseamnă sisteme microelectromecanice).

Fiecare tip de giroscop MEM are o formă de componentă oscilantă de unde poate fi detectată acclerația și, prin urmare, schimbarea direcției. Acest lucru se datorează faptului că, conform legii de conservare a mișcării, unui obiect care vibrează îi place să continue să vibreze în același plan și orice abatere vibrațională poate fi utilizată pentru a obține o schimbare de direcție.

Giroscopul conține, de asemenea, un microcontroler propriu pentru a calcula rularea, înălțimea și înclinarea prin câteva matematici fanteziste.

Dar datele brute giroscopice suferă de zgomot și derivație, așa că am folosit o bibliotecă externă pentru a netezi lucrurile și pentru a ne oferi date curate care pot fi utilizate.

Neopixel sunt leduri RGB adresabile individual și înlănțuite în benzi și inele. Funcționează pe 5V și conțin circuite proprii, deci trebuie doar să alimentați neopixeli și să comunicați cu aceștia folosind linia de date. Comunicarea se face cu o singură linie de date care conține ceas și date (mai multe detalii aici). Adafruit oferă o bibliotecă curată pentru interacțiunea cu inelele de neopixeli.

Codul

În funcția l oop () se numește biblioteca MPU6050_6Axis_MotionApps20. Când biblioteca are date noi din giroscop, ea apelează redrawLeds (x, y, z) cu 3 argumente care reprezintă yaw, pitch and roll

În interiorul redrawLeds ():

- ne concentrăm pe două axe: y, z

- constrângem ambii axi de la -MAX_ANGLE la + MAX_ANGLE, am definit unghiul maxim la 45 și este modificabil

- împărțim 360 de grade în 4 cadrane și apelăm funcțiile lightLeds () pentru fiecare după cum urmează:

* y negativ, z pozitiv primul cadran va controla ledurile de la 0 la 5, unghiul va fi de la 0 la 89

* y negativ, z negativ al doilea cadran controlează ledurile de la 6 la 12, unghiul va fi de la 89 la 0

* … etc.

- în interiorul funcției lightLeds

* Calculez un unghi bazat pe cele două axe folosind arctangent (verificați imaginea atașată)

* Calculez ceea ce a dus la afișare folosind funcția de hartă arduino

* Restabilesc banda LED-urilor, cu excepția a două LED-uri, cea care corespunde poziției de led pe care am calculat-o anterior și o poziție a led-ului înainte (pentru a arăta un efect de estompare)

* Folosesc o funcție numită normalizeLedPosition () pentru a ține cont de calibrarea neopixelului. Calibrarea este utilă deoarece inelul de neopixeli poate fi rotit după bunul plac și ar trebui aliniat cu giroscopul

* Imprim și axa de remorcare, ce led are lumină și unghiul

Matematica

Am atașat o imagine cu inelul led și funcția trigonometrică utilizată pentru a determina unghiul.

Recomandat: