Proyecto con Arduino: receptor inalámbrico y luces

El post anterior fue el esquema y el código definitivos del transmisor; este post es el esquema y el código definitivos del receptor.

Tras decidir quitar el altavoz – porque para donde se iba a usar no se iba a escuchar nada – y cambiar los leds RGB por neopixels, el circuito quedó ligeramente menos complejo. La complejidad real está en montar el circuito real, porque ha resultado ser un lío de cables. Le he añadido un botón de encendido y apagado por si fallara la comunicación inalámbrica, y el esquemático del resultado es este:

Sobre el circuito:

He usado tantos leds que al final han sido necesarias dos fuentes de alimentación, una para el arduino y otra para los leds. En este post hay información super útil sobre qué fuentes usar; para el arduino vale cualquiera, pero para los LEDs se necesita una fuente de alimentación de exactamente 5V, y que sea capaz de dar bastante más de los 500mA que proporciona el arduino. Calculé a ojo que para los 47 LEDs que iba a necesitar, que recordemos que no son 47, son 47*4, al tratarse de LEDs RGBW, iba a necesitar un máximo de 4A. Al final usé como fuente de alimentación para los leds 2 baterías de litio 18650 de 3,7V, enganchadas a un regulador de voltaje que proporciona 5V y hasta 6A.

Además de la fuente de alimentación adicional para los LEDs – y no olvidar conectar la tierra de todos los componentes entre sí -, al hacer el circuito real es útil seguir las indicaciones de la uberguide de adafruitaquí un post que lo resume en español – que son colocar un condensador de 1000uF entre el voltaje y la tierra de la fuente de alimentación de los LEDs, y colocar una resistencia de unos 470 Ohmios delante del primer LED de cada tira. También, si usáis tiras de LEDs esto no es necesario, pero si usáis LEDs independientes y los conectais a mano sí, habría que añadir un condensador de 0,1uF entre voltaje y tierra de cada LED.

tal que así

El código para las luces del pecho – 23 LEDs -, los brazos – 1 LED cada uno -, el torso y abdomen – 18 LEDs – y las piernas – 4 LEDs cada uno, pero usé un pin para las dos, en vez de dos, como en los brazos – ha quedado así:


#include
#include //the communication interface with the modem
#include “RF24.h” //the library which helps us to control the radio modem
#includeRF24 radio(5,10); /*This o–bject represents a modem connected to the Arduino.
Arguments 5 and 10 are a digital pin numbers to which signals
CE and CSN are connected.*/const uint64_t pipe = 0xE8E8F0F0E1LL; //the address of the modem,that will receive data from the Arduino.byte RFID_Data[4];int boton = 3;
long tiempo_anterior_boton;
long diferencia_boton;

long tiempo_anterior =0;
long diferencia;

#define PIN_PECHO 6
#define NUMPIXELS_PECHO 23

#define PIN_BRAZO1 7
#define NUMPIXELS_BRAZO1 1

#define PIN_BRAZO2 8
#define NUMPIXELS_BRAZO2 1

#define PIN_TORSOABDOMEN 9
#define NUMPIXELS_TORSOABDOMEN 18

#define PIN_PIERNAS 4
#define NUMPIXELS_PIERNAS 2

Adafruit_NeoPixel pixelsPecho = Adafruit_NeoPixel(NUMPIXELS_PECHO, PIN_PECHO, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixelsBrazo1 = Adafruit_NeoPixel(NUMPIXELS_BRAZO1, PIN_BRAZO1, NEO_RGBW + NEO_KHZ800);
Adafruit_NeoPixel pixelsBrazo2 = Adafruit_NeoPixel(NUMPIXELS_BRAZO2, PIN_BRAZO2, NEO_RGBW + NEO_KHZ800);
Adafruit_NeoPixel pixelsTorsoAbdomen = Adafruit_NeoPixel(NUMPIXELS_TORSOABDOMEN, PIN_TORSOABDOMEN, NEO_RGBW + NEO_KHZ800);
Adafruit_NeoPixel pixelsPiernas = Adafruit_NeoPixel(NUMPIXELS_PIERNAS, PIN_PIERNAS, NEO_RGBW + NEO_KHZ800);

bool encendido = false;
int cont = 0;

void setup(){
Serial.begin(9600);

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

pixelsBrazo1.begin();
pixelsBrazo1.show();

pixelsBrazo2.begin();
pixelsBrazo2.show();

pixelsTorsoAbdomen.begin();
pixelsTorsoAbdomen.show();

pixelsPiernas.begin();
pixelsPiernas.show();

pinMode(boton, INPUT);
attachInterrupt(digitalPinToInterrupt(boton), pulsacion, FALLING);

radio.begin(); //it activates the modem.
radio.openReadingPipe(1, pipe); //determines the address of our modem which receive data.
radio.startListening(); //enable receiving data via modem
}

void loop(){
if(radio.available()){ //checks whether any data have arrived at the address of the modem
radio.read(&RFID_Data, sizeof(RFID_Data));
char scannedRFID[10];
sprintf(scannedRFID, “%02X%02X%02X%02X”, RFID_Data[0], RFID_Data[1], RFID_Data[2], RFID_Data[3]);
Serial.println(scannedRFID);
cont++;
if(cont>5){
if(scannedRFID[0] == ‘8’ && scannedRFID[1] == ‘B’ && scannedRFID[2] == ‘B’ &&
scannedRFID[3] ==’1′ && scannedRFID[4] ==’B’ && scannedRFID[5] ==’3′ &&
scannedRFID[6] ==’1′ && scannedRFID[7] ==’B’){
diferencia = millis() – tiempo_anterior;
tiempo_anterior = millis();
if(diferencia > 7000){
cambiaEstadoLED();
cont = 0;
}
}
}
}
}

void pulsacion(){
diferencia_boton = millis() – tiempo_anterior_boton;
tiempo_anterior_boton = millis();
if(diferencia_boton > 500){
cambiaEstadoLED();
}
}

void cambiaEstadoLED(){
if(!encendido){
encender();
Serial.println(“encendido”);
}
else{
apagar();
Serial.println(“apagado”);
}
encendido = !encendido;
}

void encender(){
uint16_t i, j;

for (j = 0; j < 150 ; j++) {
for(int i=0;i<NUMPIXELS_PECHO;i++){
pixelsPecho.setPixelColor(i, pixelsPecho.Color(23,161,165));
}
pixelsPecho.setBrightness(j);
pixelsPecho.show();

for(int i=0;i<NUMPIXELS_BRAZO1;i++){
pixelsBrazo1.setPixelColor(i, pixelsBrazo1.Color(161,23,190, 50));
}
pixelsBrazo1.setBrightness(j);
pixelsBrazo1.show();

for(int i=0;i<NUMPIXELS_BRAZO2;i++){
pixelsBrazo2.setPixelColor(i, pixelsBrazo2.Color(161,23,190, 50));
}
pixelsBrazo2.setBrightness(j);
pixelsBrazo2.show();

for(int i=0;i<NUMPIXELS_TORSOABDOMEN;i++){
pixelsTorsoAbdomen.setPixelColor(i, pixelsTorsoAbdomen.Color(161,23,190, 50));
}
pixelsTorsoAbdomen.setBrightness(j);
pixelsTorsoAbdomen.show();

for(int i=0;i<NUMPIXELS_PIERNAS;i++){
pixelsPiernas.setPixelColor(i, pixelsPiernas.Color(161,23,190, 50));
}
pixelsPiernas.setBrightness(j);
pixelsPiernas.show();

delay(20);
}
}

void apagar(){
uint16_t i, j;

for (j = 150; j > 0; j–) {
for(int i=0;i<NUMPIXELS_PECHO;i++){
pixelsPecho.setPixelColor(i, pixelsPecho.Color(23,161,165));
}
pixelsPecho.setBrightness(j);
pixelsPecho.show();

for(int i=0;i<NUMPIXELS_BRAZO1;i++){
pixelsBrazo1.setPixelColor(i, pixelsBrazo1.Color(161,23,190, 50));
}
pixelsBrazo1.setBrightness(j);
pixelsBrazo1.show();

for(int i=0;i<NUMPIXELS_BRAZO2;i++){
pixelsBrazo2.setPixelColor(i, pixelsBrazo2.Color(161,23,190, 50));
}
pixelsBrazo2.setBrightness(j);
pixelsBrazo2.show();

for(int i=0;i<NUMPIXELS_TORSOABDOMEN;i++){
pixelsTorsoAbdomen.setPixelColor(i, pixelsTorsoAbdomen.Color(161,23,190, 50));
}
pixelsTorsoAbdomen.setBrightness(j);
pixelsTorsoAbdomen.show();

for(int i=0;i<NUMPIXELS_PIERNAS;i++){
pixelsPiernas.setPixelColor(i, pixelsPiernas.Color(161,23,190, 50));
}
pixelsPiernas.setBrightness(j);
pixelsPiernas.show();

delay(15);
}
}

Sobre el código:

He tenido algunos problemas con la lectura del código que se está transmitiendo: cuando cambio de tarjeta, las primeras lecturas son del código de la tarjeta anterior. Por eso he colocado un contador que solamente comprueba si el código leído es el “programado” para accionar las luces cuando se han recibido 5 códigos seguidos (if(cont>5){).

Si el código es el correcto, comprueba que hayan pasado más de 7 segundos desde la última lectura – el transmisor emite durante 4 segundos, y las luces tardan en encenderse unos 3, así a ojo, así que decidí que 7 segundos era un buen tiempo para evitar lecturas falsas o apagar y encender las luces con la misma transmisión -.

Si han pasado más de 7 segundos, identifica la lectura como “correcta”, y acciona las luces.

El botón para encender y apagar las luces está programado con una interrupción y también tiene un pequeño control de tiempo entre pulsaciones para evitar rebotes, este solo de 500 milisegundos.

El código de encendido y apagado ya lo he mostrado en posts anteriores, y bueno, lo único que he hecho ha sido replicarlo cinco veces, una por cada salida de las luces.

Y solo mencionar que en mi circuito los LEDs del pecho no son RGBW, son GRB – se puede ver en la línea en la que “declaro” los pixels -, y por eso el código del color azul ciano para su pin tiene solo tres códigos – falta el blanco -, y R y G están cambiados.

Este código me parece ideal para realizar modificaciones, ya que lo único que hay que modificar es el pin y el número de pixels, todo lo demás está ya hecho a medida.

El circuito ya montado es un lío de cables, pero esto es lo que me ha salido a mi:

 

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

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 *