Proyecto con Arduino: luces y audio con WS1812 (neopixel) y nueva biblioteca de reproducción de audio

Tras tener el circuito de las luces y el audio, me di cuenta de que los diodos que iba a usar eran una variedad del model WS2812 (llamados neopixel), unos diodos especiales, y encima no los RGB sino los RGBW. Y también encontré una biblioteca (TMRpcm) para reproducir el audio de la tarjeta microSD que ni hacía el sonido más agudo ni lo reproducía cuatro veces más rápido, aunque se sigue teniendo que convertir el archivo a .wav de la misma forma que para la antigua biblioteca.

Recordemos el circuito, cambiando los diodos RGB por dos anillos de neopixel:

Los neopixel tienen un controlador integrado así que solo requieren una entrada analógica que interpretan para saber qué color mostrar, y encima pueden encadenarse en serie (no la tierra y el voltaje de referencia, pero sí la señal con la información del color). También necesitan de su propia biblioteca, que os podéis bajar aquí. El código para el diagrama de arriba, con la biblioteca de reproducción de audio nueva, es el siguiente:


#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#include "SD.h" //Lib to read SD card
#include "TMRpcm.h" //Lib to play auido
#include "SPI.h" //SPI lib for SD card

#define SD_ChipSelectPin 4 //Chip select is pin number 4
TMRpcm music; //Lib object is named "music"

#define PIN 6
#define PIN2 3
#define NUMPIXELS 7
#define NUMPIXELS2 16

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels2 = Adafruit_NeoPixel(NUMPIXELS2, PIN2, NEO_GRB + NEO_KHZ800);

int boton = 2;
long tiempo_anterior;
long diferencia;
bool encendido = false;
bool flagLuces = false;

void setup() {
Serial.begin(9600);
pinMode(boton, INPUT);

pixels.begin(); // This initializes the NeoPixel library.
pixels.show(); // initialize all pixels to "off"

pixels2.begin(); // This initializes the NeoPixel library.
pixels2.show(); // initialize all pixels to "off"

attachInterrupt(digitalPinToInterrupt(boton), botonLuces, FALLING);

music.speakerPin = 9; //Auido out on pin 9

if (!SD.begin(SD_ChipSelectPin)) {
Serial.println("SD fail");
return;
}

music.setVolume(5); // 0 to 7. Set volume level
music.quality(1); // Set 1 for 2x oversampling Set 0 for normal
}

void loop() {
if(flagLuces){
flagLuces = false;
cambiaEstadoLED();
}
}

void cambiaEstadoLED(){
music.play("ALARMA.wav");
if(!encendido){
encender();
Serial.println("encendido");
music.disable();
}
else{
apagar();
Serial.println("apagado");
music.disable();
}
encendido = !encendido;
}

void botonLuces(){
diferencia = millis() - tiempo_anterior;
tiempo_anterior = millis();
//Serial.println(diferencia);

if(diferencia > 500){
flagLuces = true;
}
}

void encender(){
uint16_t i, j;
for (j = 0; j < 255; j++) {
for(int i=0;i<NUMPIXELS;i++){
pixels.setPixelColor(i, pixels.Color(23,161,165));
}
pixels.setBrightness(j);
pixels.show();
for(int i=0;i<NUMPIXELS2;i++){
pixels2.setPixelColor(i, pixels2.Color(23,161,165));
}
pixels2.setBrightness(j);
pixels2.show();
delay(20);
}
}

void apagar(){
uint16_t i, j;
for (j = 255; j > 0; j--) {
for(int i=0;i<NUMPIXELS;i++){
pixels.setPixelColor(i, pixels.Color(23,161,165));
}
pixels.setBrightness(j);
pixels.show();
for(int i=0;i<NUMPIXELS2;i++){
pixels2.setPixelColor(i, pixels2.Color(23,161,165));
}
pixels2.setBrightness(j);
pixels2.show();
delay(10);
}
}

Sobre el código:

Os recomiendo que si no conocéis la biblioteca Adafruit_Neopixel, la abráis y la tengáis a mano mientras programáis con estos diodos; el código está muy bien documentado y puede ayudaros (a mi me sacó de un aprieto con el cambio de intensidades).

No fui capaz de cambiar la intensidad de los LEDs jugando con los códigos de colores: me cambiaba de color en vez de brillo. Así que por eso fijé el color y lo que fui modificando fue la intensidad — y el código funciona porque leí los comentarios sobre la función en la biblioteca —. También cambia un poco cómo se inicializa el audio, pero poco más.

No ha desaparecido el pitido que se oye por los altavoces cuando los diodos están encendidos, quiero pensar que cuando los diodos estén más lejos del altavos dejará de escucharse o al menos bajará de volumen, pero no las tengo todas conmigo.

También es más que probable que el arduino no pueda con tantos diodos a la vez y la ejecución comience a hacer cosas raras, lo sé porque a mi me ha pasado con el audio. Un arduino da una intensidad de 500mA, y un diodo al 100% de intensidad necesita unos 60mA. Los neopixel no chupan tanto porque NO están al 100% de su brillo, pero vamos, que si enganchas 23 diodos a una fuente de 500mA lo más seguro es que empiecen a hacer cosas raras.

Para un número muy alto de diodos de este tipo — o de cualquiera — lo suyo es usar una fuente externa, a 5V y la intensidad que calculéis necesaria. Cuando haga el circuito final – que lleva bastantes más diodos que 23 – os enseñaré por qué he optado yo, y os pasaré un par de enlaces para ver otras opciones.

 

************************************************************

Espero que esta entrada pueda ser de utilidad, y si no, como siempre, aquí tenéis un gato para compensar.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *