Centralina Wemos Neopixel Music

Le settimane trascorse hai letto gli articoli sulla realizzazione Wemos Neopixel Music: la centralina neopixel e suoni per l’albero di natale.

wemos music light top

Il progetto è articolato per cui era impossibile spiegarlo in un solo articolo.

Oggi leggi come realizziare la centralina Wemos Neopixel Music coni la WeMos D1, i neopixel WS2812B per la parte luminosa ed il DFPlayer mini mp3 per riprodurre brani musicali natalizi.

Materiale per realizzare la centralina Wemos Neopixel Music

L’elenco dei componenti elettronici che ti servono per realizzare la tua centralina è:

  • n.1 WeMos D1 ESP8266
  • n.1 Neopixel Strip WS2812B ( io ne ho usata una da 4m 60 led per metro )
  • n.1 DFPlayer mini mp3 della DFRobot
  • n.1 basetta breadboard o millefori per il circuito
  • n.1 resistenza da 1Kohm
  • n.1 Micro SD Card
  • n.1 alimentatore da 5v 3A o superione
  • n.1 speaker amplificato
  • connettori audio adatti allo speaker
  • alcuni cavi per breadboard

Ecco come puoi collegare la Wemos Neopixel Music sulla breadboard:

wemos neopixel music light schema

Nota che i collegamenti tra il DFPlayer mini mp3 sono simili a quelli che hai eseguito nel tutorial con arduino i pin che usi sono D5 e D6 per Tx ed Rx.

La strip neopixel WS2812B è collegata ai pin +5v, Gnd per l’alimentazione ed al pin D1 come linea In.

I collegamenti Wemos Neopixel Music li puoi eseguire come:

wemos neopixel music light connection

lo speaker è connesso ai pin 6 ed 8 del circuito attraverso un connettore.

Sketch Wemos Neopixel Music

Lo sketch che puoi utilizzare è abbastanza complesso in quanto unisce sia le istruzioni per il controllo del DFPlayer mini mp3 sia l’uso della FastLED per i neopixel WS2812B.

Puoi far riferimento agli articoli singoli che ho scritto e commentato sulle due parti:

in modo da partire da una base di conoscenze che ti aiuta a comprendere meglio questo sketch:

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

/************* Fast LEd *****************************************************/

#define FASTLED_INTERRUPT_RETRY_COUNT 0 
#define FASTLED_ALLOW_INTERRUPTS 0
 
#include <FastLED.h>
 
#define LED_PIN     5
#define NUM_LEDS    240
#define BRIGHTNESS  128
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
 
CRGB leds[NUM_LEDS];
 
#define UPDATES_PER_SECOND 100

/**************************************************************************/

#define changeMusic 60000
#define changeLight 15000

/**************************************************************************/

SoftwareSerial mySoftwareSerial(D6, D5); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

static unsigned long timerMusic;
static unsigned long timerLight;

/**************************************************************************/

CRGBPalette16 currentPalette;
TBlendType    currentBlending;
 
extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;
static uint8_t lastPalette = 0;
 
/**************************************************************************/

void setup() {
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  
  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));
  
  if (!myDFPlayer.begin(mySoftwareSerial)) {
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true){
      delay(0); // Code to compatible with ESP8266 watch dog.
    }
  }
  Serial.println(F("DFPlayer Mini online."));
  
  myDFPlayer.volume(15);  //Set volume value. From 0 to 30
  myDFPlayer.play(1);  //Play the first mp3
  
  /************* Fast LEd *****************************************************/
  
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness(  BRIGHTNESS );
   
  currentPalette =  RainbowStripeColors_p;
  currentBlending = LINEARBLEND;

  /**************************************************************************/

  timerMusic = millis();
  timerLight = millis();
}

void loop() {
  if (millis() - timerMusic > changeMusic) {
    timerMusic = millis();
    myDFPlayer.next();
  }
  
  if (myDFPlayer.available()) {
    printDetail(myDFPlayer.readType(), myDFPlayer.read());
  }

  /************* Fast LEd *****************************************************/
  
  if (millis() - timerLight > changeLight) {
    ChangePalette();
    timerLight = millis();
  }
  
  static uint8_t startIndex = 0;
  startIndex = startIndex + 1; /* motion speed */
  
  FillLEDsFromPaletteColors( startIndex);
  
  FastLED.show();
  FastLED.delay(1000 / UPDATES_PER_SECOND);

  /**************************************************************************/

}

void printDetail(uint8_t type, int value) {
  switch (type) {
    case TimeOut:
      Serial.println(F("Time Out!"));
      break;
    case WrongStack:
      Serial.println(F("Stack Wrong!"));
      break;
    case DFPlayerCardInserted:
      Serial.println(F("Card Inserted!"));
      break;
    case DFPlayerCardRemoved:
      Serial.println(F("Card Removed!"));
      break;
    case DFPlayerCardOnline:
      Serial.println(F("Card Online!"));
      break;
    case DFPlayerPlayFinished:
      Serial.print(F("Number:"));
      Serial.print(value);
      Serial.println(F(" Play Finished!"));
      break;
    case DFPlayerError:
      Serial.print(F("DFPlayerError:"));
      switch (value) {
        case Busy:
          Serial.println(F("Card not found"));
          break;
        case Sleeping:
          Serial.println(F("Sleeping"));
          break;
        case SerialWrongStack:
          Serial.println(F("Get Wrong Stack"));
          break;
        case CheckSumNotMatch:
          Serial.println(F("Check Sum Not Match"));
          break;
        case FileIndexOut:
          Serial.println(F("File Index Out of Bound"));
          break;
        case FileMismatch:
          Serial.println(F("Cannot Find File"));
          break;
        case Advertise:
          Serial.println(F("In Advertise"));
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }

}

void FillLEDsFromPaletteColors( uint8_t colorIndex) {
    uint8_t brightness = 255;
     
    for( int i = 0; i < NUM_LEDS; i++) {
       leds[i]=ColorFromPalette(currentPalette,colorIndex,brightness,currentBlending);
       colorIndex += 3;
    }
}
 
void ChangePalette() {
    Serial.print("Curr Palette: "); Serial.println(lastPalette);
    switch(lastPalette) {
      case 0:
        currentPalette = RainbowStripeColors_p;
        currentBlending = LINEARBLEND;
        break;
      case 1:
        SetupBlackAndRedStripedPalette;
        currentBlending = LINEARBLEND;
        break;
      case 2:
        currentPalette = RainbowStripeColors_p;
        currentBlending = LINEARBLEND;
        break;
      case 3:
        SetupPurpleAndGreenPalette();
        currentBlending = LINEARBLEND;
        break;
      case 4:
        SetupPurpleAndGreenPalette();
        currentBlending = LINEARBLEND;
        break;
      case 5:
        SetupTotallyRandomPalette();
        currentBlending = LINEARBLEND;
        break;
      case 6:
        SetupBlackAndWhiteStripedPalette();
        currentBlending = NOBLEND;
        break;
      case 7:
        SetupBlackAndWhiteStripedPalette();
        currentBlending = LINEARBLEND;
        break;                
      case 8:
        currentPalette = CloudColors_p;
        currentBlending = LINEARBLEND;
        break;                
      case 9:
        currentPalette = PartyColors_p;
        currentBlending = LINEARBLEND;
        break;                
      case 10:
        currentPalette = myRedWhiteBluePalette_p;
        currentBlending = NOBLEND;
        break;                
      case 11:
        currentPalette = myRedWhiteBluePalette_p;
        currentBlending = LINEARBLEND;
        break;                
    }
    lastPalette++;
    if ( lastPalette > 11 ) lastPalette = 0;
}
 
// This function fills the palette with totally random colors.
void SetupTotallyRandomPalette() {
    for( int i = 0; i < 16; i++) {
        currentPalette[i] = CHSV( random8(), 255, random8());
    }
}
 
void SetupBlackAndWhiteStripedPalette() {
    // 'black out' all 16 palette entries...
    fill_solid( currentPalette, 16, CRGB::Black);
    // and set every fourth one to white.
    currentPalette[0] = CRGB::White;
    currentPalette[4] = CRGB::White;
    currentPalette[8] = CRGB::White;
    currentPalette[12] = CRGB::White;
}

void SetupBlackAndRedStripedPalette() {
    // 'black out' all 16 palette entries...
    fill_solid( currentPalette, 16, CRGB::Black);
    // and set every fourth one to white.
    currentPalette[0] = CRGB::Red;
    currentPalette[4] = CRGB::Red;
    currentPalette[8] = CRGB::Red;
    currentPalette[12] = CRGB::Red;
}

void SetupPurpleAndGreenPalette() {
    CRGB purple = CHSV( HUE_PURPLE, 255, 255);
    CRGB green  = CHSV( HUE_GREEN, 255, 255);
    CRGB black  = CRGB::Black;
     
    currentPalette = CRGBPalette16(
                                   green,  green,  black,  black,
                                   purple, purple, black,  black,
                                   green,  green,  black,  black,
                                   purple, purple, black,  black );
}
 
const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM = {
    CRGB::Red,
    CRGB::Gray, // 'white' is too bright compared to red and blue
    CRGB::Blue,
    CRGB::Black,
     
    CRGB::Red,
    CRGB::Gray,
    CRGB::Blue,
    CRGB::Black,
     
    CRGB::Red,
    CRGB::Red,
    CRGB::Gray,
    CRGB::Gray,
    CRGB::Blue,
    CRGB::Blue,
    CRGB::Black,
    CRGB::Black
};

linee 01-03: includi le librerie necessarie per il controllo del DFPlayer;

linee 07-20: imposta tutte le definizioni necessarie al controllo dei WS2812B, ricordati di impostare il numero corretto di led alla linea 13 in funzione di quanti ne possiede la tua strip neopixel;

linee 024-025: definisci due variabili di timer una per il cambio della musica ed una per quello del gioco luminoso, potrai definire cambi sincroni o asincroni in funzione della sequenza luminosa o sonora;

linee 029-031: imposta le istanze di comunicazione con il DFPlayer;

linee 033-034: come alle linee 24 e 25 definisci due variabili con cui gestire il tempo trascorso dall’ultimo cambio del brano musicale o dell’effetto luminoso;

linee 038-043: imposta le palette correnti e il tipo di blending per la parte neopixel. aggiungi la variabile lastPalette a 0 che userai come indice della palette in eseguzione;

linee 048-066: sono le medesime linee già analizzate nell’articolo dedicato al DFPlayer mini mp3;

linee 070-075: inizializza la libreria FastLED ed imposta la currentPalette e Blending mode;

linee 079-080: imposta i timer come il conteggio dei millis() correnti, ti serve nel loop() per controllare quanto tempo è trascorso dall’avvio del primo brano e del primo gioco di luci;

linea 084: se il tempo trascorso dall’ultima impostazione della variabile timerMusic è maggiore del tempo impostato nella variabile changeMusic è il momento di cambiare brano;

linea 085: imposta il nuovo timer come il millesimo corrente;

linea 086: usa il metodo next della libreria DFPlayer  per passare al brano successivo;

linee 089-091: printa sul monitor seriale eventuali informazioni che puoi ricevere dal mini mp3;

linea 095-098: esegui il controllo del tempo trasorso anche per la parte luminosa al fine di determinare il cambio del gioco luminoso;

linee 100-290: sono le stesse che hai già visto e compreso in occasione dell’articolo dedicato alla WeMos ed alla FastLED

Il video della Wemos Neopixel Music

Esegui l’upload sulla WeMos D1, collega le casse e …

Buone Feste !!!

Cortesemente, prima di inserire i commenti leggi il regolamento

Permanent link to this article: http://www.mauroalfieri.it/elettronica/wemos-neopixel-music.html

Lascia un commento

Your email address will not be published.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.