Lunettes disco avec le WS2812b RGB LED Ring
Bonjour et bienvenue à une autre série de blogs sur notre WS2812b RGB LED Ring. Une fois de plus, il s’agit du sujet actuel de l’upcycling. Après tout, personne ne devrait être en mesure de dire que le fabricant :) pense pas aussi à l’environnement.
Cette fois, nous "upcycle" une vieille lunettes de soleil à un élégant "lunettes disco" pour la prochaine visite disco. Bien que je ne sois plus l’un des amateurs de disco, je pense qu’il devrait aussi y avoir un projet pour nos jeunes fabricants parmi les lecteurs. J’espère que vous aimez l’idée de lunettes Disco LED pour la prochaine visite disco! Avec cela, vous serez certainement vraiment rattraper dans la masse (danse). Les anneaux LED WS2812b agissent comme des « lunettes ». Le cadre autour des deux anneaux d’oeil peut être assemblé à partir d’une vieille lunette de soleil. Comme mc nous utilisons l’Arduino Nano à nouveau pour des raisons d’espace, comme une alimentation d’une banque d’énergie USB à partir du téléphone mobile. Pour le câblage, je recommande de décharger l’électronique et l’alimentation des lunettes, il suffit donc d’avoir un mince, 3 câble adrige disparaissent de la poignée de l’oreille gauche ou droite sur le dessus dans une boîte électronique dans la poche de chemise ou poche de pantalon. Dans cette boîte électronique, vous installez le pushbutton et d’autres capteurs (dans les pièces à venir) pour contrôler les lunettes. Pour notre blog d’aujourd’hui, nous avons besoin de la configuration matérielle suivante:
En tant que pièces, vous n’avez pas besoin de grand-chose :
2 x RGB LED Ring WS2812b avec 12 LED RGB 5V pour Arduino 50 mm de diamètre externe
1x Pushbutton
1x Banque d’alimentation Usb et câble USB adapté à Arduino Nano
Lorsque nous avons terminé le circuit, nous devons maintenant inclure la bibliothèque Adafruit Neopixel afin que nous puissions facilement contrôler les LED de l’anneau.
La bibliothèque requise peut être ajoutée à notre IDE de 2 façons :
1.) Téléchargez la bibliothèque sur l’URL https://github.com/adafruit/Adafruit_NeoPixel. Ensuite, dans l’IDE dans l’élément de menu Croquis - -gt; Inclure la bibliothèque --gt;Ajouter Zip Library manuellement.
2.) Entrez "Adafruit Neopixel" dans le gestionnaire de la bibliothèque comme terme de recherche, cliquez sur la bibliothèque et sélectionnez ensuite "Install". S’il vous plaît sélectionner au moins la version 1.2.4.
Si tout a fonctionné jusqu’à présent, s’il vous plaît télécharger le code suivant à la nano:
#include <Adafruit_NeoPixel.H (en)> #define BUTTON_CHANGEANIMATION 12 Épingle IO numérique connectée au bouton. Ce sera conduit avec une résistance pull-up de sorte que le commutateur devrait Tirez la broche au sol momentanément. Sur un haut - bas transition de la logique de bouton appuyez sur s’exécutera. #define PIXEL_PIN 6 Épingle IO numérique connectée aux NeoPixels. #define PIXEL_COUNT 24 Tous les pixels sur Umbrella #define MaxAninmationsAvail 1 #define STATUS_PIN 13 Bouton de contrôle d’animation Adafruit_NeoPixel Bande = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_RGB + NEO_KHZ800); Const Int hueRedLow = 0; Const Int hueRedHigh = 255; Const Int hueBlue = 170; La taille de l’angle d’un secteur (1/6 d’une roue de couleur), et d’un cycle de la roue de couleur. Const Int angleMin = 0; Const Int angleSector = 60; Const Int angleMax = 360; Const Int brightMin = 0; Const Int brightMax (en) = 255; Octet Teinte, "Je ne suis pas; La saturation est fixée à 255 (plein) pour enlever le blead-through de différents "Je ne suis pas Il pourrait être lié à un autre potentiomètre si une démonstration de teinte Est désiré. Octet Saturation = 255; Variables de minuterie Int TimerSeconds TimerSeconds = 0; Counter Int TimerAlarmSet (en anglais) = 15; Minuterie de 15 secondes Bool TimerStartFlagFlagFlag = Faux; Bool Timerstop = Vrai; Opérations manuelles Bool ButtonAPress (en) = Faux; Octet LedMode (en) = 2; AnimationControl Int DevraitAnimation = 0; Int IsAnimation = 0; Int OLDLightBorder (en) = 0; Bool GetONOFFStatus GetONOFFStatus = Faux; Bool OLDONOFFStatus = Faux; Bool PlayIntro = Faux; Intro Bool PlayOutro PlayOutro = Faux; Outro Bool ChangementAnimation = Faux; Bool RunOnce (RunOnce) = Vrai; variables universelles Octet Un,C,D,E,F; Unsigned Int R, G, B; Interrompre les routines ISR (ISR)(TIMER1_COMPA_vect) { Bool LEDChange (en),PressedZ (pressedZ); Commutateur Abfrage PressedZ (pressedZ)= digitalRead (en)(BUTTON_CHANGEANIMATION); Si ((PressedZ (pressedZ) == Faible) Et (ButtonAPress (en) == Faux)) { ButtonAPress (en) = Vrai; } TCNT1 (en) = 0; Inscription initialisant } Interrompre la fin commencer le programme Vide Configuration() { Bande.Commencer(); Bande.Montrer(); Initialiser tous les pixels à 'off' pinMode(BUTTON_CHANGEANIMATION, INPUT_PULLUP); pinMode(STATUS_PIN,Sortie); digitalWrite (en)(STATUS_PIN, Haute); randomSeed(analogRead (en)(0)); noInterrupts(); Toutes les interruptions désactiver TCCR1A (EN) = 0x00; TCCR1B (EN) = 0x02; TCNT1 (en) = 0; Initalisation de registre OCR1A = 33353; Charge de sortie Comparer registre TIMSK1 (en) |= (1 << OCIE1A); Activer la minuterie Comparer l’interruption Interrompt(); Activer toutes les interruptions Série.Commencer(9600); Série.Rincer(); } Fonctions d’aide Vide HSBToRGB( Unsigned Int inHue, Unsigned Int inSaturation, Unsigned Int inBrightness, Unsigned Int *Ou, Unsigned Int *Og, Unsigned Int *Ob ) { Si (inSaturation == 0) { achromatique (gris) *Ou = *Og = *Ob = inBrightness; } Autre { Unsigned Int scaledHue = (inHue * 6); Unsigned Int Secteur = scaledHue >> 8; secteur 0 à 5 autour de la roue de couleur Unsigned Int offsetInSector = scaledHue - (Secteur << 8); position au sein du secteur Unsigned Int P = (inBrightness * ( 255 - inSaturation )) >> 8; Unsigned Int Q = (inBrightness * ( 255 - ((inSaturation * offsetInSector) >> 8) )) >> 8; Unsigned Int T = (inBrightness * ( 255 - ((inSaturation * ( 255 - offsetInSector )) >> 8) )) >> 8; Interrupteur( Secteur ) { Cas 0: *Ou = inBrightness; *Og = T; *Ob = P; Pause; Cas 1: *Ou = Q; *Og = inBrightness; *Ob = P; Pause; Cas 2: *Ou = P; *Og = inBrightness; *Ob = T; Pause; Cas 3: *Ou = P; *Og = Q; *Ob = inBrightness; Pause; Cas 4: *Ou = T; *Og = P; *Ob = inBrightness; Pause; Par défaut: cas 5: *Ou = inBrightness; *Og = P; *Ob = Q; Pause; } } } Vide CheckConfigButtons () InterruptRoutine { Bool PressedZ (pressedZ); Si (ButtonAPress (en) == Vrai) { DevraitAnimation = !DevraitAnimation; Retard(250); ButtonAPress (en) = Faux; } } Vide AnimationControl () { Int GetSelAnimation (en) = 0; Si (GetONOFFStatus GetONOFFStatus != OLDONOFFStatus) { OLDONOFFStatus = GetONOFFStatus GetONOFFStatus; Si (GetONOFFStatus GetONOFFStatus) { randomSeed(analogRead (en)(3)); GetSelAnimation (en) = 1; DevraitAnimation = GetSelAnimation (en); Série.Imprimer ("Système ON. Sélectionné: "); Série.println (DevraitAnimation); } Autre { Série.Imprimer ("Système OFF. Secondes:"); TimerStartFlagFlagFlag = Faux; Série.println (TimerSeconds TimerSeconds); DevraitAnimation = 0; } } } ----------------------------------------------------------------------- de la boucle principale Vide Boucle() { AnimationControl(); RunAnimations(); CheckConfigButtons(); } Boucle principale ----------------------------------------------------------------------- Ende Intros Vide Intro_RaiseRainbow(Bool hausse) { Luminosité = 255; Int Rainbowcolor (Rainbowcolor) = 0; Si (hausse) { Pour (Int Ⅰ=0; Ⅰ < Bande.numPixels (numPixels)(); Ⅰ++) { wdt_reset(); Teinte = Carte(Ⅰ + Rainbowcolor (Rainbowcolor), angleMin, 60, hueRedLow, hueRedHigh); Définir La couleur minute HSBToRGB(Teinte, Saturation, Luminosité, &R, &G, &B); Définir la couleur d’heure Bande.setPixelColor(Ⅰ, R, G, B); Valeurs Calulate RGB pour Pixel Heure Bande.Montrer(); Retard(40); } } Autre { Pour (Int Ⅰ=0; Ⅰ < Bande.numPixels (numPixels)(); Ⅰ++) { wdt_reset(); Bande.setPixelColor(Ⅰ, 0, 0, 0); Bande.Montrer(); Retard(40); } } } Animations Vide Ani_AllOff () { Pour ( Int Ⅰ = 0; Ⅰ < Bande.numPixels (numPixels)(); Ⅰ++) { Bande.setPixelColor(Ⅰ,0, 0, 0); tous hors tension } Bande.Montrer(); } Vide Ani_Rainbow(Octet retard) { "Je ne suis pas = 100; Int Rainbowcolor (Rainbowcolor) = 0; Jeu { Pour (Int Ⅰ.=0; Ⅰ. < Bande.numPixels (numPixels)(); Ⅰ.++) { Teinte = Carte(Ⅰ. + Rainbowcolor (Rainbowcolor), angleMin, 60, hueRedLow, hueRedHigh); HSBToRGB(Teinte, Saturation, "Je ne suis pas, &R, &G, &B); Bande.setPixelColor(Ⅰ., R, G, B); } Bande.Montrer(); Afficher les résultats :) Retard(retard); Rainbowcolor (Rainbowcolor)++ ; } Tandis que (Rainbowcolor (Rainbowcolor) < 61); } Vide RunAnimations() { Si (!(DevraitAnimation == IsAnimation)) { PlayOutro PlayOutro = Vrai; ChangementAnimation = Vrai; } Interrupteur (IsAnimation) { Cas 0: tous LedsOFF Si (PlayIntro) { PlayIntro = Faux; Runonce (Runonce) = Vrai; } Si ((!(PlayIntro)) && (!(PlayOutro PlayOutro))) { Si (Runonce (Runonce)) { Ani_AllOff (); } Runonce (Runonce) = Faux; } Si (PlayOutro PlayOutro) { PlayOutro PlayOutro = Faux; PlayIntro = Vrai; Runonce (Runonce) = Vrai; IsAnimation = DevraitAnimation; } Pause; Cas 1: Si (PlayIntro) { Intro_RaiseRainbow(Vrai); PlayIntro = Faux; } Si ((!(PlayIntro)) && (!(PlayOutro PlayOutro))) { Ani_Rainbow(20); } Si (PlayOutro PlayOutro) { Intro_RaiseRainbow(Faux); PlayOutro PlayOutro = Faux; PlayIntro = Vrai; IsAnimation = DevraitAnimation; } Pause; } }
Maintenant, appuyez sur le bouton et profiter du spectacle :). Une autre pression d’un bouton éteint les lunettes.
Je vous souhaite beaucoup de plaisir à reconstruire et, comme toujours, jusqu’à la prochaine fois.
4 commentaires
Tobias
In der Tat hat sich ein kleiner Fehler in das Fritzing Bild eingeschlichen. Natürlich müssen die Ringmassen auch mit GND verbunden werden. Für die Verbindung der Ringe ist folgendes zu beachten :
D6 > DI (Ring1) DO (Ring1) → DI (Ring2)
Sascha
Moin
Von der Idee her, finde ich es gut, aber mir stellt sich die Frage ob es funktioniert wenn die Ringe keinen Null bekommen.
Geht dir nichts an
Die Fritzing funktioniert so nicht, Masse (gnd) ist zwar zwischen den einzelnen Ringen verbunden, aber nicht zum Breadboard … dafür aber 2 mal die 5V Verbindung.
P.S.: Wenn ihr nächstes mal das Bild mit halb so vielen Pixeln veröffentlicht, dann sieht man auch solche Fehler nicht mehr. (Oder in anderen Worten: Bitte einen link zu einem Fritzing Bild mit höherer Auflösung damit die Leute auch erkennen können was wohin geht, denn hier sind die Beschriftungen nicht mehr zu erkennnen)
Bernd
Der Schaltplan sieht ja ganz nett aus, aber die zwei RGB LED Ringe brauchen nicht nur die GND Verbindung untereinander sondern auch noch die GND Verbindung zum Breadboard, oder nur zwei schwarze Verbindungen von den Ringen zum Breadboard auf GND. Etwa so wie bei zwei den roten +5V Verbindungen.