Inhoudsopgave:

Arduino & Neopixel Coke Bottle Rainbow Party Light - Ajarnpa
Arduino & Neopixel Coke Bottle Rainbow Party Light - Ajarnpa

Video: Arduino & Neopixel Coke Bottle Rainbow Party Light - Ajarnpa

Video: Arduino & Neopixel Coke Bottle Rainbow Party Light - Ajarnpa
Video: Arduino & Neopixel Coke Bottle Party Light 2024, November
Anonim
Image
Image

Dus mijn zoon Doon ziet een heel cool feestlicht gemaakt van oude colaflessen en de kleverige ingewanden van Glow Sticks, en vraagt of we er een kunnen maken voor zijn aanstaande schoolexamens zijn voorbij Blowout PartAYYY!!! Ik zeg zeker, maar zou je niet liever een paar van die sjieke Adafruit Neopixel Rings hebben waar we over hebben gelezen… Hij kijkt me met een lege blik aan. Want feit is dat hij niet weet waar ik het over heb, maar papa heeft een kans gezien om te spelen met die Neopixel-ringen waar hij over heeft gelezen, en we kennen allemaal een van de top 10 redenen waarom geekvaders zich voortplanten is om een excuus om te spelen met coole gadgets waarvan ze zeggen dat ze allemaal voor hun kinderen zijn.

Dit is een supereenvoudig project dat er echt geweldig uitziet. We bouwden de onze van 3 oude colaflessen, een houten plaat en een beugel voor een speelpaal -- spullen die in de kelder rondslingeren -- gecombineerd met een Arduino (in ons geval Leonardo, maar elk Genuino-bord zal het doen!) en drie Neopixel-ringen. Ik bestelde een 9-LED-ring, maar eindigde met een 12-LED-ring voor dezelfde prijs. Dat was lief, maar betekende een opknapbeurt van de putgaten - de 12-LED-ringen zijn 35 mm breed, in tegenstelling tot 23 mm. Wat je nodig hebt:

  • Genuino/Arduino-bord (we gebruikten een Leonardo, maar bijna elk bord zal het doen)
  • 3 Neopixel-ringen (elk 12 LED's): haal ze van Adafruit en steun die fijne mensen
  • 1000 µf 6.3v of betere condensator
  • 300-500 ohm weerstand
  • Een houten bord, of een stuk sloophout, of wat dan ook waar je de neopixels in kunt plaatsen en de colaflesjes erop kunt zetten
  • Een of andere vorm van bevestiging voor de plaat - een beugel voor een speelpaal werkte prima voor ons
  • 9v muurwrat
  • Gatenboor van 40 mm
  • Bouten, moeren, ringen, afstandhouders
  • Massieve kerndraad
  • Een soldeerbout en soldeer
  • Breadboard
  • Een plastic behuizing voor de Arduino. Je kunt een heel mooie, perfect passende plastic koffer kopen, gemaakt van een miljoen jaar oude aardolie die in een kwetsbare omgeving uit de grond is geboord en aan de andere kant van de planeet is vervaardigd en in een container naar een magazijn bij jou in de buurt is verscheept met alle poorten zijn perfect uitgelijnd en laten het bij je thuis bezorgen door een busje dat koolstofdioxide in de atmosfeer spuwt. Of je kunt doen wat ik deed en een oude afgedankte plastic doos gebruiken.. in dit geval een pleisterdoos uit Madagaskar die in het medicijnkastje ligt… en er een paar gaten in boren. Hier eindigt de lezing. Laten we maken…

Stap 1: Maak de basis

Maak de basis
Maak de basis
Maak de basis
Maak de basis

Je kunt je basis improviseren met alle rommel die je in je eigen kelder hebt, of zelfs gewoon een houten kist gebruiken of iets dat je elektronica verbergt.

Eerst hebben we drie gaten geboord, gelijkmatig verdeeld over de houten plaat, groot genoeg voor de Neopixel-ringen. Op de afbeelding zijn de gaten geboord met een spadeboor. Uiteindelijk moesten we vanwege het grotere formaat van de 12-LED-ringen gaten boren met een boor. Dit betekende dat ik helemaal door de plaat moest gaan, en in plaats van de ringen mooi in hun fijn gemaakte kleine 2 mm diepe putten met een gat in het midden voor een nette draadloop te steken, heb ik de ringen uiteindelijk vastgezet met … ahem … ducttape over de bodem van de plaat. Oordeel niet. In mijn ontwerp zie je sowieso de onderkant van het bord niet. En het is donker als het aan is. En bovendien -- wat is er mis met ducttape?

Ik had ruimte nodig tussen de plaat en de beugel voor een breadboard aan de onderkant van de plaat en één onderdeel - de condensator, en voor de draadlopen die van het breadboard naar Arduino moesten gaan, die ik in de beugel wilde plaatsen. Dus ik heb een set geïmproviseerde afstandhouders op de boutassen geplaatst om voldoende speling te geven - ongeveer 3 cm, de hoogte van het breadboard en een beetje zodat je de bedrading niet verplettert. Ik gebruikte twee houten ankerbouten per hoek omdat ze de juiste hoogte hadden en in de mannenlade rondslingerden… die doos met losse schroeven, bouten, spijkers, roestige kettingschakels, slangkoppelingen, oude munten, onverwacht scherpe voorwerpen en van alles van stukjes en beetjes die je op magische wijze een reis naar de ijzerhandel kunnen besparen door iets aan te bieden dat, zo niet precies wat je nodig hebt, prima zal werken.

Gelukkig ongeluk over de speelplaatspaal die ik in de kelder vond, was dat er al gaten door de plaat liepen. Je hoeft niet in ijzer te boren! De basis had vier boutgaten en we boorden vier verzonken gaten in de houten plaat die bij elkaar pasten.

Vervolgens hebben we het geheel Gothic Black gespoten.

Stap 2: De Neopixel-ringen voorbereiden

De Neopixel-ringen voorbereiden
De Neopixel-ringen voorbereiden

U moet draden op uw neopixel-ringen solderen: een Data-In-draad voor allemaal, een Data-Out-draad voor twee ervan, en stroom en aarde voor elk. Welke lengte je ook denkt nodig te hebben, voeg wat toe. U kunt overtollige draad altijd afknippen, een te korte draad kunt u niet uitrekken. En let op de waarschuwing van Adafruit:

Bij het solderen van draden aan deze ringen moet je extra alert zijn op soldeervlekken en kortsluitingen. De afstand tussen de componenten is erg krap! Het is vaak het gemakkelijkst om de draad van voren in te steken en aan de achterkant te solderen.

Ik wou dat ik dat had gelezen voordat ik aan de voorkant soldeerde. Ik slaagde erin om geen van mijn LED's door te branden, maar ik verschroeide de rand van een op een manier die me deed zweten totdat ik hem aanzette. Als ik de goede handleiding had gelezen, had ik ook de waarschuwing gelezen om geen krokodillenklem op de LED te plaatsen. Laat mijn bijna-scheepswrakken jouw vuurtoren zijn.

Neopixel-ringen zijn in serie geschakeld, wat betekent dat je al hun LED's tegelijkertijd kunt bedienen vanaf een Arduino door een draad van de OUT van de ene ring naar de IN van een andere ring te verbinden. Elke ring heeft ook stroom- en aardingsdraden nodig.

Stap 3: De bedrading

de bedrading
de bedrading

Sluit het aan zoals in hij Fritzing hierboven - pin 6 van de Arduino brengt de gegevens naar de eerste ring, de data-out van die ring gaat naar de data-in van de volgende, de data-out van die gaat naar de Data-in van de laatste ring. U hebt de data-uit-draad van de laatste ring niet nodig.

De capaciteit van 1000 µf gaat tussen de positieve en negatieve rails van het breadboard. Deze dop beschermt de ringen tegen stroompieken en wordt aanbevolen door de best-practice-sectie van Adafruit NeoPixel Uberguide. De weerstand op de gegevens in de eerste neopixel wordt ook aanbevolen door Adafruit -- het is 1K in de Fritzing, maar de aanbevolen weerstand is 300-500 ohm.

In mijn build heb ik de draden van de Neopixels over de achterkant van de plaat naar een breadboard in het midden geleid. Op die manier hoef je maar drie lange draden naar de basiseenheid te leiden: stroom, aarde en data. Ik heb deze draden superlang gemaakt -- er is veel opbergruimte in de basis, en het maakt het gemakkelijk om het bord eruit te trekken voor herprogrammering.

Stap 4: De code

"loading="lazy" zei dat mijn zoon hier een muziek-reactieve versie van wilde hebben. Het duurde tot zijn 18e om eraan toe te komen, maar hier is hij dan!

Extra uitrustingen:

1 enkelpolige, dubbele worpschakelaar1 Automatic Gain Control Mic (ik gebruikte AdaFruit's MAX9184) 1 1uF-100uF condensator (elke waarde)

De microfoon moet echt Automatic Gain Control hebben om dit goed te laten werken. AGC bemonstert constant het omgevingsgeluid en verhoogt en verlaagt de drempel die het als achtergrond beschouwt, zodat uw licht zal reageren op pieken tegen die achtergrond. De microfoon van AdaFruit is briljant: je kunt van een stille kamer waarin het geluid van een enkele stem het geluid activeert naar de volledige feestmodus gaan met een kamer vol tieners en schetterende muziek, en het zal het ritme van de muziek gewoon oppikken. prima. Het alternatief, een verstelbare versterkingsmicrofoon, heeft een kleine potentiometer op het bord die onmogelijk delicaat en onhandig is. Er is niet veel verandering in het omgevingsgeluid nodig om het apparaat onbruikbaar te maken: continu branden of constant donker. AGC werkt als magie.

Ik wilde de optie om het swirl-testpatroon of muziek te gebruiken, dus ik bedraadde de middelste draad van een schakelaar naar VIN en een draad naar pin 4 en de andere naar pin 8 van de Leonardo. Door die pinnen te testen op HOOG of LAAG, kunnen we weten in welke staat de schakelaar zich bevindt en dienovereenkomstig de vertakkingscode.

Stap 7: De microfoon aansluiten

De microfoon aansluiten
De microfoon aansluiten

Voer de microfooningang, via die condensator van 1-100 µF, in analoge pen 0. Als uw condensator gepolariseerd is, gaat de uit-pen naar de positieve kant (groene draad).

Met dank aan CodeGirlJP voor haar Trinket-Color-by-Sound-routine, die ik hieronder heb aangepast:

// Geluid geactiveerde LED's met de Arduino en NeoPixels

#erbij betrekken

#define MIC_PIN A0 // Microfoon is bevestigd aan pin a0 op de Leonardo

#define LED_PIN 6 // NeoPixel LED-streng bevestigd aan pin 6 op de Leonardo #define N_PIXELS 36 // aantal pixels in LED-streng !!!!!! Pas het aantal pixels in uw opstelling aan. Dit is correct voor 3 Neopixel-ringen !!!!!! #define N 100 // Aantal te nemen samples elke keer dat readSamples wordt aangeroepen #define fadeDelay 5 // vertragingstijd voor elke fade-hoeveelheid #define noiseLevel 30 // hellingsniveau van gemiddelde microfoonruis zonder geluid

// Initialiseer de NeoPixel-strip met de hierboven gedefinieerde waarden:

Adafruit_NeoPixel-strip = Adafruit_NeoPixel (N_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);

int-voorbeelden[N]; // opslag voor een set voor het verzamelen van monsters

int periodeFactor = 0; // houd het aantal ms bij voor periodeberekening int t1 = -1; // tijden van helling > 100 gedetecteerd. int T; // periode tussen tijden geschaald naar milliseconden int helling; // de helling van twee verzamelde data sample punten byte periodChanged = 0; const int SwitchPinMusic = 4; // Pin voor schakelaarpositie muziekgevoeligheid const int SwitchPinSwirl = 8; // Pin voor schakelaarpositie Testpatroon (swirl) int MusicbuttonState = 0; // Aan uit logische variabele voor muziekgevoeligheid

// Arduino-configuratiemethode

ongeldige setup() {

strip.begin();

ledsUit(); vertraging (500); displayColor (wiel (100)); strip.show(); vertraging (500); oddWheel (Wiel (100)); strip.show(); vertraging (500); pinMode (SwitchPinMusic, INPUT); pinMode (SwitchPinSwirl, INPUT); //attachInterrupt (4, Switched, FALLING);

}

// Arduino-lusmethode

void loop () { SwirlbuttonState = digitalRead (SwitchPinSwirl); // HOOG als de schakelaar is ingesteld op Muziekgevoeligheid MusicbuttonState = digitalRead (SwitchPinMusic); // HOOG als de schakelaar is ingesteld op Testpatroon terwijl (SwirlbuttonState == LAAG) { readSamples (); // Voer de muziekbemonsteringsroutine uit SwirlbuttonState = digitalRead (SwitchPinSwirl); //Controleer of de schakelaar is gewijzigd} SwirlbuttonState = digitalRead (SwitchPinSwirl); MusicbuttonState = digitalRead (SwitchPinMusic); while (SwirlbuttonState == HOOG) { Dance(); // Voer de swirly-testpatroonroutine uit SwirlbuttonState = digitalRead (SwitchPinSwirl); //Controleer of de schakelaar is gewijzigd

}

}

ongeldige dans() {

while (SwirlbuttonState == HOOG) { colorWipe (strip. Color (255, 0, 0), 50); // Rode SwirlbuttonState = digitalRead (SwitchPinSwirl); colorWipe(strip. Color(0, 255, 0), 50); // Groene SwirlbuttonState = digitalRead (SwitchPinSwirl); colorWipe(strip. Color(0, 0, 255), 50); // Blauwe SwirlbuttonState = digitalRead (SwitchPinSwirl); //colorWipe(strip. Color(0, 0, 0, 255), 50); // Witte RGBW // Stuur een theater pixel chase in… SwirlbuttonState = digitalRead(SwitchPinSwirl); theaterChase(strip. Color(127, 127, 127), 50); // Witte SwirlbuttonState = digitalRead (SwitchPinSwirl); theaterChase(strip. Color(127, 0, 0), 50); // Rode SwirlbuttonState = digitalRead (SwitchPinSwirl); theaterChase(strip. Color(0, 0, 127), 50); // Blauwe SwirlbuttonState = digitalRead (SwitchPinSwirl); regenboog(20); SwirlbuttonState = digitalRead (SwitchPinSwirl); regenboogCyclus (20); SwirlbuttonState = digitalRead (SwitchPinSwirl); theaterChaseRainbow(50); SwirlbuttonState = digitalRead (SwitchPinSwirl); } } // Lees en verwerk voorbeeldgegevens van Mic void readSamples () { for (int i = 0; i0) { slope = samples - samples [i-1]; } else { helling = steekproeven - steekproeven[N-1]; } // Controleer of Helling groter is dan noiseLevel - geluid dat niet op geluidsniveau is gedetecteerd if(abs(slope)> noiseLevel) { if(slope <0) {calcPeriod(i); if (periodChanged == 1) { displayColor (getColor (T)); } } } else { ledsOff(); // theaterChaseRainbow(50); } periodeFactor += 1; vertraging(1); } }

void berekenPeriode(int i)

{ if(t1 == -1) { // t1 is niet ingesteld t1 = i; } else { // t1 was zo ingesteld calc period int period = periodFactor*(i - t1); periodeGewijzigd = T==periode ? 0: 1; T = periode; //Seriële.println(T); // reset t1 naar nieuwe i-waarde t1 = i; periodeFactor = 0; } }

uint32_t getColor(int periode)

{ if(periode == -1) return Wheel (0); else if(periode > 400) return Wheel(5); else return Wheel (kaart (-1 * periode, -400, -1, 50, 255)); }

void fadeOut()

{ for(int i=0; i<5; i++) { strip.setBrightness(110 - i*20); strip.show(); // Update stripvertraging (fadeDelay); periodFactor +=fadeDelay; } }

ongeldig fadeIn()

{ strip.setBrightness(100); strip.show(); // Update strip // fade kleur in voor (int i=0; i<5; i++) {//strip.setBrightness (20*i + 30); //strip.show(); // Update stripvertraging (fadeDelay); periodFactor+=fadeDelay; } }

leegte ledsOff()

{ fadeOut(); for(int i=0; i

void displayColor (uint32_t kleur)

{ for(int i=0; i

ongeldig oddWheel (uint32_t kleur)

{ for (int j=0; j <256; j++) { // cycle alle 256 kleuren in het wiel voor (int q=0; q <3; q++) { for (uint16_t i=24; i <36; i =i+3) { strip.setPixelColor(i+q, Wheel((i+j) % 255)); // zet elke derde pixel aan } strip.show();

vertraging(1);

for (uint16_t i=24; i <36; i=i+3) { strip.setPixelColor(i+q, 0); // zet elke derde pixel uit } } } fadeIn(); }

// Vul de stippen een voor een met een kleur

void colorWipe(uint32_t c, uint8_t wacht) { for(uint16_t i=0; i

ongeldige regenboog (uint8_t wacht) {

uint16_t i, j;

for(j=0; j<256; j++) { for(i=0; i

// Iets anders, hierdoor is de regenboog gelijkmatig verdeeld

void rainbowCycle (uint8_t wacht) { uint16_t i, j;

for(j=0; j<256*5; j++) {// 5 cycli van alle kleuren op het wiel for(i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255)); } strip.show(); vertraging (wacht); } }

// Kruiplichten in theaterstijl.

void theaterChase(uint32_t c, uint8_t wacht) { for (int j=0; j<10; j++) {//doe 10 cycli van jagen voor (int q=0; q <3; q++) { for (uint16_t i= 0; ik <strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, c); // zet elke derde pixel aan } strip.show();

vertraging (wacht);

for (uint16_t i=0; i <strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); // zet elke derde pixel uit } } } }

// Kruiplichten in theaterstijl met regenboogeffect

void theaterChaseRainbow(uint8_t wait) { for (int j=0; j <256; j++) { // cycle alle 256 kleuren in het wiel voor (int q=0; q <3; q++) { for (uint16_t i=0 i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, Wheel((i+j) % 255)); // zet elke derde pixel aan } strip.show();

vertraging (wacht);

for (uint16_t i=0; i <strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); // zet elke derde pixel uit } } } }

// Voer een waarde in van 0 tot 255 om een kleurwaarde te krijgen.

// De kleuren zijn een overgang r - g - b - terug naar r. uint32_t Wheel (byte WheelPos) { WheelPos = 255 - WheelPos; if (WheelPos < 85) { retourstrip. Kleur (255 - WheelPos * 3, 0, WheelPos * 3); } if(WheelPos < 170) { WheelPos -= 85; retourstrip. Kleur (0, WheelPos * 3, 255 - WheelPos * 3); } WielPos -= 170; retourstrook. Kleur (WheelPos * 3, 255 - WheelPos * 3, 0); }

ongeldig Geschakeld(){

strip.show(); leesVoorbeelden(); }

Voordat ik werd afgeslacht in de reacties (denk aan het Be Nice-beleid!!), realiseerde ik me nadat ik dit had geüpload hoe slordig sommige van mijn code is. Het is niet nodig om zowel Pin 4 als Pin 8 constant op HOOG te testen. Aangezien de schakelaar enkelpolige dubbele worp is, kan de waarde van de ene worden afgeleid uit de andere: u hoeft er maar één te testen. Dus je zou elke verwijzing naar het lezen en schrijven van de MusicButtonState kunnen doornemen en verwijderen en het geheel efficiënter kunnen uitvoeren door SwirlButtonState te testen, als je weinig geheugen hebt of uitbreidt met andere routines. Maar bovenstaande code werkt.

En als iemand die audioroutines wil aanpassen om niet alleen het geluidsniveau maar ook de frequentie te voelen, en een soepele code wil schrijven om op en neer te schuiven in het lichtspectrum als reactie op bewegingen langs het audiospectrum, plaats dan een link in de opmerkingen om hoe heb je dat gedaan.

Genieten van!

Aanbevolen: