Lab_interaccio/2018/LLAC-RX-Neopixel_Sublime/LLAC-RX-Neopixel_Sublime.ino
2025-02-25 21:29:42 +01:00

2338 lines
64 KiB
C++

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#include "Adafruit_NeoPixel.h"
#define RADIOSEND false
#define CE_PIN 12
#define CSN_PIN 2
#define DEBUG 0
#define TEST 0
#define RED 11
#define GREEN 10
#define BLUE 9
#define WHITE 6
#define SDO1 4
#define SDO2 8
#define SDO3 3
#define NUMPIXELS1 300 // fuego
#define NUMPIXELS2 150
#define NUMPIXELS3 150
//int idpin[8] = { 5, 13, A4, A3, A2, A1, A0, A5};
int idpin[6] = { A5, A0, A1, A2, A3, A4};
int chpin[2] = { 13, 5 }; // no se va a usar en esta App
Adafruit_NeoPixel pixels1 = Adafruit_NeoPixel(NUMPIXELS1, SDO1, NEO_GRBW + NEO_KHZ800);
Adafruit_NeoPixel pixels2 = Adafruit_NeoPixel(NUMPIXELS2, SDO2, NEO_GRBW + NEO_KHZ800);
Adafruit_NeoPixel pixels3 = Adafruit_NeoPixel(NUMPIXELS3, SDO3, NEO_GRBW + NEO_KHZ800);
byte neopix_gamma[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255
};
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
const uint64_t pipe = 0xE8E8F0F0E1LL; // Define the transmit pipe
uint8_t CMD[ 8 ]; // CMD + Ch + 2
int ch = 76; // Fuerzo a canal 76 (showroom)
// Globales PIXEL
unsigned long delayed = 0; // control de tiempo de funciones de pixel
int countFrame = 0;
unsigned long launchTime = 0;
short stroboPixelFlag = 0;
short pixelFlag = 0;
short pixelOn = 0;
short stroboPixelOn = 0;
float incRed, incGreen, incBlue, incWhite;
// Globales NEON
unsigned long delayedNeon = 0; // control de tiempo de funciones de neon
unsigned long launchTimeNeon = 0;
int countFrameNeon = 0;
short stroboFlagNeon = 0;
short neonFlag = 0;
short stroboNeonOn = 0;
short chflag = 0;
uint8_t param1 = 20;
uint8_t param2 = 140;
uint8_t selectedEffect = 0;
uint16_t i = 0;
int c = 0;
int numSer = 0;
char numStr[4];
byte globalNeonRed;
byte globalNeonGreen;
byte globalNeonBlue;
byte globalNeonWhite;
uint32_t p1, p2, p3, p4, p5, p6 ; // bytes para los comandos OSC (colores)
void resetBoard()
{
//Serial.println("reset");
NVIC_SystemReset(); // esta funcion en teoria si funciona en SAMD
}
byte id()
{
int id = 0;
for (byte i = 0; i < 6; i++ ) bitWrite(id, i, digitalRead(idpin[i]));
return id;
}
int channel()
{
int value = code();
switch (value)
{
case 0:
value = 0x10; //
break;
case 1:
value = 0x4C; //
break;
case 3:
value = 0x64; //
break;
case 4:
value = 0x7F; //
break;
default:
value = 0; //
break;
}
return value;
}
int code()
{
int value = 0;
for (byte i = 0; i < 2; i++) bitWrite(value, i, digitalRead(chpin[i]));
return value;
}
//////////////////////////////////////////////////////////////////
///////////////////////// SETUP ////////////////////////////////
//////////////////////////////////////////////////////////////////
void setup() {
pinMode(RED, OUTPUT);
digitalWrite(RED, LOW);
pinMode(GREEN, OUTPUT);
digitalWrite(GREEN, LOW);
pinMode(BLUE, OUTPUT);
digitalWrite(BLUE, LOW);
pinMode(WHITE, OUTPUT);
digitalWrite(WHITE, LOW);
for (int i = 0; i < 4; i++)
{
pinMode(idpin[i], INPUT);
pinMode(chpin[i], INPUT);
}
analogWrite(WHITE, 255);
analogWrite(RED, 255);
analogWrite(GREEN, 255);
analogWrite(BLUE, 255);
pixels1.begin();
pixels2.begin();
pixels3.begin();
pixels1.show(); // Initialize all pixels to 'off'
pixels2.show(); // Initialize all pixels to 'off'
pixels3.show(); // Initialize all pixels to 'off'
Serial.begin(512000);
//while (!Serial) {
// ; // wait for serial port to connect. Needed for Leonardo only
//}
analogWrite(WHITE, 0);
analogWrite(RED, 0);
analogWrite(GREEN, 0);
analogWrite(BLUE, 0);
//printf_begin();
radio.begin();
radio.setDataRate( RF24_250KBPS );
radio.setPALevel( RF24_PA_MAX );
radio.setAutoAck(0);
radio.setPayloadSize(8);
radio.setChannel(ch);
#if RADIOSEND
radio.openWritingPipe(pipe);
#else
radio.openReadingPipe(1, pipe);
radio.startListening();
#endif
radio.printDetails();
}
//////////////////////////////////////////////////////////////////
///////////////////////// LOOP ////////////////////////////////
//////////////////////////////////////////////////////////////////
void loop()
{
///////////////////////// RADIO ENCUESTA ////////////////////////
// Serial.print("id: ");
// Serial.println(id());
// Serial.print("code: ");
// Serial.println(code());
#if TEST
colorBrightness(255, 255, 0, 16);
#endif
while (radio.available())
{
//done = radio.read( CMD, sizeof(CMD) );
radio.read( CMD, sizeof(CMD) );
#if DEBUG
Serial.println("Got command");
for (int i = 0 ; i < sizeof(CMD) ; i++)
{
Serial.print(CMD[i]);
Serial.print(",");
}
Serial.println();
#endif
if(( CMD[1] == id() || ( CMD[1] == 0xFF ))) // Solo actualizo si el comando es para mi
{
selectedEffect = CMD[0];
p1 = CMD[2]; // color
p2 = CMD[3]; // color
p3 = CMD[4]; // modo, totalframes, tamaño
p4 = CMD[5]; // tiempo, framerate (randoms)
p5 = CMD[6]; // inicio pixel, numflashes, density (randoms)
p6 = CMD[7]; // final pixel, modo, decay
}
else break; // Sino es para mi, salgo del while
// ajustar los parametros de numero de pixels que llegan hasta 300,
//extrapolar 255 a 300
switch (selectedEffect) {
// case 0:
// // CMD 0 = off
// break;
case 1: // CMD 1 - FADE OUT
pixelFlag = 0; //No estaba originalmente, tiene sentido????
p4 = p4*100;
// P1 = DECAY
break;
case 2: // CMD 2 - FADE IN OUT NEON
neonFlag = 0;
p1 = hueWeel(CMD[2]);
p4 = p4*100;
// P1 = COLOR (HUE+WHITE), P2 = MODE (IN/OUT) , P3 = FADETIME
break;
case 3: // CMD 3 - FADE in/out PIXEL
pixelFlag = 0;
p1 = hueWeel(CMD[2]);
p4 = p4*100; // de DECIMAS A MILISEGUNDOS
// P1 = COLOR (HUE+WHITE), P2 = MODE (IN/OUT) , P3 = FADETIME
break;
case 4: // CMD 4 - FADE in/out PIXEL + NEON SIMULTANEOS
pixelFlag = 0;
neonFlag = 0;
p1 = hueWeel(CMD[2]);
p4 = p4*100; // de DECIMAS A MILISEGUNDOS
// P1 = COLOR (HUE+WHITE), P2 = MODE (IN/OUT) , P3 = FADETIME
break;
case 5: // CMD 5 - FADE COLOR PIXEL + NEON SIMULTANEOS
pixelFlag = 0;
neonFlag = 0;
p1 = hueWeel(CMD[2]);
p4 = p4*100; // de DECIMAS A MILISEGUNDOS
// P1 = END COLOR (HUE+WHITE), P2 = FADETIME
break;
case 6: // CMD 6 - FADE PIXEL RAINBOW
pixelFlag = 0;
p1 = hueWeel(CMD[2]);
p2 = hueWeel(CMD[3]);
p4 = p4*100;
// P1 = INIT COLOR (HUE+WHITE), P2 = END COLOR (HUE+WHITE), P3 = FADETIME
break;
case 7: // CMD 7 - STROBO NEON
neonFlag = 0;
p1 = hueWeel(CMD[2]);
// P1 = COLOR (HUE+WHITE), P2 = PERIODO, P3 = PWM, P4 = NUM FLASHES ( 0 permante )
break;
case 8: // CMD 8 - STROBO PIXEL + NEON SIMULTANEOS (sync ON)
pixelFlag = 0;
p1 = hueWeel(CMD[2]);
// P1 = COLOR (HUE+WHITE), P2 = PERIODO, P3 = PWM, P4 = NUM FLASHES ( 0 permante )
// P5 = NEON SYNC
break;
case 9: // CMD 9 - STROBO RANDOM COLOR + NEON SIMULTANEOS (sync ON)
pixelFlag = 0;
// P1 = PERIODO, P2 = PWM, P4 = NUM FLASHES ( 0 permante ), P4 (bool) = NEON SYNC
break;
case 10: // CMD 10 - RANDOM PIXEL
pixelFlag = 0;
p1 = hueWeel(CMD[2]);
// P1 = COLOR, P2 = TOTALFRAMES, P4 = FRAMERATE???, P5 = DENSITY
break;
case 11:
// CMD 11 - RANDOM COLOR + NEON SIMULTANEOS (sync ON) ????
pixelFlag = 0;
// P1 = TOTALFRAMES, P2 = FRAMERATE????
break;
case 12: // CMD 12 - RANDOM INVERT - EFECTO DISOLUCION
pixelFlag = 0;
p1 = hueWeel(CMD[2]);
// P1 = COLOR, P2 = TOTALFRAMES, P3 = FRAMERATE???, P4 = DENSITY
break;
case 13:// CMD 13 - PIXELBAR
pixelFlag = 0;
p1 = hueWeel(CMD[2]);
p4 = p4*100; // de DECIMAS A MILISEGUNDOS
if(p6 > p5)
p6=p6*300/255;
else
p5=p5*300/255;
// P1 = COLOR, P2 = ORIGEN, P3 = FINAL , P4 = TIEMPO
break;
case 14: // CMD 14 - SCANNER
pixelFlag = 0;
p1 = hueWeel(CMD[2]);
p4 = p4*100; // de DECIMAS A MILISEGUNDOS
if(p6 > p5)
p6=p6*300/255;
else
p5=p5*300/255;
// P1 = COLOR, P2 = ORIGEN, P3 = FINAL , P4 = TAMAÑO, P5 = TIEMPO
break;
case 15:// CMD 15 - METEORITO
pixelFlag = 0;
p1 = hueWeel(CMD[2]);
p4 = p4*100; // de DECIMAS A MILISEGUNDOS
if(p2 > p5)
p2=p2*300/255;
else
p5=p5*300/255;
// P1 = COLOR, P2 = DECAY, P3 = TAMAÑO, P4 = TIEMPO
break;
case 16:// CMD 16 - EXPLOSION, CENTRO A EXTREMOS
pixelFlag = 0;
p1 = hueWeel(CMD[2]);
p4 = p4*100; // de DECIMAS A MILISEGUNDOS
// P1 = COLOR, P2 = MODO, P3 = TAMAÑO, P4 = TIEMPO
break;
case 17: // CMD 17 - IMPLOSION, EXTREMO A CENTRO
pixelFlag = 0;
p1 = hueWeel(CMD[2]);
p4 = p4*100; // de DECIMAS A MILISEGUNDOS
// P1 = COLOR, P2 = MODO, P3 = TAMAÑO, P4 = TIEMPO
break;
case 18: // CMD 18 - FUEGO
pixelFlag = 0;
neonFlag = 0; // programar automatico un rojo en el NEON
// P1 = TAMAÑO, P2 = CHISPAS, P3 = TAMAÑO, P4 = TIEMPO
break;
case 19:
pixelFlag = 0;
neonFlag = 0; //color
p1 = hueWeel(CMD[2]);
break;
case 20:
// CMD 20 -
pixelFlag = 0;
neonFlag = 0; // programar automatico un rojo en el NEON
// P1 = color, P2 = value, P3 =
break;
case 100:
chflag = 0;
break;
case 200:
resetBoard(); //Reset de la placa
break;
}
}
///////////////////////// SERIE ENCUESTA ////////////////////////
if (Serial.available())
{
c = Serial.read();
if ( (c != 13) && (c != 10) )
{
numStr[numSer] = c;
numSer++;
//Serial.println(numSer);
}
if ( c == 13 ) // first 13, then 10
{
numStr[numSer] = '\0';
//Serial.println("retorno de carro");
//Serial.println(numStr);
selectedEffect = atol(numStr);
#if DEBUG
Serial.println(selectedEffect);
#endif
numSer = 0;
pixelFlag = 0;
neonFlag = 0;
chflag = 0;
}
}
///////////////////////// CALLS ANIMACIONES ////////////////////////
switch (selectedEffect)
{
case 0 : { // OFF - no parameters
setAll(0, 0, 0, 0);
colorNeon(0, 0, 0, 0);
splitStrip();
showStrip();
break;
}
///////////////////// FADES ////////////////////////
case 1 : {
// FADE OUT RANDOM - ( fadeTime, fadeRandomDecay, fadeTrailDecay, frameTime)
//fadeOutRandom(4000, true, 50, 16); // decay max:255
fadeOutRandom(p4, true, 50, 16);
break;
}
case 2 : { // ONLY NEON FADE IN OR FADE OUT
// NEON Color (color mode in/out, fadetime, frametime)
//fadeNeon(255, 0, 0, 0, 0, 2000, 16, 0);
fadeNeon(p1, p3, p4, 16);
break;
}
case 3 : { // ONLY STRIP FADE IN or FADE OUT
// Strip FADE Color (color, mode in/out, fadetime, frametime)
//fadePixel(p1, 0, 1000, 16); // fadein
fadePixel(p1, p3, p4, 16); // fadein , p4 unidades son decimas de segundo. 255 = 25,5s
// Serial.print(p1);
// Serial.print(",");
// Serial.print(p3);
// Serial.print(",");
// Serial.println(p4);
break;
}
case 4 : { // STRIP FADE + NEON SYNC
// Strip FADE Color (color, mode in/out, fadetime, frametime)
// NEON Color (color, mode in/out, fadetime, frametime)
fadePixel(p1, p3, p4, 16); // fadeout
fadeNeon(p1, p3, p4, 16);
//fadeNeon(255, 120, 40, 40, 1, 3000, 16); // BLANCO CALIBRADO NEON: 255, 120, 40
break;
}
case 5 : { // STRIP FADE COLOR
fadePixelColor(p1, p4, 33);
//fadePixelColor(0, 0, 255, 0, 5000, 33); // FADECOLOR
// NEON FADE COLOR
// ( color, fadeTime, frameTime, syncPixel ) // parte del color actual del strip
//fadeNeonColor(0, 0, 255, 255, 5000, 33, 1); // FADEC1OLOR
//fadeNeonColor(0, 0, 255, 255, 5000, 33);
fadeNeonColor(p1, p4, 33);
break;
}
// añadir casos nuevos de pixel y neon solos!!!!
case 6 : { // color inicial, color final, mode, fadetime, frameRate
//fadePixelRainbow(p1, p2, 1, 2000, 33); // FADE PIXEL RAINBOW, UN COLOR ARRIBA Y UNO ABAJO, FADE IN o FADE OUT
fadePixelRainbow(p1, p2, p3, p4, 33); // p1, p2: color, p3 mode, p4 time
break;
}
///////////////////// STROBOS ////////////////////////
case 7 : {
// Strobe - (time, PWM, numFlashes)
//stroboNeon(p1, 500, 15, 3);
stroboNeon(p1, p4, 15, p5); // aqui p4 es en milisegundos. Maximo 255
break;
}
case 8 : {
// Strobe SYNC- (r, g, b, w, time, PWM, numFlashes, NEON sync)
//stroboPixel(p1, 50, 15, 10, 1);
stroboPixel(p1, p4, 15, p5, p6); // sync= 1 aciva NEON, p5 = numflashes, p6 = sync
break;
}
case 9 : {
// Strobe SYNC- (time, PWM, numFlashes, NEON sync)
//stroboRandomColor(100, 50, 10, 1); //sync= 1 aciva NEON
stroboRandomColor(p4, 50, p5, p6); //sync= 1 aciva NEON
break;
}
///////////////////// RANDOMS ////////////////////////
case 10 : { // RANDOM: r, g, b, w, totalFrames, frameRate, density, oneOnly or adding pixels
randomPixel(p1, p3, p4, p5, false); // usar una variable FRAMERATE y DENSITY controlable en tiempo real
//randomPixel(0, 0, 0, 255, 100, 16, 3, true); //
break;
}
case 11 : {
//randomColor( 100, 100 ); // totalFrames , frameRate // usar una variable FRAMERATE
randomColor( p3, p4 ); // totalFrames , frameRate // usar una variable FRAMERATE
break;
}
case 12 : {// RANDOM: r, g, b, w, size, totalFrames, frameRate, density, oneOnly or adding pixels
//randomInvert(p1, 2, 30, 16, 20, true); // usar una variable FRAMERATE y DENSITY controlable en tiempo real
randomInvert(p1, 2, p3, 16, 20, true); // usar una variable FRAMERATE y DENSITY controlable en tiempo real
break;
}
///////////////////// BARRIDOS ////////////////////////
case 13 : {
// PIXELBAR - ( r, g, b, w, pixelInit, pixelEnd, loopTime, frameTime )
//pixelBar(255, 0, 0, 0, 100, 200, 16, 16); // pintado inmediato con 1 unico frame
//pixelBar(0, 0, 0, 255, 0, 300, 5000, 16); // rampa de SUBIDA de 5s
pixelBar(p1, p5, p6, p4, 16); // p4 tiempo de animacion, siempre hacia arriba?
// p5 = posicion origen, p6 = posicion fin
break;
}
case 14 : {
// SCANNER - (r, g, b, w, mode, pixelInit, pixelEnd, pixelWidth, loopTime, frameTime )
//scanner(0, 0, 0, 255, , 0, 0, 300, 4, 1000, 16); // rampa de SUBIDA de 1s
scanner(p1, 0, p5, p6, p3, p4, 16); // MODE = 0, scan
// p5 = origen, p6 = fin, p3 = tamaño, p4 = tiempo
break;
}
case 15 : {
// METEOR - (r, g, b, w, meteorTrailDecay, meteorRandomDecay, pixelInit, pixelEnd, pixelWidth, loopTime, frameTime)
//meteorRain(0, 0, 0, 255, true, 255, 0, 300, 10, 200, 16); // rampa de BAJADA de 1s
//meteorRain(p1, true, 100, 300, 0, 10, 3000, 16);
//meteorRain(p1, true, p6, 300, 0, p3, p4, 16); // rampa de BAJADA de 1s
meteorRain(p1, true, p6, p2, p5, p3, p4, 16); // Dos direcciones
// p3 = tamaño, p4 = tiempo, p6 = decay (100), p2 = pixelInit, p5 = pixelEnd
break;
}
case 16 : {
// CENTER TO OUT - (r, g, b, w, mode, pixelWidth, loopTime, frameTime )
//centerToOut(p1, false, 8, 1000, 16); // modo segmento
centerToOut(p1, p6, p3, p4, 16);
// p3 = tamaño, p4 = tiempo, p6 = modo (segmento o barra)
break;
}
case 17 : {
// OUT TO CENTER - (r, g, b, w, mode, pixelWidth, loopTime, frameTime ) // mode para hacerlo solido o barrido
outToCenter(p1, p6, p3, p4, 16); // modo barra
// p3 = tamaño, p4 = tiempo, p6 = modo (segmento o barra)
break;
}
///////////////////// EFECTOS ////////////////////////
case 18 : {
// Fire - Cooling rate, Sparking rate, framerate
//fire(55, 120, 16);
fire(p4, p5, p6, 16);
// p4 = altura llama, p5 = chispas, p6 = direccion
break;
}
case 19 : {
// go to color con control de intensidad
colorBrightness(p1, p2, p3, 16);
break;
}
case 100 : {
if (!chflag)
{
chflag = 1;
// go to color con control de intensidad
radio.setChannel(p1);
radio.startListening();
#if DEBUG
radio.printDetails();
Serial.print("canal: ");
Serial.println(p1);
#endif
//delay(1000);
}
break;
}
case 200 : {
#if DEBUG
Serial.println("Reseteando...");
#endif
resetBoard();
break;
}
}
}
//////////////////////////////////////////////////////////////////
/////////////////////// NEON FUNCIONS ///////////////////
//////////////////////////////////////////////////////////////////
void colorNeon(byte red, byte green, byte blue, byte white)
{
globalNeonRed = red;
globalNeonGreen = green;
globalNeonBlue = blue;
globalNeonWhite = white;
analogWrite(RED, globalNeonRed);
analogWrite(GREEN, globalNeonGreen);
analogWrite(BLUE, globalNeonBlue);
analogWrite(WHITE, globalNeonWhite);
}
//void fadeNeon(byte red, byte green, byte blue, byte white, int mode, int fadeTime, int frameTime, int syncPixel) // mode 0 = fadeIn, mode 1 = fadeOut
//void fadeNeon(byte red, byte green, byte blue, byte white, int mode, int fadeTime, int frameTime) // mode 0 = fadeIn, mode 1 = fadeOut
void fadeNeon(uint32_t color, int mode, int fadeTime, int frameTime) // mode 0 = fadeIn, mode 1 = fadeOut
{
if ( millis() > delayedNeon )
{
//if (syncPixel) // es necesario para sincronizar cuando va al mismo tiempo del pixel que es bloqueante
if (pixelOn) // automatico para no tener que pasarle syncPixel como parametro
delayedNeon = millis() + frameTime - 11 ; // compensacion de bloqueo de millis
else
delayedNeon = millis() + frameTime ; // compensacion de bloqueo de millis
float r, g, b, w;
float totalFrames = fadeTime / frameTime;
byte endRed = red(color);
byte endGreen = green(color);
byte endBlue = blue(color);
byte endWhite = white(color);
if(endWhite){ // si llega blanco configurar como natura white calibrado
endRed = 255;
endGreen = 120;
endBlue = 40;
endWhite = 40; // solo en PCB con salida azul estropeada
}
if (!neonFlag)
{
#if DEBUG
launchTimeNeon = millis();
if (!mode)
Serial.println("---NEON FADEIN---");
else
Serial.println("---NEON FADEOUT---");
Serial.print("fadeTime: ");
Serial.println(fadeTime);
Serial.print("LaunchTime: ");
Serial.println(launchTime);
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
countFrameNeon = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
neonFlag = true;
}
if (countFrameNeon < totalFrames)
{
countFrameNeon++;
if (!mode) // FADE IN
{
r = neopix_gamma[(byte)(255.*countFrameNeon / totalFrames)] * endRed / 255.; //
g = neopix_gamma[(byte)(255.*countFrameNeon / totalFrames)] * endGreen / 255.;
b = neopix_gamma[(byte)(255.*countFrameNeon / totalFrames)] * endBlue / 255.;
w = neopix_gamma[(byte)(255.*countFrameNeon / totalFrames)] * endWhite / 255.;
// Serial.println("----");
// Serial.println(255.*countFrameNeon/totalFrames);
// Serial.println(neopix_gamma[(int)(255.*countFrameNeon/totalFrames)]);
}
else
{
r = neopix_gamma[(byte)(255.*(totalFrames - countFrameNeon) / totalFrames)] * endRed / 255. ;
g = neopix_gamma[(byte)(255.*(totalFrames - countFrameNeon) / totalFrames)] * endGreen / 255. ;
b = neopix_gamma[(byte)(255.*(totalFrames - countFrameNeon) / totalFrames)] * endBlue / 255.;
w = neopix_gamma[(byte)(255.*(totalFrames - countFrameNeon) / totalFrames)] * endWhite / 255.;
// Serial.println("----");
// Serial.println(255.*countFrameNeon/totalFrames);
// Serial.println(neopix_gamma[(int)(255.*countFrameNeon/totalFrames)]);
}
globalNeonRed = r;
globalNeonGreen = g;
globalNeonBlue = b;
globalNeonWhite = w;
analogWrite(RED, r);
analogWrite(GREEN, g);
analogWrite(BLUE, b);
analogWrite(WHITE, b); // parche para salida blanco a azul en placa estropeada
//Serial.print("Red: ");
//Serial.println( r );
}
}
}
//void fadeNeonColor(byte startRed, byte startGreen, byte startBlue, byte startWhite, byte endRed, byte endGreen, byte endBlue, byte endWhite,int fadeTime, int frameTime, int syncPixel)
//void fadeNeonColor(byte endRed, byte endGreen, byte endBlue, byte endWhite,int fadeTime, int frameTime, int syncPixel)
void fadeNeonColor(uint32_t color ,int fadeTime, int frameTime)
{
if ( millis() > delayedNeon )
{
//if (syncPixel) // es necesario para sincronizar cuando va al mismo tiempo del pixel que es bloqueante
if (pixelOn)
delayedNeon = millis() + frameTime - 11 ; // compensacion de bloqueo de millis
else
delayedNeon = millis() + frameTime ; // compensacion de bloqueo de millis
float r, g, b, w;
float totalFrames = fadeTime / frameTime;
static byte startRed;
static byte startGreen;
static byte startBlue;
static byte startWhite;
byte endRed = red(color);
byte endGreen = green(color);
byte endBlue = blue(color);
byte endWhite = white(color);
if(endWhite){ // si llega blanco configurar como natura white calibrado
endRed = 255;
endGreen = 120;
endBlue = 40;
}
if (!neonFlag)
{
#if DEBUG
launchTimeNeon = millis();
Serial.println("---NEON FADECOLOR---");
Serial.print("fadeTime: ");
Serial.println(fadeTime);
Serial.print("LaunchTime: ");
Serial.println(launchTime);
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
countFrameNeon = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
neonFlag = true;
startRed = globalNeonRed;
startGreen = globalNeonGreen;
startBlue = globalNeonBlue;
startWhite = globalNeonWhite;
}
if (countFrameNeon < totalFrames)
{
countFrameNeon++;
r = map(countFrameNeon*255./totalFrames, 0, 255, startRed, endRed);
g = map(countFrameNeon*255./totalFrames, 0, 255, startGreen, endGreen);
b = map(countFrameNeon*255./totalFrames, 0, 255, startBlue, endBlue);
w = map(countFrameNeon*255./totalFrames, 0, 255, startWhite, endWhite);
// Serial.println("----------------------");
// Serial.print("startBlue: ");
// Serial.print(startBlue);
// Serial.print(" endBlue: ");
// Serial.println(endBlue);
// Serial.println(countFrameNeon*255./totalFrames);
// Serial.println(b);
globalNeonRed = r;
globalNeonGreen = g;
globalNeonBlue = b;
globalNeonWhite = w;
analogWrite(RED, r);
analogWrite(GREEN, g);
analogWrite(BLUE, b);
analogWrite(WHITE, b); // azul replicado en salida de blanco por placa estropeada
}
}
}
void stroboNeon(uint32_t color, int stroboTime, int stroboPwm, int numFlash)
{
// countFrameNeon = 0;
if ( millis() > delayedNeon )
{
byte endRed = red(color);
byte endGreen = green(color);
byte endBlue = blue(color);
byte endWhite = white(color);
if(endWhite){ // si llega blanco configurar como natura white calibrado
endRed = 255;
endGreen = 120;
endBlue = 40;
endWhite = 40; // solo en PCB con salida azul estropeada
}
if (!neonFlag)
{
countFrameNeon = 0;
stroboFlagNeon = 0;
stroboNeonOn = true;
neonFlag = true;
#if DEBUG
Serial.println("---NEON STROBO---");
Serial.print("strobo Period: ");
Serial.println(stroboTime);
Serial.print("PWM: ");
Serial.println(stroboPwm);
Serial.print("Flashes: ");
Serial.println(numFlash);
#endif
}
if (stroboNeonOn)
{
if ( !stroboFlagNeon )
{
delayedNeon = millis() + (stroboTime * stroboPwm / 100);
analogWrite(RED, endRed);
analogWrite(GREEN, endGreen);
analogWrite(BLUE, endBlue);
analogWrite(WHITE, endBlue); // solo para arreglar la placa estropeada, azul replicado
stroboFlagNeon = 1;
globalNeonRed = endRed;
globalNeonGreen = endGreen;
globalNeonBlue = endBlue;
globalNeonWhite = endWhite;
//.println("Strobo_ON");
}
else
{
delayedNeon = millis() + (stroboTime * (100 - stroboPwm) / 100);
analogWrite(RED, 0);
analogWrite(GREEN, 0);
analogWrite(BLUE, 0);
analogWrite(WHITE, 0);
//Serial.println("Strobo_OFF");
globalNeonRed = 0;
globalNeonGreen = 0;
globalNeonBlue = 0;
globalNeonWhite = 0;
countFrameNeon++;
if (countFrameNeon < numFlash)
stroboFlagNeon = 0; // otro flash mas!
else
{
stroboFlagNeon = 1; // stop flash
stroboNeonOn = false; // stop neon
}
}
}
}
}
//////////////////////////////////////////////////////////////////
//////////////// PIXEL BASIC FUNCIONS //////////////////
//////////////////////////////////////////////////////////////////
uint8_t white(uint32_t c) {
return (c >> 24);
}
uint8_t red(uint32_t c) {
return (c >> 16);
}
uint8_t green(uint32_t c) {
return (c >> 8);
}
uint8_t blue(uint32_t c) {
return (c);
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t hueWeel(byte wheelPos)
{
if (wheelPos == 255)
return pixels1.Color(0, 0, 0, 255); // caso especial BLANCO
else
{
wheelPos = 255 - wheelPos;
if (wheelPos < 85) {
return pixels1.Color(255 - wheelPos * 3, 0, wheelPos * 3, 0);
}
if (wheelPos < 170) {
wheelPos -= 85;
return pixels1.Color(0, wheelPos * 3, 255 - wheelPos * 3, 0);
}
wheelPos -= 170;
return pixels1.Color(wheelPos * 3, 255 - wheelPos * 3, 0, 0);
}
}
void splitStrip()
{
// CONVERSION DE UNA ANIMACION DE 5M A DOS TRAMOS
for ( int i = 0; i < 150 ; i++) // numPixels/2
{
pixels2.setPixelColor( i, pixels1.getPixelColor(i) );
pixels3.setPixelColor( i, pixels1.getPixelColor(i + 150) );
}
}
void showStrip()
{
//pixels1.show(); // tira entera de 5m
pixels2.show(); // parte 1 de 2.5m
pixels3.show(); // parte 2 de 2.5m
}
void setPixel(int Pixel, byte red, byte green, byte blue, byte white)
{
pixels1.setPixelColor(Pixel, pixels1.Color(red, green, blue, white));
}
void setAll(byte red, byte green, byte blue, byte white)
{
for (int i = 0; i < NUMPIXELS1; i++ ) {
setPixel(i, red, green, blue, white);
}
}
void fadeToBlack(int ledNo, byte fadeValue)
{
uint32_t oldColor;
uint8_t r, g, b, w;
int value;
oldColor = pixels1.getPixelColor(ledNo);
w = (oldColor & 0xff000000UL) >> 24;
r = (oldColor & 0x00ff0000UL) >> 16;
g = (oldColor & 0x0000ff00UL) >> 8;
b = (oldColor & 0x000000ffUL);
r=(r<=10)? 0 : (int) r-(r*fadeValue/256);
g=(g<=10)? 0 : (int) g-(g*fadeValue/256);
b=(b<=10)? 0 : (int) b-(b*fadeValue/256);
w=(w<=10)? 0 : (int) w-(w*fadeValue/256);
pixels1.setPixelColor(ledNo, r,g,b,w);
}
//////////////////////////////////////////////////////////////////
/////////////////////// PIXEL FADE //////////////////////
//////////////////////////////////////////////////////////////////
void fadeOutRandom(int fadeTime, int fadeRandomDecay, int fadeTrailDecay, int frameTime) // usar fade to black para desaparecer a negro
{
float r, g, b, w;
float totalFrames = fadeTime / frameTime;
#if DEBUG
if (!pixelFlag)
{
#if DEBUG
launchTime = millis();
Serial.println("---FADE OUT RANDOM---");
Serial.print("fadeTime: ");
Serial.println(fadeTime);
Serial.print("LaunchTime: ");
Serial.println(launchTime);
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
countFrame = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
pixelFlag = true;
}
#endif
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11;
for (int j = 0; j < NUMPIXELS1; j++)
{
if( (!fadeRandomDecay) || (random(10)>5) )
{
fadeToBlack(j, fadeTrailDecay );
}
}
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
}
void colorBrightness(uint32_t color , int value, int syncNeon, int frameTime)
{
#if DEBUG
if (!pixelFlag)
{
launchTime = millis();
Serial.println("---COLOR BRIGHTNESS---");
Serial.print("Brightness: ");
Serial.println(value);
pixelFlag = true;
}
#endif
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11;
uint8_t r, g, b, w;
//r = map(countFrameNeon*255./totalFrames, 0, 255, startRed, endRed);
r = red(color)*value/255.;
g = green(color)*value/255.;
b = blue(color)*value/255.;
w = white(color)*value/255.;
setAll(r, g, b, w);
splitStrip();
showStrip(); // para millis() durante 4.5 ms
if (syncNeon)
{
if(w){ // si llega blanco configurar como natura white calibrado
r = 255;
g = 120;
b = 40;
w = 40; // solo en PCB con salida azul estropeada
}
analogWrite(RED, r);
analogWrite(GREEN, g);
analogWrite(BLUE, b);
analogWrite(WHITE, b); // parche para el azul que no funciona
}
}
}
//void fadePixel(byte red, byte green, byte blue, byte white, int mode, int fadeTime, int frameTime) // mode 0 = fadeIn, mode 1 = fadeOut
void fadePixel(uint32_t color, int mode, int fadeTime, int frameTime) // mode 0 = fadeIn, mode 1 = fadeOut
{
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11 ; // compensacion de bloqueo de millis
float r, g, b, w;
float totalFrames = fadeTime / frameTime;
byte endRed = red(color);
byte endGreen = green(color);
byte endBlue = blue(color);
byte endWhite = white(color);
if (!pixelFlag)
{
#if DEBUG
launchTime = millis();
if (!mode)
Serial.println("---FADEIN---");
else
Serial.println("---FADEOUT---");
Serial.print("fadeTime: ");
Serial.println(fadeTime);
Serial.print("LaunchTime: ");
Serial.println(launchTime);
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
countFrame = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
pixelFlag = true;
}
//Serial.print("Time: ");
//Serial.println( millis() - launchTime );
//if (millis() - launchTime < inTime)
if (countFrame < totalFrames)
{
countFrame++;
pixelOn = true;
if (!mode) // FADE IN
{
// r = neopix_gamma[(byte)(red*countFrame / totalFrames)];
// g = neopix_gamma[(byte)(green*countFrame / totalFrames)];
// b = neopix_gamma[(byte)(blue*countFrame / totalFrames)];
// w = neopix_gamma[(byte)(white*countFrame / totalFrames)];
r = neopix_gamma[(byte)(255.*countFrame / totalFrames)]*endRed/255.;
g = neopix_gamma[(byte)(255.*countFrame / totalFrames)]*endGreen/255.;
b = neopix_gamma[(byte)(255.*countFrame / totalFrames)]*endBlue/255.;
w = neopix_gamma[(byte)(255.*countFrame / totalFrames)]*endWhite/255.;
}
else
{
r = neopix_gamma[(byte)(255.*(totalFrames - countFrame) / totalFrames)]*endRed/255.;
g = neopix_gamma[(byte)(255.*(totalFrames - countFrame) / totalFrames)]*endGreen/255.;
b = neopix_gamma[(byte)(255.*(totalFrames - countFrame) / totalFrames)]*endBlue/255;
w = neopix_gamma[(byte)(255.*(totalFrames - countFrame) / totalFrames)]*endWhite/255.;
}
//Serial.println(w);
setAll(r, g, b, w);
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
else
pixelOn = false; // flag para que el NEON sepa cuando hay una funcion de pixel simultanea
}
}
void fadePixelRainbow(uint32_t initColor, uint32_t endColor, int mode, int fadeTime, int frameTime) // mode 0 = fadeIn, mode 1 = fadeOut
{
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11 ; // compensacion de bloqueo de millis
uint8_t r, g, b, w;
float totalFrames = fadeTime / frameTime;
byte endRed = red(endColor);
byte endGreen = green(endColor);
byte endBlue = blue(endColor);
byte endWhite = white(endColor);
byte initRed = red(initColor);
byte initGreen = green(initColor);
byte initBlue = blue(initColor);
byte initWhite = white(initColor);
if (!pixelFlag)
{
#if DEBUG
launchTime = millis();
if (!mode)
Serial.println("---FADEIN RAINBOW---");
else
Serial.println("---FADEOUT RAINBOW---");
Serial.print("fadeTime: ");
Serial.println(fadeTime);
Serial.print("LaunchTime: ");
Serial.println(launchTime);
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
countFrame = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
pixelFlag = true;
incRed = (endRed-initRed)/300.;
incGreen = (endGreen-initGreen)/300.;
incBlue = (endBlue-initBlue)/300.;
incWhite = (endWhite-initWhite)/300.;
}
if (countFrame < totalFrames)
{
countFrame++;
pixelOn = true;
if (!mode) // FADE IN
{
for ( int i = 0; i < NUMPIXELS1 ; i++)
{
// redTemp = initRed + incRed*i;
// greenTemp = initGreen + incGreen*i;
// blueTemp = initBlue + incBlue*i;
// whiteTemp = initWhite + incWhite*i;
r = (countFrame / totalFrames) * (initRed + incRed*i) ;
g = (countFrame / totalFrames) * (initGreen + incGreen*i);
b = (countFrame / totalFrames) * (initBlue + incBlue*i);
w = (countFrame / totalFrames) * (initWhite + incWhite*i);
//r = neopix_gamma[(byte)(redTemp*countFrame/totalFrames)];
//g = neopix_gamma[(byte)(greenTemp*countFrame/totalFrames)];
//b = neopix_gamma[(byte)(blueTemp*countFrame/totalFrames)];
//w = neopix_gamma[(byte)(whiteTemp*countFrame/totalFrames)];
setPixel(i, r, g, b, w); // white is saturation
}
}
else
{
for ( int i = 0; i < NUMPIXELS1 ; i++)
{
// redTemp = initRed + incRed*i;
// greenTemp = initGreen + incGreen*i;
// blueTemp = initBlue + incBlue*i;
// whiteTemp = initWhite + incWhite*i;
r = ((totalFrames - countFrame) / totalFrames) * (initRed + incRed*i) ;
g = ((totalFrames - countFrame) / totalFrames) * (initGreen + incGreen*i) ;
b = ((totalFrames - countFrame) / totalFrames) * (initBlue + incBlue*i) ;
w = ((totalFrames - countFrame) / totalFrames) * (initWhite + incWhite*i);
setPixel(i, r, g, b, w); // white is saturation
}
// r = neopix_gamma[(int)(255.*(totalFrames - countFrame) / totalFrames)] * red / 255;
// g = neopix_gamma[(int)(255.*(totalFrames - countFrame) / totalFrames)] * green / 255;
// b = neopix_gamma[(int)(255.*(totalFrames - countFrame) / totalFrames)] * blue / 255;
// w = neopix_gamma[(int)(255.*(totalFrames - countFrame) / totalFrames)] * white / 255;
}
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
else
pixelOn = false; // flag para que el NEON sepa cuando hay una funcion de pixel simultanea
}
}
void fadePixelColor(uint32_t color, int fadeTime, int frameTime) // conversion pixel a pixel desde el getpixelcolor
//void fadePixelColor(byte red, byte green, byte blue, byte, white, int fadeTime, int frameTime) // conversion pixel a pixel desde el getpixelcolor
{
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11; // compensacion de bloqueo de millis
int r, g, b, w;
float totalFrames = fadeTime / frameTime;
static uint32_t colorRead[NUMPIXELS1];
static float colorRedTemp[NUMPIXELS1];
static float colorGreenTemp[NUMPIXELS1];
static float colorBlueTemp[NUMPIXELS1];
static float colorWhiteTemp[NUMPIXELS1];
static float colorIncRed[NUMPIXELS1]; // int porque puede ser positivo o negativo el incremento
static float colorIncGreen[NUMPIXELS1];
static float colorIncBlue[NUMPIXELS1];
static float colorIncWhite[NUMPIXELS1];
byte endRed = red(color);
byte endGreen = green(color);
byte endBlue = blue(color);
byte endWhite = white(color);
if (!pixelFlag)
{
#if DEBUG
launchTime = millis();
Serial.println("---FADECOLOR---");
Serial.print("fadeTime: ");
Serial.println(fadeTime);
Serial.print("LaunchTime: ");
Serial.println(launchTime);
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
for ( int i = 0; i < NUMPIXELS1 ; i++)
{
colorRead[i] = pixels1.getPixelColor(i);
//endRed = red(hueWeel(hueDest));
//endGreen = green(hueWeel(hueDest));
//endBlue = blue(hueWeel(hueDest));
colorIncRed[i] = (endRed-red(colorRead[i]))/totalFrames; // ojo, puede ser positivo o negativo!!!!!
colorIncGreen[i] = (endGreen-green(colorRead[i]))/totalFrames;
colorIncBlue[i] = (endBlue-blue(colorRead[i]))/totalFrames;
colorIncWhite[i] = (endWhite-white(colorRead[i]))/totalFrames;
colorRedTemp[i] = red(colorRead[i]);
colorGreenTemp[i] = green(colorRead[i]);
colorBlueTemp[i] = blue(colorRead[i]);
colorWhiteTemp[i] = white(colorRead[i]);
}
countFrame = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
pixelFlag = true;
}
//Serial.print("tiempo despues de init: ");
//Serial.println(millis()-launchTime);
if (countFrame < totalFrames)
{
countFrame++;
pixelOn = true; // flag para que el NEON sepa cuando hay una funcion de pixel simultanea
for ( int i = 0; i < NUMPIXELS1 ; i++)
{
//colorRedTemp[i] = map(countFrame*255./totalFrames, 0, 255, red(colorRead[i]), endRed);
colorRedTemp[i] = colorRedTemp[i] + colorIncRed[i];
//colorGreenTemp[i] = map(countFrame*255./totalFrames, 0, 255, green(colorRead[i]), endGreen);
colorGreenTemp[i] = colorGreenTemp[i] + colorIncGreen[i];
//colorBlueTemp[i] = map(countFrame*255./totalFrames, 0, 255, blue(colorRead[i]), endBlue);
colorBlueTemp[i] = colorBlueTemp[i] + colorIncBlue[i];
colorWhiteTemp[i] = colorWhiteTemp[i] + colorIncWhite[i];
//setPixel(i, colorRedTemp[i], colorGreenTemp[i], colorBlueTemp[i], 0); // white is saturation
setPixel(i, (byte)colorRedTemp[i], (byte)colorGreenTemp[i], (byte)colorBlueTemp[i], colorWhiteTemp[i]); // white is saturation
}
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
else
pixelOn = false; // flag para que el NEON sepa cuando hay una funcion de pixel simultanea
}
}
//////////////////////////////////////////////////////////////////
/////////////////////// PIXEL BAR //////////////////////
//////////////////////////////////////////////////////////////////
void pixelBar(uint32_t color, int pixelInit, int pixelEnd, int loopTime, int frameTime)
{
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11;
int pixelPos = 0;
float r, g, b, w;
float totalFrames = loopTime / frameTime;
byte endRed = red(color);
byte endGreen = green(color);
byte endBlue = blue(color);
byte endWhite = white(color);
if (!pixelFlag)
{
#if DEBUG
launchTime = millis();
Serial.println("---PIXELBAR---");
Serial.print("loopTime: ");
Serial.println(loopTime);
Serial.print("LaunchTime: ");
Serial.println(launchTime);
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
countFrame = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
pixelFlag = true;
}
//Serial.print("Time: ");
//Serial.println( millis() - launchTime );
//if (millis() - launchTime < inTime)
if (countFrame < totalFrames)
{
countFrame++;
pixelOn = true;
if (pixelInit < pixelEnd) // SENTIDO UP
{
pixelPos = pixelInit + (1 - (totalFrames - countFrame) / totalFrames) * (pixelEnd - pixelInit);
for ( int i = pixelInit; i < pixelPos ; i++)
setPixel(i, endRed, endGreen, endBlue, endWhite);
}
else // SENTIDO DOWN
{
pixelPos = pixelInit - (1 - (totalFrames - countFrame) / totalFrames) * (pixelInit - pixelEnd);
for ( int i = pixelInit; i >= pixelPos ; i--)
setPixel(i, endRed, endGreen, endBlue, endWhite);
}
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
else
pixelOn = false; // flag para que el NEON sepa cuando hay una funcion de pixel simultanea
}
}
//////////////////////////////////////////////////////////////////
/////////////////////// SCANNER /////////////////////
//////////////////////////////////////////////////////////////////
void scanner(uint32_t color, int mode, int pixelInit, int pixelEnd, int pixelWidth, int loopTime, int frameTime) // MODE 0 = BAR, MODE 1 = BARRIDO SCAN
{
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11;
int pixelPos;
float r, g, b, w;
float totalFrames = loopTime / frameTime;
byte endRed = red(color);
byte endGreen = green(color);
byte endBlue = blue(color);
byte endWhite = white(color);
if (!pixelFlag)
{
#if DEBUG
launchTime = millis();
Serial.println("---PIXEL SCANNER---");
Serial.print("loopTime: ");
Serial.println(loopTime);
Serial.print("LaunchTime: ");
Serial.println(launchTime);
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
countFrame = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
pixelFlag = true;
}
if (countFrame < totalFrames)
{
countFrame++;
pixelOn = true;
if (pixelInit < pixelEnd) // SENTIDO UP
{
pixelPos = pixelInit + (1 - (totalFrames - countFrame) / totalFrames) * (pixelEnd - pixelInit);
if(!mode) // si es modo es 0, no se borra. PixelBAR
setAll(0, 0, 0, 0);
for ( int i = pixelPos - (pixelWidth / 2); i < pixelPos + (pixelWidth / 2) ; i++)
setPixel(i, endRed, endGreen, endBlue, endWhite);
}
else // SENTIDO DOWN
{
pixelPos = pixelInit - (1 - (totalFrames - countFrame) / totalFrames) * (pixelInit - pixelEnd);
if(!mode) // si es modo es 0, no se borra. PixelBAR
setAll(0, 0, 0, 0);
for ( int i = pixelPos - (pixelWidth / 2); i < pixelPos + (pixelWidth / 2) ; i++)
setPixel(i, endRed, endGreen, endBlue, endWhite);
}
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
else
pixelOn = false; // flag para que el NEON sepa cuando hay una funcion de pixel simultanea
}
}
//////////////////////////////////////////////////////////////////
/////////////////////// METEORITO ////////////////////
//////////////////////////////////////////////////////////////////
void meteorRain(uint32_t color, boolean meteorRandomDecay, byte meteorTrailDecay, int pixelInit, int pixelEnd, int pixelWidth, int loopTime, int frameTime)
{
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11;
int pixelPos;
float r, g, b, w;
float totalFrames = loopTime / frameTime;
byte endRed = red(color);
byte endGreen = green(color);
byte endBlue = blue(color);
byte endWhite = white(color);
if (!pixelFlag)
{
#if DEBUG
launchTime = millis();
Serial.println("---METEOR---");
Serial.print("loopTime: ");
Serial.println(loopTime);
Serial.print("LaunchTime: ");
Serial.println(launchTime);
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
countFrame = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
pixelFlag = true;
setAll(0, 0, 0, 0);
}
for (int j = 0; j < NUMPIXELS1; j++)
{
if( (!meteorRandomDecay) || (random(10)>5) )
{
fadeToBlack(j, meteorTrailDecay );
}
}
if (countFrame < totalFrames)
{
countFrame++;
pixelOn = true;
if (pixelInit < pixelEnd) // SENTIDO UP
{
pixelPos = pixelInit + (1 - (totalFrames - countFrame) / totalFrames) * (pixelEnd - pixelInit);
for ( int i = pixelPos - (pixelWidth / 2); i < pixelPos + (pixelWidth / 2) ; i++)
setPixel(i, endRed, endGreen, endBlue, endWhite);
}
else
{
pixelPos = pixelInit - (1 - (totalFrames - countFrame) / totalFrames) * (pixelInit - pixelEnd);
for ( int i = pixelPos - (pixelWidth / 2); i < pixelPos + (pixelWidth / 2) ; i++)
setPixel(i, endRed, endGreen, endBlue, endWhite);
}
}
else
pixelOn = false; // flag para que el NEON sepa cuando hay una funcion de pixel simultanea
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
}
//////////////////////////////////////////////////////////////////
/////////////////////// CENTER TO OUT ////////////////////
//////////////////////////////////////////////////////////////////
void centerToOut(uint32_t color, int mode, int pixelWidth, int loopTime, int frameTime) // mode define si es solido o scanner
{
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11;
int pixelPos;
float r, g, b, w;
float totalFrames = loopTime / frameTime;
byte endRed = red(color);
byte endGreen = green(color);
byte endBlue = blue(color);
byte endWhite = white(color);
if (!pixelFlag)
{
#if DEBUG
launchTime = millis();
Serial.println("---CENTER TO OUT---");
Serial.print("loopTime: ");
Serial.println(loopTime);
Serial.print("LaunchTime: ");
Serial.println(launchTime);
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
countFrame = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
pixelFlag = true;
setAll(0, 0, 0, 0);
}
if (countFrame < totalFrames)
{
countFrame++;
pixelOn = true;
//pixelPos = pixelInit + (1 - (totalFrames - countFrame) / totalFrames) * (pixelEnd - pixelInit);
if(!mode)
setAll(0, 0, 0, 0);
pixelPos = NUMPIXELS1/2 + (1 - (totalFrames - countFrame) / totalFrames) * NUMPIXELS1/2;
for ( int i = pixelPos - (pixelWidth / 2); i < pixelPos + (pixelWidth / 2) ; i++)
setPixel(i, endRed, endGreen, endBlue, endWhite);
pixelPos = ((totalFrames - countFrame) / totalFrames) * NUMPIXELS1/2;
for ( int i = pixelPos - (pixelWidth / 2); i < pixelPos + (pixelWidth / 2) ; i++)
setPixel(i, endRed, endGreen, endBlue, endWhite);
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
else
{
if(!mode)
{
setAll(0, 0, 0, 0);
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
pixelOn = false;
}
}
}
//////////////////////////////////////////////////////////////////
/////////////////////// OUT TO CENTER ////////////////////
//////////////////////////////////////////////////////////////////
void outToCenter(uint32_t color, int mode, int pixelWidth, int loopTime, int frameTime) // mode define si es solido o scanner
{
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11;
int pixelPos;
float r, g, b, w;
float totalFrames = loopTime / frameTime;
byte endRed = red(color);
byte endGreen = green(color);
byte endBlue = blue(color);
byte endWhite = white(color);
if (!pixelFlag)
{
#if DEBUG
launchTime = millis();
Serial.println("---OUT TO CENTER---");
Serial.print("loopTime: ");
Serial.println(loopTime);
Serial.print("LaunchTime: ");
Serial.println(launchTime);
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
countFrame = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
pixelFlag = true;
setAll(0, 0, 0, 0);
}
if (countFrame < totalFrames)
{
countFrame++;
pixelOn = true;
//pixelPos = pixelInit + (1 - (totalFrames - countFrame) / totalFrames) * (pixelEnd - pixelInit);
if(!mode)
setAll(0, 0, 0, 0);
pixelPos = NUMPIXELS1 - (1 - (totalFrames - countFrame) / totalFrames) * NUMPIXELS1/2;
for ( int i = pixelPos - (pixelWidth / 2); i < pixelPos + (pixelWidth / 2) ; i++)
setPixel(i, endRed, endGreen, endBlue, endWhite);
pixelPos = (1 - (totalFrames - countFrame) / totalFrames) * NUMPIXELS1/2;
for ( int i = pixelPos - (pixelWidth / 2); i < pixelPos + (pixelWidth / 2) ; i++)
setPixel(i, endRed, endGreen, endBlue, endWhite);
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
else
{
if(!mode)
{
setAll(0, 0, 0, 0);
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
pixelOn = false;
}
}
}
//////////////////////////////////////////////////////////////////
/////////////////////// PIXEL STROBO ////////////////////
//////////////////////////////////////////////////////////////////
void stroboPixel(uint32_t color, int stroboTime, int stroboPwm, int numFlash, bool syncNeon)
{
if ( millis() > delayed )
{
byte endRed = red(color);
byte endGreen = green(color);
byte endBlue = blue(color);
byte endWhite = white(color);
if (!pixelFlag)
{
countFrame = 0;
stroboPixelFlag = 0;
stroboPixelOn = true;
pixelFlag = true;
#if DEBUG
Serial.println("---PIXEL STROBO---");
Serial.print("strobo Period: ");
Serial.println(stroboTime);
Serial.print("PWM: ");
Serial.println(stroboPwm);
Serial.print("Flashes: ");
Serial.println(numFlash);
#endif
}
if (stroboPixelOn)
{
if ( !stroboPixelFlag )
{
delayed = millis() + (stroboTime * stroboPwm / 100) - 11 ; // 11ms de compensacion del showstrip
stroboPixelFlag = 1;
setAll(endRed, endGreen, endBlue, endWhite);
splitStrip();
showStrip();
if (syncNeon)
{
if(endWhite){ // si llega blanco configurar como natura white calibrado
endRed = 255;
endGreen = 120;
endBlue = 40;
endWhite = 40; // solo en PCB con salida azul estropeada
}
analogWrite(RED, endRed);
analogWrite(GREEN, endGreen);
analogWrite(BLUE, endBlue);
analogWrite(WHITE, endBlue); // parche para el neon estropeado
}
}
else
{
delayed = millis() + (stroboTime * (100 - stroboPwm) / 100) - 11 ; // 11ms de compensacion del showstrip
setAll(0, 0, 0, 0);
splitStrip();
showStrip();
if (syncNeon)
{
analogWrite(RED, 0);
analogWrite(GREEN, 0);
analogWrite(BLUE, 0);
analogWrite(WHITE, 0);
}
countFrame++;
if (countFrame < numFlash)
stroboPixelFlag = 0; // otro flash mas!
else
{
stroboPixelFlag = 1; // stop flash
stroboPixelOn = false; // stop neon
}
}
}
}
}
void stroboRandomColor(int stroboTime, int stroboPwm, int numFlash, int syncNeon)
{
if (!pixelFlag)
{
countFrame = 0;
stroboPixelFlag = 0;
stroboPixelOn = true;
pixelFlag = true;
#if DEBUG
Serial.println("---PIXEL STROBO---");
Serial.print("strobo Period: ");
Serial.println(stroboTime);
Serial.print("PWM: ");
Serial.println(stroboPwm);
Serial.print("Flashes: ");
Serial.println(numFlash);
#endif
}
if ( millis() > delayed )
{
if (stroboPixelOn)
{
if ( !stroboPixelFlag )
{
delayed = millis() + (stroboTime * stroboPwm / 100) - 11 ; // 11ms de compensacion del showstrip
stroboPixelFlag = 1;
int hueRandom = random(255);
for(int i=0; i < NUMPIXELS1 ; i++)
setPixel(i, red(hueWeel(hueRandom)), green(hueWeel(hueRandom)), blue(hueWeel(hueRandom)), 0 ) ;
splitStrip();
showStrip();
if (syncNeon)
{
analogWrite(RED, red(hueWeel(hueRandom)));
analogWrite(GREEN, green(hueWeel(hueRandom)));
analogWrite(BLUE, blue(hueWeel(hueRandom)));
analogWrite(WHITE, blue(hueWeel(hueRandom))); // canal estropeado
}
}
else
{
delayed = millis() + (stroboTime * (100 - stroboPwm) / 100) - 11 ; // 11ms de compensacion del showstrip
setAll(0, 0, 0, 0);
splitStrip();
showStrip();
if (syncNeon)
{
analogWrite(RED, 0);
analogWrite(GREEN, 0);
analogWrite(BLUE, 0);
analogWrite(WHITE, 0);
}
countFrame++;
if (countFrame < numFlash)
stroboPixelFlag = 0; // otro flash mas!
else
{
stroboPixelFlag = 1; // stop flash
stroboPixelOn = false; // stop neon
}
}
}
}
}
//////////////////////////////////////////////////////////////////
/////////////////////// PIXEL FIRE //////////////////////
//////////////////////////////////////////////////////////////////
void fire(int Cooling, int Sparking, int mode, int frameTime)
{
#if DEBUG
if (!pixelFlag)
{
pixelFlag = true;
Serial.println("---FIRE---");
Serial.print("Cooling: ");
Serial.println(Cooling);
Serial.print("Sparking: ");
Serial.println(Sparking);
}
#endif
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11 ; // 11ms de compensacion del showstrip
static byte heat[NUMPIXELS1];
int cooldown;
// Step 1. Cool down every cell a little
for ( int i = 0; i < NUMPIXELS1 ; i++) {
cooldown = random(0, ((Cooling * 10) / NUMPIXELS1) + 2);
if (cooldown > heat[i]) {
heat[i] = 0;
} else {
heat[i] = heat[i] - cooldown;
}
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for ( int k = NUMPIXELS1 - 1; k >= 2; k--) {
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
}
// Step 3. Randomly ignite new 'sparks' near the bottom
if ( random(255) < Sparking ) {
int y = random(7);
heat[y] = heat[y] + random(160, 255);
//heat[y] = random(160,255);
}
// Step 4. Convert heat to LED colors
if( !mode)
{
for ( int j = 0; j < NUMPIXELS1; j++) {
setPixelHeatColor(j, heat[j] );
}
}
else // INVERSION DE ARRAY PARA MODO INVERTIDO DE TUBO
{
for ( int j = 0; j < NUMPIXELS1; j++) {
setPixelHeatColor(NUMPIXELS1-j-1, heat[j] );
}
}
// INVERSION DE ARRAY PARA MODO INVERTIDO DE TUBO
//for(int i=0; i<300 ; i++)
// {
// //pixels1.setPixelColor( i, pixels1.getPixelColor(300-i) );
// }
splitStrip();
showStrip();
}
}
void setPixelHeatColor (int Pixel, byte temperature)
{
// Scale 'heat' down from 0-255 to 0-191
byte t192 = round((temperature / 255.0) * 191);
// calculate ramp up from
byte heatramp = t192 & 0x3F; // 0..63
heatramp <<= 2; // scale up to 0..252
// figure out which third of the spectrum we're in:
if ( t192 > 0x80) { // hottest
setPixel(Pixel, 255, 255, heatramp, 0);
} else if ( t192 > 0x40 ) { // middle
setPixel(Pixel, 255, heatramp, 0, 0);
} else { // coolest
setPixel(Pixel, heatramp, 0, 0, 0);
}
}
//////////////////////////////////////////////////////////////////
/////////////////////// RANDOMS PIXEL ///////////////////
//////////////////////////////////////////////////////////////////
void randomPixel(uint32_t color, int totalFrames, int frameTime, int density, boolean onlyOne) {
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11;
byte endRed = red(color);
byte endGreen = green(color);
byte endBlue = blue(color);
byte endWhite = white(color);
if (!pixelFlag)
{
#if DEBUG
Serial.println("---RANDOM PIXEL---");
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
countFrame = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
pixelFlag = true;
setAll(0, 0, 0, 0);
}
if (countFrame < totalFrames)
{
countFrame++;
pixelOn = true;
for(int i=0; i < density ; i++)
setPixel(random(NUMPIXELS1), endRed, endGreen, endBlue, endWhite);
splitStrip();
showStrip(); // para millis() durante 4.5 ms
if(!onlyOne)
setAll(0, 0, 0, 0);
}
else{
setAll(0, 0, 0, 0);
pixelOn = false;
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
}
}
void randomInvert(uint32_t color, int size, int totalFrames, int frameTime, int density, boolean onlyOne) {
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11;
byte endRed = red(color);
byte endGreen = green(color);
byte endBlue = blue(color);
byte endWhite = white(color);
if (!pixelFlag)
{
#if DEBUG
Serial.println("---RANDOM INVERT---");
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
countFrame = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
pixelFlag = true;
setAll(endRed, endGreen, endBlue, endWhite);
}
if (countFrame < totalFrames)
{
countFrame++;
pixelOn = true;
for(int i=0; i < density ; i++){
int pixelRandom = random(NUMPIXELS1);
for(int j=0; j<size ; j++)
setPixel(pixelRandom+j, 0, 0, 0, 0);
}
splitStrip();
showStrip(); // para millis() durante 4.5 ms
if(!onlyOne)
setAll(endRed, endGreen, endBlue, endWhite);
}
else{
setAll(0, 0, 0, 0);
pixelOn = false;
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
}
}
void randomColor( int totalFrames, int frameTime ) {
if ( millis() > delayed )
{
delayed = millis() + frameTime - 11;
if (!pixelFlag)
{
#if DEBUG
Serial.println("---RANDOM COLOR---");
Serial.print("totalFrames: ");
Serial.println(totalFrames);
#endif
countFrame = 0; // RESET DE VARIABLES ANTES DE ARRANCAR
pixelFlag = true;
setAll(0, 0, 0, 0);
}
if (countFrame < totalFrames)
{
countFrame++;
pixelOn = true;
int hueRandom = random(255);
for(int i=0; i < NUMPIXELS1 ; i++)
setPixel(i, red(hueWeel(hueRandom)), green(hueWeel(hueRandom)), blue(hueWeel(hueRandom)), 0 ) ;
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
else{
setAll(0, 0, 0, 0);
pixelOn = false;
splitStrip();
showStrip(); // para millis() durante 4.5 ms
}
}
}
// void SnowSparkle(byte red, byte green, byte blue, byte white, int SparkleDelay, int SpeedDelay) {
// setAll(red, green, blue, white);
// int Pixel = random(NUMPIXELS1);
// setPixel(Pixel, 0xff, 0xff, 0xff, 0xff);
// showStrip();
// delay(SparkleDelay);
// setPixel(Pixel, red, green, blue, white);
// showStrip();
// delay(SpeedDelay);
// }
// void RunningLights(byte red, byte green, byte blue, byte white, int WaveDelay) {
// int Position = 0;
// for (int i = 0; i < NUMPIXELS1 * 2; i++)
// {
// Position++; // = 0; //Position + Rate;
// for (int i = 0; i < NUMPIXELS1; i++)
// {
// // sine wave, 3 offset waves make a rainbow!
// //float level = sin(i+Position) * 127 + 128;
// //setPixel(i,level,0,0);
// //float level = sin(i+Position) * 127 + 128;
// setPixel(i, ((sin(i + Position) * 127 + 128) / 255)*red,
// ((sin(i + Position) * 127 + 128) / 255)*green,
// ((sin(i + Position) * 127 + 128) / 255)*blue,
// ((sin(i + Position) * 127 + 128) / 255)*white);
// }
// showStrip();
// delay(WaveDelay);
// }
// }
// void rainbowCycle(int SpeedDelay) {
// byte *c;
// uint16_t i, j;
// for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
// for(i=0; i< NUMPIXELS1; i++) {
// c=Wheel(((i * 256 / NUMPIXELS1) + j) & 255);
// setPixel(i, *c, *(c+1), *(c+2), 0);
// }
// showStrip();
// delay(SpeedDelay);
// }
// }
// void theaterChase(byte red, byte green, byte blue, byte white, int SpeedDelay) {
// for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
// for (int q = 0; q < 3; q++) {
// for (int i = 0; i < NUMPIXELS1; i = i + 3) {
// setPixel(i + q, red, green, blue, white); //turn every third pixel on
// }
// showStrip();
// delay(SpeedDelay);
// for (int i = 0; i < NUMPIXELS1; i = i + 3) {
// setPixel(i + q, 0, 0, 0, 0); //turn every third pixel off
// }
// }
// }
// }
// void theaterChaseRainbow(int SpeedDelay) {
// uint32_t c;
// for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
// for (int q=0; q < 3; q++) {
// for (int i=0; i < NUMPIXELS1; i=i+3) {
// c = wheel( (i+j) % 255);
// setPixel(i+q, c, (c+1), (c+2),0); //turn every third pixel on
// }
// showStrip();
// delay(SpeedDelay);
// for (int i=0; i < NUMPIXELS1; i=i+3) {
// setPixel(i+q, 0,0,0,0); //turn every third pixel off
// }
// }
// }
// }