Hola,
aquí os dejo el código para programar el cubo con LEDS. Es un firmware en desarrollo, todavía tiene fallos y lo iré actualizando.
Aquí os dejo también un boceto que me hice para calcular el cambio de coordenadas para los LEDS.
Un saludo.
// NeoPixelTest
// This example will cycle between showing four pixels as Red, Green, Blue, White
// and then showing those pixels as Black.
//
// Included but commented out are examples of configuring a NeoPixelBus for
// different color order including an extra white channel, different data speeds, and
// for Esp8266 different methods to send the data.
// NOTE: You will need to make sure to pick the one for your platform
//
//
// There is serial output of the current state so you can confirm and follow along
//
//#include <NeoPixelBus.h>
#include <NeoPixelBrightnessBus.h> // instead of NeoPixelBus.h
#include "IRLibAll.h"
#define PIN_CHR 3
#define PIN_FULL 9
#define PIN_ADC 0
#define STATUS_CHR 0
#define STATUS_1 1
#define STATUS_2 2
#define STATUS_3 3
#define STATUS_4 4
#define STATUS_5 5
#define STATUS_6 6
#define STATUS_OFF 7
#define LEDS_OFF 0
#define LEDS_ON 1
int RECV_PIN = 2;
//volatile bool ir_flag = false;
unsigned char status_cube = STATUS_OFF;
unsigned char status_leds = LEDS_OFF;
uint8_t brightness = 50; //between 8 and 255
IRrecvPCI myReceiver(RECV_PIN); //create receiver and pass pin number
IRdecode myDecoder; //create decoder
const uint16_t PixelCount = 192; // this example assumes 4 pixels, making it smaller will cause a failure
const uint8_t PixelPin = 4; // make sure to set this to the correct pin, ignored for Esp8266 //default 2
#define colorSaturation 128
// three element pixels, in different order and speeds
//NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin); //default
NeoPixelBrightnessBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
//NeoPixelBus<NeoRgbFeature, Neo400KbpsMethod> strip(PixelCount, PixelPin);
// For Esp8266, the Pin is omitted and it uses GPIO3 due to DMA hardware use.
// There are other Esp8266 alternative methods that provide more pin options, but also have
// other side effects.
//NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount);
//
// NeoEsp8266Uart800KbpsMethod uses GPI02 instead
// You can also use one of these for Esp8266,
// each having their own restrictions
//
// These two are the same as above as the DMA method is the default
// NOTE: These will ignore the PIN and use GPI03 pin
//NeoPixelBus<NeoGrbFeature, NeoEsp8266Dma800KbpsMethod> strip(PixelCount, PixelPin);
//NeoPixelBus<NeoRgbFeature, NeoEsp8266Dma400KbpsMethod> strip(PixelCount, PixelPin);
// Uart method is good for the Esp-01 or other pin restricted modules
// NOTE: These will ignore the PIN and use GPI02 pin
//NeoPixelBus<NeoGrbFeature, NeoEsp8266Uart800KbpsMethod> strip(PixelCount, PixelPin);
//NeoPixelBus<NeoRgbFeature, NeoEsp8266Uart400KbpsMethod> strip(PixelCount, PixelPin);
// The bitbang method is really only good if you are not using WiFi features of the ESP
// It works with all but pin 16
//NeoPixelBus<NeoGrbFeature, NeoEsp8266BitBang800KbpsMethod> strip(PixelCount, PixelPin);
//NeoPixelBus<NeoRgbFeature, NeoEsp8266BitBang400KbpsMethod> strip(PixelCount, PixelPin);
// four element pixels, RGBW
//NeoPixelBus<NeoRgbwFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
RgbColor red(colorSaturation, 0, 0);
RgbColor green(0, colorSaturation, 0);
RgbColor blue(0, 0, colorSaturation);
RgbColor white(colorSaturation);
RgbColor black(0);
RgbColor yellow(colorSaturation,colorSaturation,0);
RgbColor orange(colorSaturation,colorSaturation / 2,0);
HslColor hslRed(red);
HslColor hslGreen(green);
HslColor hslBlue(blue);
HslColor hslWhite(white);
HslColor hslBlack(black);
HslColor hslYellow(yellow);
HslColor hslOrange(orange);
unsigned int xy2pixel(unsigned int x,unsigned int y){
unsigned int pixel;
unsigned int face;
unsigned int u = 0;
unsigned int v = 0;
if( x>= 0 && x<=14) face = 0;
else if(x > 14 && x < 30) face = 1;
else if(x >= 30 && x <= 44) face = 2;
x = x % 15;
//transform x,y to u,v
u = (x - 7 + y) / 2;
v = (7 - x + y) / 2;
//transform u,v to pixel number
pixel = (face * 64) + 56 + u - (8 * v);
// Serial.print("Pos x:");
// Serial.print(x);
// Serial.print("Pos y:");
// Serial.print(y);
// Serial.print("Pos u:");
// Serial.print(u);
// Serial.print("Pos v:");
// Serial.print(v);
// Serial.print("Face:");
// Serial.print(face);
// Serial.print("Pixel:");
// Serial.println(pixel);
return pixel;
}
bool validxy(unsigned int x,unsigned int y){
x = x % 15;
if(x == 0 && y == 7) return true;
if(x == 1 && (y == 6 || y == 8)) return true;
if(x == 2 && (y == 5 || y == 7 || y == 9)) return true;
if(x == 3 && (y == 4 || y == 6 || y == 8 || y == 10)) return true;
if(x == 4 && (y == 3 || y == 5 || y == 7 || y == 9 || y == 11)) return true;
if(x == 5 && (y == 2 || y == 4 || y == 6 || y == 8 || y == 10 || y == 12)) return true;
if(x == 6 && (y == 1 || y == 3 || y == 5 || y == 7 || y == 9 || y == 11 || y == 13)) return true;
if(x == 7 && (y == 0 || y == 2 || y == 4 || y == 6 || y == 8 || y == 10 || y == 12 || y == 14)) return true;
if(x == 8 && (y == 1 || y == 3 || y == 5 || y == 7 || y == 9 || y == 11 || y == 13)) return true;
if(x == 9 && (y == 2 || y == 4 || y == 6 || y == 8 || y == 10 || y == 12)) return true;
if(x == 10 && (y == 3 || y == 5 || y == 7 || y == 9 || y == 11)) return true;
if(x == 11 && (y == 4 || y == 6 || y == 8 || y == 10)) return true;
if(x == 12 && (y == 5 || y == 7 || y == 9)) return true;
if(x == 13 && (y == 6 || y == 8)) return true;
if(x == 14 && y == 7) return true;
return false;
}
void ISR_CHR(void){
status_cube = STATUS_CHR;
}
//void ISR_IR(void){
// ir_flag = true;
//}
void charging(void){
status_leds = LEDS_ON;
unsigned int pos_x,pos_y,level;
unsigned int adcvalue = analogRead(PIN_ADC); //10bit ADC 0-1023
level = map(adcvalue,613,869,0,14);
if(digitalRead(PIN_FULL) == LOW){
for(pos_x = 0;pos_x < 3*15; pos_x ++){
for(pos_y = 0;pos_y < 15; pos_y ++){
if(validxy(pos_x,pos_y)) strip.SetPixelColor(xy2pixel(pos_x,pos_y), hslGreen); //cube green to indicate it is fully charged
}
}
strip.Show();
delay(1000);
for(int i = 0;i<192;i++){
strip.SetPixelColor(i, black);
}
strip.Show();
delay(1000);
}
else{
//is charging but we want to know the voltage. LiIon should be between 3--613 and 4.2 V--859
for(pos_y = 0;pos_y < level; pos_y ++){
for(pos_x = 0;pos_x < 15*3; pos_x ++){
if(validxy(pos_x,pos_y)) strip.SetPixelColor(xy2pixel(pos_x,pos_y), hslGreen); //cube green to indicate it is fully charged
}
}
strip.Show();
//delay(500);
}
}
void turn_off(void){
for(int i = 0;i<192;i++){
strip.SetPixelColor(i, black);
}
strip.Show();
status_leds = LEDS_OFF;
}
void status_1(void){ //fill displays in x direction
status_leds = LEDS_ON;
unsigned int pos_x; //pos x from 0 to 14 (3x15-1)
unsigned int pos_y; //pos y from 0 to 14
// turn off the pixels
for(int i = 0;i<192 /*&& !ir_flag*/;i++){
strip.SetPixelColor(i, black);
}
strip.Show();
delay(10);
//pos_y = 8;
for(pos_y = 0; pos_y < 15 /*&& !ir_flag*/; pos_y ++){
for(pos_x = 0; pos_x < 15*3 /*&& !ir_flag*/; pos_x ++){
if(validxy(pos_x,pos_y)){
strip.SetPixelColor(xy2pixel(pos_x,pos_y), hslGreen);
strip.Show();
delay(10);
}
}
}
}
void status_2(void){ //fill display in y direction
status_leds = LEDS_ON;
unsigned int pos_x; //pos x from 0 to 14 (3x15-1)
unsigned int pos_y; //pos y from 0 to 14
// turn off the pixels
for(int i = 0;i<192 /*&& !ir_flag*/;i++){
strip.SetPixelColor(i, black);
}
strip.Show();
delay(10);
//pos_y = 8;
for(pos_x = 0; pos_x < 15*3 /*&& !ir_flag*/; pos_x ++){
for(pos_y = 0; pos_y < 15 /*&& !ir_flag*/; pos_y ++){
if(validxy(pos_x,pos_y)){
strip.SetPixelColor(xy2pixel(pos_x,pos_y), hslRed);
strip.Show();
delay(10);
}
}
}
}
void status_3(void){ //fill display in lines, from botton to top
status_leds = LEDS_ON;
unsigned int pos_x; //pos x from 0 to 14 (3x15-1)
unsigned int pos_y; //pos y from 0 to 14
// turn off the pixels
for(int i = 0;i<192 /*&& !ir_flag*/;i++){
strip.SetPixelColor(i, black);
}
strip.Show();
delay(10);
//pos_y = 8;
for(pos_y = 0; pos_y < 15 /*&& !ir_flag*/; pos_y ++){
for(pos_x = 0; pos_x < 15*3 /*&& !ir_flag*/; pos_x ++){
if(validxy(pos_x,pos_y)){
strip.SetPixelColor(xy2pixel(pos_x,pos_y), hslBlue);
}
}
strip.Show();
delay(80);
}
}
void status_4(void){ //rotate 2 colors in x direction
status_leds = LEDS_ON;
unsigned int pos_x; //pos x from 0 to 14 (3x15-1)
unsigned int pos_y; //pos y from 0 to 14
// turn off the pixels
// for(int i = 0;i<192;i++){
// strip.SetPixelColor(i, black);
// }
// strip.Show();
// delay(1000);
//pos_y = 8;
for(pos_x = 0; pos_x < 15*3 /*&& !ir_flag*/; pos_x ++){
for(pos_y = 0; pos_y < 15 /*&& !ir_flag*/; pos_y ++){
if(validxy(pos_x,pos_y)) strip.SetPixelColor(xy2pixel(pos_x,pos_y), hslBlue);
if(validxy(pos_x + 1,pos_y)) strip.SetPixelColor(xy2pixel(pos_x + 1,pos_y), hslGreen);
if(validxy(pos_x + 2,pos_y)) strip.SetPixelColor(xy2pixel(pos_x + 2,pos_y), hslGreen);
if(validxy(pos_x + 3,pos_y)) strip.SetPixelColor(xy2pixel(pos_x + 3,pos_y), hslGreen);
if(validxy(pos_x + 4,pos_y)) strip.SetPixelColor(xy2pixel(pos_x + 4,pos_y), hslGreen);
if(validxy(pos_x + 5,pos_y)) strip.SetPixelColor(xy2pixel(pos_x + 5,pos_y), hslRed);
if(validxy(pos_x + 6,pos_y)) strip.SetPixelColor(xy2pixel(pos_x + 6,pos_y), hslRed);
if(validxy(pos_x + 7,pos_y)) strip.SetPixelColor(xy2pixel(pos_x + 7,pos_y), hslRed);
}
strip.Show();
delay(80);
}
}
void status_5(void){ //go up and down
status_leds = LEDS_ON;
unsigned int pos_x; //pos x from 0 to 14 (3x15-1)
unsigned int pos_y; //pos y from 0 to 14
// turn off the pixels
// for(int i = 0;i<192;i++){
// strip.SetPixelColor(i, black);
// }
// strip.Show();
// delay(1000);
//pos_y = 8;
for(pos_y = 0; pos_y < 15 - 5 /*&& !ir_flag*/; pos_y ++){
for(pos_x = 0; pos_x < 15*3 /*&& !ir_flag*/; pos_x ++){
if(validxy(pos_x,pos_y)) strip.SetPixelColor(xy2pixel(pos_x,pos_y), hslYellow);
if(validxy(pos_x,pos_y + 1)) strip.SetPixelColor(xy2pixel(pos_x,pos_y + 1), hslGreen);
if(validxy(pos_x,pos_y + 2)) strip.SetPixelColor(xy2pixel(pos_x,pos_y + 2), hslGreen);
if(validxy(pos_x,pos_y + 3)) strip.SetPixelColor(xy2pixel(pos_x,pos_y + 3), hslGreen);
if(validxy(pos_x,pos_y + 4)) strip.SetPixelColor(xy2pixel(pos_x,pos_y + 4), hslRed);
if(validxy(pos_x,pos_y + 5)) strip.SetPixelColor(xy2pixel(pos_x,pos_y + 5), hslRed);
}
strip.Show();
delay(60);
}
for(pos_y = 15; pos_y >= 0 + 5 /*&& !ir_flag*/; pos_y --){
for(pos_x = 0; pos_x < 15*3 /*&& !ir_flag*/; pos_x ++){
if(validxy(pos_x,pos_y)) strip.SetPixelColor(xy2pixel(pos_x,pos_y), hslYellow);
if(validxy(pos_x,pos_y - 1)) strip.SetPixelColor(xy2pixel(pos_x,pos_y - 1), hslGreen);
if(validxy(pos_x,pos_y - 2)) strip.SetPixelColor(xy2pixel(pos_x,pos_y - 2), hslGreen);
if(validxy(pos_x,pos_y - 3)) strip.SetPixelColor(xy2pixel(pos_x,pos_y - 3), hslGreen);
if(validxy(pos_x,pos_y - 4)) strip.SetPixelColor(xy2pixel(pos_x,pos_y - 4), hslRed);
if(validxy(pos_x,pos_y - 5)) strip.SetPixelColor(xy2pixel(pos_x,pos_y - 5), hslRed);
}
strip.Show();
delay(60);
}
}
void status_6(void){
status_leds = LEDS_ON;
unsigned int pos_x; //pos x from 0 to 14 (3x15-1)
unsigned int pos_y; //pos y from 0 to 14
unsigned int index;
// turn off the pixels
// for(int i = 0;i<192;i++){
// strip.SetPixelColor(i, black);
// }
// strip.Show();
// delay(1000);
//pos_y = 8;
for(pos_x = 0; pos_x < 15*3 /*&& !ir_flag*/; pos_x ++){
for(pos_y = 0; pos_y < 15 /*&& !ir_flag*/; pos_y ++){
for(index = 0; index < 15; index ++){
if(validxy(pos_x + index,pos_y)) strip.SetPixelColor(xy2pixel((pos_x + index) % (3*15),pos_y), hslRed);
if(validxy(pos_x + index + 15,pos_y)) strip.SetPixelColor(xy2pixel((pos_x + index + 15) % (3*15),pos_y), hslGreen);
if(validxy(pos_x + index + 30,pos_y)) strip.SetPixelColor(xy2pixel((pos_x + index + 30) % (3*15),pos_y), hslBlue);
}
}
strip.Show();
delay(60);
}
}
void change_mode(void){
myDecoder.decode(); //Decode SONY protocol
switch(myDecoder.value){
case 0x199D: status_cube = STATUS_CHR;break;//DATA CODE
case 0xD9C: status_cube = STATUS_1;break;//1 REW
case 0x39C: status_cube = STATUS_2;break;//2 FF
case 0x19C: status_cube = STATUS_3;break;//3 STOP
case 0x59C: status_cube = STATUS_4;break;//4 PLAY
case 0x5BC: status_cube = STATUS_5;break;//5 DATA SCREEN
case 0x99C: status_cube = STATUS_6;break;//6 PAUSE
case 0x4C9D: status_cube = STATUS_OFF; break;//START STOP T is 2C9B and W is 6C9B
default: status_cube = STATUS_OFF;break;
}
//ir_flag = false;
Serial.print("Status:");
Serial.println(status_cube);
}
void setup()
{
pinMode(PIN_CHR,INPUT_PULLUP);
pinMode(PIN_FULL,INPUT_PULLUP);
//pinMode(PIN_ADC,INPUT);
Serial.begin(115200);
while (!Serial); // wait for serial attach
Serial.println();
Serial.println("Initializing...");
Serial.flush();
// this resets all the neopixels to an off state
strip.Begin();
strip.Show();
strip.SetBrightness(brightness);
myReceiver.enableIRIn(); // Start the receiver
attachInterrupt(digitalPinToInterrupt(PIN_CHR), ISR_CHR, FALLING);
//attachInterrupt(digitalPinToInterrupt(RECV_PIN), ISR_IR, FALLING);
// Serial.println();
// Serial.println("Running...");
}
void loop(){
if (myReceiver.getResults()) change_mode();
//Serial.println(results.value, HEX);
switch(status_cube){
case STATUS_CHR: /*turn_off();*/ charging();break;
case STATUS_1: status_1();break;
case STATUS_2: status_2();break;
case STATUS_3: status_3();break;
case STATUS_4: status_4();break;
case STATUS_5: status_5();break;
case STATUS_6: status_6();break;
case STATUS_OFF: if(status_leds == LEDS_ON) turn_off();break;
default: break;
}
myReceiver.enableIRIn(); //Restart receiver
}