Cuprins:
2025 Autor: John Day | [email protected]. Modificat ultima dată: 2025-01-13 06:58
Întotdeauna mi-am dorit să fac un proiect Arduino, dar nu am avut niciodată idei grozave pentru unul până când familia mea nu a fost invitată la o petrecere de pălării fanteziste. Cu un timp de plumb de două săptămâni, eram curios dacă aș putea să planific și să execut o pălărie de animație LED sensibilă la mișcare. Se pare că aș putea! Probabil că am trecut puțin peste bord, dar proiectul total a costat aproximativ 80 USD. Cu experimentarea și unele coduri, puteți face acest lucru pentru mai puțin.
Scopul pălăriei a fost următorul:
- Faceți un set de lumini să se deplaseze din fața centrală a pălăriei în spate, câte o lumină de fiecare parte
- Schimbați viteza de deplasare a luminii dictată de înclinarea pălăriei față în spate
- Lăsați luminile să inverseze atunci când banda pălăriei a fost înclinată în jos (adică emulați efectul gravitației asupra luminilor)
- Schimbați culoarea pe baza înclinării pălăriei de la stânga la dreapta
- Simți șocurile și afișează un efect special
- Simțiți că purtătorul se învârte și afișați un efect special
- Să-l conțin complet în pălărie
Pasul 1: Piese necesare
Am folosit următoarele componente majore (link-uri Amazon neafiliate incluse):
- Microcontroler Teensy LC - Am ales acest lucru în locul unui Arduino obișnuit datorită dimensiunilor sale reduse și având o conexiune specială pentru controlul LED-urilor mele, precum și un suport puternic pentru bibliotecă și comunitate.
- Senzor de poziție bazat pe Bosch BNO055 - sincer unul dintre primii pe care am găsit documentație. Există opțiuni mult mai puțin costisitoare, cu toate acestea, odată ce vă dați seama că Bosch face multe pentru dvs., altfel ar trebui să faceți în cod
- Benzi LED adresabile WS2812 - Am ales o lungime de 1 metru cu 144 LED-uri pe metru. Având această densitate, lumina arată mai mult ca și cum ar fi în mișcare, decât elemente individuale care se aprind în ordine.
Și următoarele componente minore:
- O pălărie - orice pălărie cu bandă de pălărie o va face. Aceasta este o pălărie de 6 USD de la un magazin local. Dacă are o cusătură în spate, va fi mai ușor să treceți cablajul. Acordați atenție dacă banda de pălărie este lipită, deoarece aceasta va provoca și unele dificultăți suplimentare. Acesta este cusut de-a lungul vârfului, dar partea de jos a tras cu ușurință.
- Rezistențe de 4,7K ohm
- 3x carcasă pentru baterii AAA - folosind 3 baterii AAA, ieșire tensiune exact în intervalul dorit de electronică, ceea ce simplifică lucrurile. AAA se potrivește într-o pălărie mai ușor decât AA și are încă un timp de rulare excelent.
- Sârmă cu ecartament mic - Am folosit câteva sârme solide pe care le aveam în jurul unui proiect anterior cu LED-uri.
- Fier de lipit și lipit
- Unele spandex care se potrivesc cu culoarea interioară a pălăriei și a firului
Sugerat, dar opțional:
- Conectori rapidi pentru firele bateriei
- Instrumentul Mâini ajutătoare, aceste lucruri sunt foarte mici și greu de lipit
Pasul 2: Modificați pălăria
Veți avea nevoie de un loc în pălărie pentru a monta electronica și un loc pentru baterie. Soția mea lucrează profesional cu îmbrăcăminte, așa că i-am cerut sfaturi și ajutor. Am ajuns să creăm două buzunare cu spandex. Primul buzunar mai mic spre față este îndreptat ca pălăria în sine, astfel încât atunci când sunt instalate componentele electronice, senzorul de poziție este ținut destul de bine în poziție, dar poate fi îndepărtat cu ușurință, dacă este necesar. Al doilea buzunar spre spate este să țineți acumulatorul în poziție.
Buzunarele erau însămânțate cu fire care se potriveau cu culoarea pălăriei, pe toată lungimea liniei coroanei. În funcție de stilul pălăriei și de materiale, este realizat din YMMV cu această tehnică.
De asemenea, am descoperit că banda de pălărie se înfășoară într-o parte și a fost complet cusută în pălărie în acea locație. A trebuit să scoatem cusătura originală pentru a rula LED-urile sub bandă. În timpul construcției, a fost ținut în loc cu știfturi, și apoi cusut cu firul potrivit când a fost finalizat.
În cele din urmă, am deschis cusătura pe spatele pălăriei, în cazul în care este acoperită de bandă. Am ascuns cablajul care a venit cu LED-urile prin acea cusătură și am căptușit primul LED din bandă care se află chiar pe cusătură. Apoi am înfășurat LED-urile în jurul pălăriei și am tăiat banda în jos, astfel încât ultimul LED să fie chiar lângă primul. Banda LED poate fi ținută în poziție doar cu banda de pălărie, cu toate acestea, în funcție de banda și materialul dvs., poate fi necesar să fixați LED-urile prin coasere sau lipire.
Pasul 3: conectați-l
Placa Teensy și LED-urile vor funcționa oriunde de la 3,3v la 5v pentru putere. Acesta este motivul pentru care am ales să folosesc 3 baterii AAA, tensiunea de ieșire de 4.5v este foarte bună în acea gamă și au o mulțime de timp de funcționare pentru modul în care am programat LED-urile să funcționeze. Ar trebui să puteți obține peste 8 ore de rulare.
Cablarea puterii
Am conectat cablurile pozitive și negative de la cutia bateriei și de la LED-uri împreună, apoi am lipit pe Teensy în locațiile corespunzătoare. Pozitivul de la baterie trebuie să fie conectat la pinul din dreapta sus al Teensy din diagramă (etichetat Vin pe tablă), iar negativul poate fi conectat la orice pin etichetat GND. În mod convenabil, există unul direct pe partea opusă a plăcii sau chiar lângă știftul Vin. Diagrama completă de afișare a plăcii poate fi găsită în partea de jos a acestei pagini. Și, în unele cazuri, o copie pe hârtie este inclusă atunci când comandați placa.
Dacă intenționați să rulați codul care are doar câteva LED-uri pornite simultan, puteți alimenta LED-urile de la Teensy în sine, utilizând o ieșire de 3,3 V și GND, totuși, dacă încercați să extrageți prea multă energie, puteți deteriorați placa. Deci, pentru a vă oferi cele mai multe opțiuni, cel mai bine este să conectați LED-urile direct la sursa bateriei.
Cablarea LED-urilor
Am ales Teensy LC pentru acest proiect, deoarece are un știft care face mult mai ușor conectarea LED-urilor adresabile. În partea de jos a plăcii, pinul care este al doilea din oglinzile stânga Pin # 17, dar are și 3.3v pe el. Aceasta este denumită pull-up și pe alte plăci ar trebui să conectați un rezistor pentru a furniza tensiunea respectivă. În cazul modelului Teensy LC, puteți doar să conectați de la acel pin direct la firul de date al LED-urilor.
Cablarea senzorului de poziție
Unele dintre plăcile BNO055 disponibile sunt mult mai stricte în ceea ce privește tensiunea și doresc doar 3.3v. Din această cauză, am conectat vinul pe placa BNO055 de la ieșirea dedicată de 3,3v de pe Teensy, care este al treilea pin în dreapta. Apoi puteți conecta GND de pe BNO055 la orice GND de pe Teensy.
Senzorul de poziție BNO055 folosește I2c pentru a vorbi cu Teensy. I2c necesită pull-up-uri, așa că am conectat două rezistențe de 4.7K ohm de la o ieșire de 3.3v pe Teensy la pinii 18 și 19. Am conectat apoi pinul 19 la pinul SCL de pe placa BNO055 și 18 la pinul SDA.
Sfaturi / trucuri de cablare
Pentru a face acest proiect, am folosit mai degrabă sârmă solidă decât eșuată. Un avantaj pentru sârmă solidă este în timpul lipirii pe plăci prototip ca acestea. Puteți dezlipi niște fire, îndoiți-le la 90 de grade și le puteți introduce prin partea inferioară a unuia dintre terminale, astfel încât capătul tăiat al firului să rămână deasupra plăcii. Apoi, aveți nevoie doar de o cantitate mică de lipit pentru ao ține la terminal și puteți tăia cu ușurință excesul.
Sârma solidă poate fi mai dificil de lucrat, deoarece tinde să dorească să rămână așa cum este îndoit. Cu toate acestea, pentru acest proiect, acesta a fost un avantaj. Mi-am tăiat și mi-am modelat firele în așa fel încât orientarea senzorului de poziție să fie consecventă pe măsură ce am introdus și am scos electronica din pălărie pentru ajustări și programare.
Pasul 4: Programare
Acum, că totul este asamblat, veți avea nevoie de un instrument de programare compatibil Arduino. Am folosit actualul Arduino IDE (funcționează cu Linux, Mac și PC). De asemenea, veți avea nevoie de software-ul Teensyduino pentru a interacționa cu placa Teensy. Acest proiect folosește în mare măsură biblioteca FastLED pentru a realiza programarea culorilor și a poziției LED-urilor.
Calibrarea
Primul lucru pe care îl veți dori să faceți este să accesați excelentul depozit GitHub al lui Kris Winer pentru BNO055 și să descărcați schița BNO_055_Nano_Basic_AHRS_t3.ino. Instalați codul cu monitorul serial în funcțiune și vă va spune dacă placa BNO055 vine în mod corespunzător online și își trece testele proprii. De asemenea, vă va conduce prin calibrarea BNO055, ceea ce vă va oferi rezultate mai consistente ulterior.
Noțiuni introductive despre schița Fancy LED
Codul pentru pălăria Fancy LED este atașat în mod specific și, de asemenea, în depozitul meu GitHub. Am de gând să fac mai multe modificări la cod și acestea vor fi postate pe repo GitHub. Fișierul de aici reflectă codul când a fost publicat acest Instructable. După descărcarea și deschiderea schiței, există câteva lucruri pe care va trebui să le schimbați. Majoritatea valorilor importante de modificat se află în partea de sus ca declarații #define:
Linia 24: #define NUM_LEDS 89 - schimbați acest lucru cu numărul real de LED-uri de pe banda dvs. de LED-uri
Linia 28: #define SERIAL_DEBUG false - probabil veți dori să faceți acest lucru adevărat, astfel încât să puteți vedea ieșirea pe monitorul serial
Codul de detectare a poziției
Detectarea poziției și majoritatea modificărilor dvs. începe de la linia 742 și trece prin 802. Obținem date Pitch, Roll și Yaw de la senzorul de poziție și le folosim pentru a seta valori. În funcție de modul în care sunt montate componentele electronice, poate fi necesar să le schimbați. Dacă montați senzorul de poziție cu cipul în partea de sus a pălăriei, iar săgeata de lângă X imprimată pe tablă îndreptată spre partea din față a pălăriei, ar trebui să vedeți următoarele:
- Pitch dă din cap
- Rola îți înclină capul, de ex. atinge-ți urechea de umăr
- Yaw este în ce direcție. vă confruntați (nord, vest etc.).
Dacă placa dvs. este montată într-o altă orientare, va trebui să schimbați Pitch / Roll / Yaw pentru ca aceștia să se comporte așa cum ați dori.
Pentru a regla setările Roll, puteți schimba următoarele valori #define:
- ROLLOFFSET: cu pălăria stabilă și cât mai centrată, dacă Roll-ul nu este 0, schimbați acest lucru prin diferență. Adică dacă vedeți Roll la -20 când pălăria este centrată, faceți acest 20.
- ROLLMAX: valoarea maximă de utilizat pentru măsurarea rolelor. Cel mai ușor de găsit purtând pălăria și mișcând urechea dreaptă spre umărul drept. Veți avea nevoie de un cablu USB lung pentru a face acest lucru în timp ce utilizați monitorul serial.
- ROLLMIN: cea mai mică valoare de utilizat pentru măsurarea rolelor, atunci când vă înclinați capul spre stânga
În mod similar, pentru Pitch:
- MAXPITCH - valoarea maximă atunci când căutați în sus
- MINPITCH - valoarea minimă când priviți în jos
- PITCHCENTER - valoarea tonului atunci când privești direct
Dacă setați SERIALDEBUG la adevărat în partea de sus a fișierului, ar trebui să vedeți valorile curente pentru ieșirea Roll / Pitch / Yaw pe monitorul serial pentru a ajuta la ajustarea acestor valori.
Alți parametri pe care poate doriți să îi modificați
- MAX_LED_DELAY 35 - cel mai lent pe care îl poate mișca particula LED. Aceasta este în milisecunde. Este întârzierea de la trecerea de la un LED la următorul din șir.
- MIN_LED_DELAY 10 - postul pe care îl poate mișca particula LED. Ca mai sus, este în milisecunde.
Concluzie
Dacă ați mers până aici, ar trebui să aveți o pălărie cu LED-uri pe deplin funcțională și distractivă! Dacă doriți să faceți mai mult cu el, pagina următoare conține câteva informații avansate despre modificarea setărilor și despre realizarea propriilor lucruri. precum și câteva explicații despre ceea ce face restul codului meu.
Pasul 5: Avansat și opțional: În interiorul codului
Detectarea impactului și a centrifugării
Detectarea impactului / rotirii se face folosind funcțiile senzorului high-G ale BNO055. Puteți modifica sensibilitatea acestuia cu următoarele rânduri în initBNO055 ():
- Linia nr. 316: BNO055_ACC_HG_DURATION - cât timp trebuie să dureze evenimentul
- Linia # 317: BNO055_ACC_HG_THRESH - cât de greu trebuie să fie impactul
- Linia # 319: BNO055_GYR_HR_Z_SET - prag de viteză de rotație
- Linia # 320: BNO055_GYR_DUR_Z - cât timp trebuie să dureze rotația
Ambele valori sunt binare pe 8 biți, în prezent impactul este setat la B11000000, care este 192 din 255.
Când este detectat un impact sau rotire, BNO055 stabilește o valoare pe care codul o caută chiar la începutul buclei:
// Detectați orice întreruperi declanșate, adică datorită octetului G ridicat intStatus = readByte (BNO055_ADDRESS, BNO055_INT_STATUS); if (intStatus> 8) {impact (); } else if (intStatus> 0) {spin (); }
Căutați linia void impact () de mai sus în cod pentru a schimba comportamentul la impact sau void spin () pentru a schimba comportamentul de rotire.
Ajutoare
Am creat o funcție simplă de ajutor (void setAllLeds ()) pentru setarea rapidă a tuturor LED-urilor la o singură culoare. Unul îl folosește pentru a le opri pe toate:
setAllLeds (CRGB:: Negru);
Sau puteți alege orice culoare recunoscută de biblioteca FastLED:
setAllLeds (CRGB:: Red);
Există, de asemenea, o funcție fadeAllLeds () care va diminua toate LED-urile cu 25%.
Clasa Particulelor
Pentru a simplifica foarte mult cablarea, am vrut să folosesc un singur șir de LED-uri, dar să se comporte ca niște șiruri multiple. Deoarece aceasta a fost prima mea încercare, am vrut să o păstrez cât mai simplă posibil, așa că tratez un șir ca două, cu LED-urile din mijloc fiind acolo divizarea ar fi. Întrucât am putea avea un număr par sau un număr impar, trebuie să ne explicăm acest lucru. Încep cu câteva variabile globale:
/ * * Variabile și containere pentru LED-uri * / Led-uri CRGB [NUM_LEDS]; static unsigned int curLedDelay = MAX_LED_DELAY; static int centerLed = NUM_LEDS / 2; static int maxLedPos = NUM_LEDS / 2; static bool oddLeds = 0; particula bool statică Dir = 1; static bool speedDir = 1; dirCount lung nesemnat; hueCont lung nesemnat;
Și un anumit cod în setup ():
if (NUM_LEDS% 2 == 1) {oddLeds = 1; maxLedPos = NUM_LEDS / 2; } else {oddLeds = 0; maxLedPos = NUM_LEDS / 2 - 1; }
Dacă avem numere impare, vrem să folosim punctul 1/2 ca mijloc, altfel vrem punctul 1/2 - 1. Acest lucru este ușor de văzut cu 10 sau 11 LED-uri:
- 11 LED-uri: 11/2 cu numere întregi ar trebui să evalueze la 5. iar calculatoarele contează de la 0. Deci 0 - 4 este o jumătate, 6 - 10 este cealaltă jumătate și 5 este între ele. Tratăm numărul 5 în acest caz ca și cum ar fi făcut parte din ambele, adică este numărul 1 pentru ambele șiruri virtuale de LED-uri
- 10 LED-uri: 10/2 este 5. Dar, deoarece calculatoarele contează de la 0, trebuie să eliminăm unul. Apoi avem 0 - 4 pentru o jumătate și 5 - 9 pentru cealaltă. # 1 pentru primul șir virtual va fi 4, iar # 1 pentru al doilea șir virtual va fi # 5.
Apoi, în codul nostru de particule, trebuie să facem o numărare de la poziția noastră generală la pozițiile reale pe șirul de LED-uri:
if (oddLeds) {Pos1 = centerLed + currPos; Pos2 = centerLed - currPos; } else {Pos1 = centerLed + currPos; Pos2 = (centerLed -1) - currPos; }
Codul are, de asemenea, condiții în care particula poate schimba direcțiile, deci trebuie să ținem cont și de acestea:
if (particleDir) {if ((currPos == NUM_LEDS / 2) && oddLeds) {currPos = 0; } else if ((currPos == NUM_LEDS / 2 - 1) && (! oddLeds)) {currPos = 0; } else {currPos ++; }} else {if ((currPos == 0) && oddLeds) {currPos = centerLed; } else if ((currPos == 0) && (! oddLeds)) {currPos = centerLed - 1; } else {currPos--; }}
Deci, folosim direcția dorită (particleDir), pentru a calcula ce LED ar trebui să fie aprins în continuare, dar trebuie, de asemenea, să luăm în considerare dacă am ajuns fie la capătul real al șirului de LED-uri, fie la punctul nostru central, care acționează și ca un capăt pentru fiecare dintre șirurile virtuale.
Odată ce ne-am dat seama de toate acestea, aprindem următoarea lumină după cum este necesar:
if (particuleDir) {if (oddLeds) {Pos1 = centerLed + currPos; Pos2 = centerLed - currPos; } else {Pos1 = centerLed + currPos; Pos2 = (centerLed -1) - currPos; }} else {if (oddLeds) {Pos1 = centerLed - currPos; Pos2 = centerLed + currPos; } else {Pos1 = centerLed - currPos; Pos2 = (centruLed -1) + currPos; }} leduri [Pos1] = CHSV (currHue, 255, 255); leduri [Pos2] = CHSV (currHue, 255, 255); FastLED.show ();}
De ce să facem această clasă deloc? Într-adevăr, acest lucru este destul de simplu și nu trebuie să fie într-adevăr într-o clasă. Cu toate acestea, am planuri viitoare de a actualiza codul pentru a permite să apară mai mult de o particulă la un moment dat, iar unele să funcționeze invers, în timp ce altele merg mai departe. Cred că există câteva posibilități foarte bune pentru detectarea spinului folosind mai multe particule.