Décoration de Noël à faire soi-même

Ça y est, on peut dire qu’on y est presque, les fêtes arrivent. Comme vous avez pu le voir dans l’article précédent, je me suis amusé à faire une matrice de LEDs pour mettre en place ma décoration de Noël. Donc, je vais vous partager la mise en place, le logiciel de la matrice ainsi que le rendu final.

Sommaire

Mise en place

Pour mettre en place ma décoration de Noël, je suis parti sur la réalisation d’une matrice de LEDs avec un bandeau de LEDs WS2812 + un autre bandeau de LEDs WS2812 d’extérieur + un bandeau de LED RGB classique d’extérieur en 12VDC.

L’objectif est d’habiller la cabane en bois de ma fille et d’éclairer un bonhomme de neige.

Première difficulté : Ma source d’énergie la plus proche (tableau électrique de mon cabanon) est à 40mètres linéaire de la cabane sur pilotis.

Deuxième difficulté : Je dois gérer 2 tensions différentes : 12VDC et 5VDC avec un peu de puissance.

Pour la décoration, Je suis parti sur l’idée suivante:

Achats

Je suis parti du bloc d’alimentation 12VDC du bandeau de LEDs RGB. Le bloc peut fournir 6A à 12VDC et le 12VDC « voyage » mieux que le 5VDC.

J’ai donc acheté une rallonge électrique de 40 mètres sur lequel va « voyager » le 12VDC. Comme il y a un peu de puissance la section 2,5² sera suffisante pour mon montage.

Ensuite, j’ai fait l’acquisition d’un convertisseur 12VDC-5VDC pour les LEDs WS2812 et pour mon NodeMCU.

1x Rallonge électrique 40m panier-acheter-ecommerce-shopping-icone-8314-4824.99€
1x Convertisseur 12vdc 5vdc panier-acheter-ecommerce-shopping-icone-8314-4813.24€

Pour le reste des achats, il suffit d’aller sur l’article précédent.

Voici le schéma de mon installation : (de la prise 220vdc jusqu’à la cabane sur pilotis)

Tout ce petit beau monde est pilotable en Z-wave par l’intermédiaire de Jeedom. Voici quelques photos de l’installation à l’intérieur de la cabane (un peu jeté):

C’est pas très beau mais je voulais quand même le montrer. (Heureusement que le schéma est là pour comprendre).

Pour la partie « bonhomme de neige », j’avoue que c’est ma compagne qui l’a fait. Elle a suivi un tutoriel sur Pinterest et je trouve que c’est une super idée. D’ailleurs, je trouve que le rendu est top. J’ai juste rajouté un nez en impression 3D et deux ronds en carton noir pour les yeux. Le tout fixer à la colle chaude.

Voici un exemple :

Pour la partie éclairage, je n’ai eu qu’à insérer à l’intérieur un bout de bandeau de LEDs. Les gobelets blancs feront bien leur travail de diffusion de la lumière.

Logiciel de la décoration

Le logiciel est un mélange de plusieurs exemples de librairies. En particulier, les différents scénarios de lumières sont tirés des exemples de la librairie FastLed. J’ai aussi mis en place les librairies LEDmatrix et LEDtext pour l’affichage de texte sur la matrice. Enfin, j’ai mis en place un serveur Web afin de pouvoir changer la couleur et le texte que je fais défiler sur la matrice.

Vu que c’était juste pour une décoration de Noël, je n’ai pas poussé les fonctionnalités et j’ai fait beaucoup de copier/coller mais « ça fait le job ».

Voici en détail le code.

[pastacode lang= »c » manual= »%0A%23include%20%3CESP8266WiFi.h%3E%0A%23include%20%3CWiFiClient.h%3E%0A%23include%20%3CESP8266WebServer.h%3E%0A%23include%20%3CESP8266mDNS.h%3E%0A%23include%20%3CFS.h%3E%0A%23include%20%22FastLED.h%22%0A%23include%20%3CLEDMatrix.h%3E%0A%23include%20%3CLEDText.h%3E%0A%23include%20%3CFontRobotron.h%3E%0A%0A%23define%20DBG_OUTPUT_PORT%20Serial%0A%0Aconst%20char*%20ssid%20%3D%20%22***********%22%3B%0Aconst%20char*%20password%20%3D%20%22********%22%3B%0Aconst%20char*%20host%20%3D%20%22esp8266fs%22%3B%0A%0A%0A%23define%20DATA_PIN%20%20%20%208%20%2F%2F%0A%23define%20LED_TYPE%20%20%20%20WS2812%0A%23define%20COLOR_ORDER%20GRB%0A%23define%20NUM_LEDS%20%20%20%20150%20%2F%2FNOMBRE%20DE%20LEDS%20SUR%20LE%20BANDEAU%0ACRGB%20leds%5B2%5D%5BNUM_LEDS%5D%3B%0A%0A%23define%20BRIGHTNESS%20%20%20%20%20%20%20%20%20%2096%20%2F%2FLUMINOSITE%0A%23define%20FRAMES_PER_SECOND%20%20120%0A%0A%23define%20MATRIX_WIDTH%20%20%2015%0A%23define%20MATRIX_HEIGHT%20%2010%0A%23define%20MATRIX_TYPE%20%20%20%20HORIZONTAL_ZIGZAG_MATRIX%0A%0AcLEDMatrix%3CMATRIX_WIDTH%2C%20MATRIX_HEIGHT%2C%20MATRIX_TYPE%3E%20ledsText%3B%0AcLEDText%20ScrollingMsg%3B%0Achar%20TxtDemo%5B%5D%20%3D%20%7BEFFECT_CHAR_DOWN%20%22%20%20%20JOYEUSES%20FETES!%22%7D%3B%0A%0Aint%20RedText%3D255%3B%0Aint%20GreenText%3D0%3B%0Aint%20BlueText%3D0%3B%0A%0AESP8266WebServer%20server(80)%3B%0A%0Avoid%20handleFileChangeText()%20%7B%0A%20%20if(!server.hasArg(%22text%22))%20%7Bserver.send(500%2C%20%22text%2Fplain%22%2C%20%22BAD%20ARGS%22)%3B%20return%3B%7D%0A%0A%20%20String%20Txt%3Dserver.arg(%22text%22)%3B%0A%20%20String%20R%3Dserver.arg(%22R%22)%3B%0A%20%20String%20G%3Dserver.arg(%22G%22)%3B%0A%20%20String%20B%3Dserver.arg(%22B%22)%3B%0A%20%20TxtDemo%5B100%5D%3D%7B%7D%3B%0A%20%20Txt.toCharArray(TxtDemo%2C100)%3B%0A%0A%20%20if%20((R!%3D%22%22)%20%26%26%20(G!%3D%22%22)%20%26%26(B!%3D%22%22))%0A%20%20%7B%0A%20%20%20%20RedText%3DR.toInt()%3B%0A%20%20%20%20GreenText%3DG.toInt()%3B%0A%20%20%20%20BlueText%3DB.toInt()%3B%0A%20%20%7D%0A%20%20%20server.send(200%2C%20%22text%2Fplain%22%2C%20%22ok%22)%3B%0A%7D%0A%0Avoid%20setup(void)%7B%0A%0A%20%20FastLED.addLeds%3CLED_TYPE%2CDATA_PIN%2CCOLOR_ORDER%3E(leds%5B0%5D%2C%20NUM_LEDS).setCorrection(TypicalLEDStrip)%3B%0A%20%20FastLED.addLeds%3CLED_TYPE%2C5%2CCOLOR_ORDER%3E(leds%5B1%5D%2C%20NUM_LEDS).setCorrection(TypicalLEDStrip)%3B%0A%0A%20%20%2F%2FWIFI%20INIT%0A%20%20DBG_OUTPUT_PORT.printf(%22Connecting%20to%20%25s%5Cn%22%2C%20ssid)%3B%0A%20%20if%20(String(WiFi.SSID())%20!%3D%20String(ssid))%20%7B%0A%20%20%20%20WiFi.begin(ssid%2C%20password)%3B%0A%20%20%7D%0A%20%20%0A%20%20while%20(WiFi.status()%20!%3D%20WL_CONNECTED)%20%7B%0A%20%20%20%20delay(500)%3B%0A%20%20%20%20DBG_OUTPUT_PORT.print(%22.%22)%3B%0A%20%20%7D%0A%20%20DBG_OUTPUT_PORT.println(%22%22)%3B%0A%20%20DBG_OUTPUT_PORT.print(%22Connected!%20IP%20address%3A%20%22)%3B%0A%20%20DBG_OUTPUT_PORT.println(WiFi.localIP())%3B%0A%0A%20%20MDNS.begin(host)%3B%0A%20%20%0A%20%20%2F%2FSERVER%20INIT%0A%20%20%20%2F%2Flist%20directory%0A%20%20server.on(%22%2Ftext%22%2C%20HTTP_GET%2C%20handleFileChangeText)%3B%0A%20%0A%20%20server.onNotFound(%5B%5D()%7B%0A%20%20%20%20if(!handleFileRead(server.uri()))%0A%20%20%20%20%20%20server.send(404%2C%20%22text%2Fplain%22%2C%20%22FileNotFound%22)%3B%0A%20%20%7D)%3B%0A%0A%20%20server.begin()%3B%0A%20%20DBG_OUTPUT_PORT.println(%22HTTP%20server%20started%22)%3B%0A%0A%7D%0A%0A%2F%2F%20List%20of%20patterns%20to%20cycle%20through.%20%20Each%20is%20defined%20as%20a%20separate%20function%20below.%0Atypedef%20void%20(*SimplePatternList%5B%5D)()%3B%0ASimplePatternList%20gPatterns%20%3D%20%7B%20rainbow%2C%20rainbowWithGlitter%2C%20confetti%2C%20sinelon%2C%20juggle%2C%20bpm%2C%20%20text%20%7D%3B%0A%0Auint8_t%20gCurrentPatternNumber%20%3D%200%3B%20%2F%2F%20Index%20number%20of%20which%20pattern%20is%20current%0Auint8_t%20gHue%20%3D%200%3B%20%2F%2F%20rotating%20%22base%20color%22%20used%20by%20many%20of%20the%20%0A%0A%0Avoid%20loop(void)%7B%0A%20%20%2F%2F%20Call%20the%20current%20pattern%20function%20once%2C%20updating%20the%20’leds’%20array%0A%20%20gPatterns%5BgCurrentPatternNumber%5D()%3B%0A%0A%20%20%2F%2F%20send%20the%20’leds’%20array%20out%20to%20the%20actual%20LED%20strip%0A%20%20FastLED.show()%3B%20%20%0A%20%20%2F%2F%20insert%20a%20delay%20to%20keep%20the%20framerate%20modest%0A%20%20FastLED.delay(1000%2FFRAMES_PER_SECOND)%3B%20%0A%0A%20%20%2F%2F%20do%20some%20periodic%20updates%0A%20%20EVERY_N_MILLISECONDS(%2020%20)%20%7B%20gHue%2B%2B%3B%20%7D%20%2F%2F%20slowly%20cycle%20the%20%22base%20color%22%20through%20the%20rainbow%0A%20%20EVERY_N_SECONDS(%2010%20)%20%7B%20nextPattern()%3B%20%7D%20%2F%2F%20change%20patterns%20periodically%0A%20%20server.handleClient()%3B%0A%7D%0A%0A%23define%20ARRAY_SIZE(A)%20(sizeof(A)%20%2F%20sizeof((A)%5B0%5D))%0A%0Avoid%20nextPattern()%0A%7B%0A%20%20%2F%2F%20add%20one%20to%20the%20current%20pattern%20number%2C%20and%20wrap%20around%20at%20the%20end%0A%20%20gCurrentPatternNumber%20%3D%20(gCurrentPatternNumber%20%2B%201)%20%25%20ARRAY_SIZE(%20gPatterns)%3B%0A%7D%0A%0Abool%20gReverseDirection%20%3D%20false%3B%0A%0A%0Avoid%20text()%20%0A%7B%0A%20%20FastLED.addLeds%3CLED_TYPE%2CDATA_PIN%2CCOLOR_ORDER%3E(ledsText%5B0%5D%2C%20NUM_LEDS)%3B%0A%20%20FastLED.setBrightness(BRIGHTNESS)%3B%0A%20%20%0A%20%20ScrollingMsg.SetFont(FredFontData)%3B%0A%20%20ScrollingMsg.Init(%26ledsText%2C%20ledsText.Width()%2C%20ScrollingMsg.FontHeight()%20%2B%201%2C%200%2C%202)%3B%0A%20%20ScrollingMsg.SetText((unsigned%20char%20*)TxtDemo%2C%20sizeof(TxtDemo)%20-%201)%3B%0A%20%20ScrollingMsg.SetTextColrOptions(COLR_RGB%20%7C%20COLR_SINGLE%2C%20RedText%2C%20GreenText%2C%20BlueText)%3B%0A%20%20ScrollingMsg.SetTextDirection(CHAR_DOWN)%3B%0A%20%0A%20%20for(int%20i%20%3D%200%3B%20i%20%3C%20150%3B%20i%2B%2B)%20%7B%20%20%0A%20%20%20%20%20%20leds%5B1%5D%5Bi%5D%20%3D%20CRGB%3A%3ABlack%3B%20%0A%20%20%7D%0A%0A%20%20for(int%20i%3D0%3Bi%3C500%3Bi%2B%2B)%0A%20%20%7B%0A%20%20%20%20if%20(ScrollingMsg.UpdateText()%20%3D%3D%20-1)%0A%20%20%20%20%20%20ScrollingMsg.SetText((unsigned%20char%20*)TxtDemo%2C%20sizeof(TxtDemo)%20-%201)%3B%0A%20%20%20%20else%0A%20%20%20%20%20%20FastLED.show()%3B%0A%20%20%20%20delay(100)%3B%0A%20%20%20%20server.handleClient()%3B%0A%20%20%20%20leds%5B1%5D%5B%20random16(NUM_LEDS)%20%5D%20%2B%3D%20CRGB%3A%3AWhite%3B%0A%20%20%7D%0A%20%20FastLED.addLeds%3CLED_TYPE%2CDATA_PIN%2CCOLOR_ORDER%3E(leds%5B0%5D%2C%20NUM_LEDS).setCorrection(TypicalLEDStrip)%3B%0A%20%20FastLED.addLeds%3CLED_TYPE%2C5%2CCOLOR_ORDER%3E(leds%5B1%5D%2C%20NUM_LEDS).setCorrection(TypicalLEDStrip)%3B%0A%7D%0A%0Avoid%20rainbow()%20%0A%7B%0A%20%20%2F%2F%20FastLED’s%20built-in%20rainbow%20generator%0A%20%20fill_rainbow(%20leds%5B0%5D%2C%20NUM_LEDS%2C%20gHue%2C%207)%3B%0A%20%20fill_rainbow(%20leds%5B1%5D%2C%20NUM_LEDS%2C%20gHue%2C%207)%3B%0A%7D%0A%0Avoid%20rainbowWithGlitter()%20%0A%7B%0A%20%20%2F%2F%20built-in%20FastLED%20rainbow%2C%20plus%20some%20random%20sparkly%20glitter%0A%20%20rainbow()%3B%0A%20%20addGlitter(80)%3B%0A%7D%0A%0Avoid%20addGlitter(%20fract8%20chanceOfGlitter)%20%0A%7B%0A%20%20if(%20random8()%20%3C%20chanceOfGlitter)%20%7B%0A%20%20%20%20leds%5B0%5D%5B%20random16(NUM_LEDS)%20%5D%20%2B%3D%20CRGB%3A%3AWhite%3B%0A%20%20%20%20leds%5B1%5D%5B%20random16(NUM_LEDS)%20%5D%20%2B%3D%20CRGB%3A%3AWhite%3B%0A%20%20%7D%0A%7D%0A%0Avoid%20confetti()%20%0A%7B%0A%20%20%2F%2F%20random%20colored%20speckles%20that%20blink%20in%20and%20fade%20smoothly%0A%20%20fadeToBlackBy(%20leds%5B0%5D%2C%20NUM_LEDS%2C%2010)%3B%0A%20%20fadeToBlackBy(%20leds%5B1%5D%2C%20NUM_LEDS%2C%2010)%3B%0A%20%20int%20pos%20%3D%20random16(NUM_LEDS)%3B%0A%20%20leds%5B0%5D%5Bpos%5D%20%2B%3D%20CHSV(%20gHue%20%2B%20random8(64)%2C%20200%2C%20255)%3B%0A%20%20leds%5B1%5D%5Bpos%5D%20%2B%3D%20CHSV(%20gHue%20%2B%20random8(64)%2C%20200%2C%20255)%3B%0A%7D%0A%0Avoid%20sinelon()%0A%7B%0A%20%20%2F%2F%20a%20colored%20dot%20sweeping%20back%20and%20forth%2C%20with%20fading%20trails%0A%20%20fadeToBlackBy(%20leds%5B0%5D%2C%20NUM_LEDS%2C%2020)%3B%0A%20%20%20fadeToBlackBy(%20leds%5B1%5D%2C%20NUM_LEDS%2C%2020)%3B%0A%20%20int%20pos%20%3D%20beatsin16(13%2C0%2CNUM_LEDS)%3B%0A%20%20leds%5B0%5D%5Bpos%5D%20%2B%3D%20CHSV(%20gHue%2C%20255%2C%20192)%3B%0A%20%20leds%5B1%5D%5Bpos%5D%20%2B%3D%20CHSV(%20gHue%2C%20255%2C%20192)%3B%0A%7D%0A%0Avoid%20bpm()%0A%7B%0A%20%20%2F%2F%20colored%20stripes%20pulsing%20at%20a%20defined%20Beats-Per-Minute%20(BPM)%0A%20%20uint8_t%20BeatsPerMinute%20%3D%2062%3B%0A%20%20CRGBPalette16%20palette%20%3D%20PartyColors_p%3B%0A%20%20uint8_t%20beat%20%3D%20beatsin8(%20BeatsPerMinute%2C%2064%2C%20255)%3B%0A%20%20for(%20int%20i%20%3D%200%3B%20i%20%3C%20NUM_LEDS%3B%20i%2B%2B)%20%7B%20%2F%2F9948%0A%20%20%20%20leds%5B0%5D%5Bi%5D%20%3D%20ColorFromPalette(palette%2C%20gHue%2B(i*2)%2C%20beat-gHue%2B(i*10))%3B%0A%20%20%20%20leds%5B1%5D%5Bi%5D%20%3D%20ColorFromPalette(palette%2C%20gHue%2B(i*2)%2C%20beat-gHue%2B(i*10))%3B%0A%20%20%7D%0A%7D%0A%0Avoid%20juggle()%20%7B%0A%20%20%2F%2F%20eight%20colored%20dots%2C%20weaving%20in%20and%20out%20of%20sync%20with%20each%20other%0A%20%20fadeToBlackBy(%20leds%5B0%5D%2C%20NUM_LEDS%2C%2020)%3B%0A%20%20fadeToBlackBy(%20leds%5B1%5D%2C%20NUM_LEDS%2C%2020)%3B%0A%20%20byte%20dothue%20%3D%200%3B%0A%20%20for(%20int%20i%20%3D%200%3B%20i%20%3C%208%3B%20i%2B%2B)%20%7B%0A%20%20%20%20leds%5B0%5D%5Bbeatsin16(i%2B7%2C0%2CNUM_LEDS)%5D%20%7C%3D%20CHSV(dothue%2C%20200%2C%20255)%3B%0A%20%20%20%20leds%5B1%5D%5Bbeatsin16(i%2B7%2C0%2CNUM_LEDS)%5D%20%7C%3D%20CHSV(dothue%2C%20200%2C%20255)%3B%0A%20%20%20%20dothue%20%2B%3D%2032%3B%0A%20%20%7D%0A%7D%0A » message= »Décoration de Noël » highlight= » » provider= »manual »/]

Ce code permet de gérer différents scénarios de décoration sur la matrice mais aussi sur un autre bandeau de LEDs.

La matrice se retrouve sur le port D8 du NodeMCU et le bandeau sur le port D5

 FastLED.addLeds<LED_TYPE,8,COLOR_ORDER>(leds[0], NUM_LEDS).setCorrection(TypicalLEDStrip);
 FastLED.addLeds<LED_TYPE,5,COLOR_ORDER>(leds[1], NUM_LEDS).setCorrection(TypicalLEDStrip);

Ensuite, j’ai mis en place une serveur Web qui va me permettre de changer le texte et la couleur du texte de la matrice. Il suffira de se connecter sur le NodeMCU de la manière suivante :

http://<IP_NODEMCU>/text?text=    JOYEUX NOEL!&R=255&G=0&B=0

(Si vous avez des questions sur le code, n’hésitez pas à poster un commentaire). Le code est trop long pour tout expliquer.

Conclusion

Voici le résultat terminé:

Cabane avant décoration de Noël

Cabane sur pilotis avec décoration de Noël

Une petite vidéo pour agrémenter le tout :

Vous pouvez retrouver l’ensemble du projet sur mon github

Click to rate this post!
[Total: 2 Average: 5]

7 comments

  1. Bonjour,
    Quand vous dites:
    « Tout ce petit beau monde est pilotable en Z-wave par l’intermédiaire de Jeedom »!?
    Ne faite vous pas un abus de language!?
    Vous utilisez un nodemcu, donc du wifi, pour commander à distance votre installation depuis Jeedom je n’ai pas vu d’équipement Zwave.
    Désolé pour ce besoin de précision. Sinon l’idée est géniale, je vous dis merci car grâce à vous l’année prochaine j’aurai de plus belle déco de Noël.

    1. Bonjour,
      En effet, ça mérite une précision. La partie zwave piloté par Jeedom est la prise 220v pilotable sur le schéma de fonctionnement. (Dans mon cas j’ai utilisé une prise greenwave). Je n’ai approfondi cette partie car ce n’était pas l’objet principal de l’article mais tu as raison, la précision était importante. Merci à toi.

      1. Ok merci pour cette précision. Parce que je ne voyais pas d’équipement Zwave.
        Sinon dans l’absolu, cela commence à devenir courant sur le net, on pourrait utiliser un relais sur le nodemcu, pour commander en wifi l’alimentation de l’éclairage depuis jeedom. Seul soucis pas de retour d’info conso comme tu pourrais l’avoir sur la prise greenwave. Mais depuis la même tuile de Jeedom tu pourrais commander l’allumage, le mode et les couleurs de cette décos.
        Le but n’étant pas de faire comme dans la pub d’orange avec les décos de Noël lol…

  2. J’ai pris un peu de temps pour me lancer, mais à force de relire ton article j’ai fini par acheté un afficheur led WS2812 de 8×8 avec Nodemcu pour commencer à faire joujou.

    J’ai lu ton code, je n’ai pas tout compris, donc je vais tester de mon côté et voir ce que j’arrive à faire.
    Le but étant d’obtenir un ptit afficheur à led RGB (à terme de 8×8 ou 16×8) que l’on pourrait commander par une page web et me permettre d’afficher des notifications visuelles.

    A bientôt.

  3. Bonjour,

    je decouvre l’univers de l’ESP8266 et je trouve votre projet génial !! merci pour le partage d’experience.

    A la lecture me vient une question – de neophyte :
    – cote matériel vous utilisez un convertisseur 12 V -> 5V 5A et je me demande si cela est suffisant pour alimenter la matrice led, composé de 5m de ruban led. Si je suis votre lien sur amazon, la puissance nécessaire pour le ruban est donnée à 9W/m, sur 5 m cela necessite 45 W, soit une alimentation de 5v 9A si je ne fais pas d’erreur.

    Auriez vous des précisions sur la facon d’alimenter le montage ?

    merci encore pour vos partages,
    au plaisir de vous lire sur d’autres projets.

Leave a Reply

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.