Lab_interaccio/2018/LLAC-RGBW-varios/NEOPIXEL/Fire/Fire.ino

515 lines
12 KiB
Arduino
Raw Permalink Normal View History

2025-02-25 21:29:42 +01:00
#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 1
#define TEST 1
#define RED 11
#define GREEN 10
#define BLUE 9
#define WHITE 6
#define SDO1 8
#define SDO2 4
#define SDO3 3
#define NUMPIXELS1 300 // fuego
#define NUMPIXELS2 150
#define NUMPIXELS3 150
int idpin[4] = { A3, A4, 13, 5}; // A partir de 1 SLAVES
int chpin[4] = { A5, A0, A1, A2 }; // 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);
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
const uint64_t pipe = 0xE8E8F0F0E1LL; // Define the transmit pipe
uint8_t CMD[ 4 ]; // CMD + Ch + 2
int ch = 76; // Fuerzo a canal 76 (showroom)
unsigned long delayed=0;
short stroboFlag = 0;
uint8_t param1=20;
uint8_t param2=140;
uint8_t mode = 0; // Modo OFF/TEST por defecto
uint8_t i = 0;
// Modo 1: FUEGO
// Modo 2: PixelPoint
// Modo 3: PixelBar
// Modo 4: StroboPixel
byte id()
{
int id = 0;
for (byte i = 0; i < 4; i++ ) bitWrite(id, i, digitalRead(idpin[i]));
return id;
}
int channel()
{
int value = code();
switch (value) {
case 0:
value = 0x4C; // showroom
break;
case 1:
value = 0x64; // developers
break;
default:
value = 0x64; // developers
break;
}
return value;
}
int code()
{
int value = 0;
for (byte i = 0; i < 4; i++) bitWrite(value, i, digitalRead(chpin[i]));
return value;
}
//////////////////////////////////////////////////////////////////
/////////////////////// NEON FUNCIONS ///////////////////
//////////////////////////////////////////////////////////////////
void stroboNeon(int stroboTime)
{
if ( millis() > delayed )
{
if ( stroboFlag )
{
analogWrite(WHITE, 255);
stroboFlag = 0;
Serial.println("Strobo_ON");
delayed = millis() + stroboTime;
}
else if ( !stroboFlag )
{
analogWrite(WHITE, 0);
Serial.println("Strobo_OFF");
stroboFlag = 1;
delayed = millis() + stroboTime;
}
}
}
void colorNeon(int red, int green, int blue)
{
analogWrite(RED, red);
analogWrite(GREEN, green);
analogWrite(BLUE, blue);
}
//////////////////////////////////////////////////////////////////
//////////////// PIXEL BASIC FUNCIONS //////////////////
//////////////////////////////////////////////////////////////////
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);
}
splitStrip();
showStrip();
}
//////////////////////////////////////////////////////////////////
/////////////////////// PIXEL BAR //////////////////////
//////////////////////////////////////////////////////////////////
void pixelBar(int SpeedDelay, byte red, byte green, byte blue, byte white)
{
setAll(0,0,0,0);
for (int i = 0; i < NUMPIXELS1; i++)
{
setPixel(i, red, green, blue, white);
splitStrip();
showStrip();
delay(SpeedDelay);
}
}
//////////////////////////////////////////////////////////////////
/////////////////////// PIXEL POINT /////////////////////
//////////////////////////////////////////////////////////////////
void pixelPoint(int pixelPos, int pixWidth)
{
//setAll(0,0,0,0);
if( pixelPos > NUMPIXELS1 )
pixelPos=NUMPIXELS1;
if( pixelPos< 0 )
pixelPos= 0;
// pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels1.setPixelColor(pixelPos, pixels1.Color(255, 0, 0, 0)); // Moderately bright green color.
pixels1.setPixelColor(pixelPos-pixWidth, pixels1.Color(0, 0, 0, 0)); // Moderately bright green color.
splitStrip();
showStrip();
//delay(15);
// }
// else
// {
// //for (int i = NUMPIXELS1; i > 0; i--) {
// i--;
// if( i < 0 )
// i=NUMPIXELS1;
// // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
// pixels1.setPixelColor(i, pixels1.Color(0, 255, 255, 0)); // Moderately bright green color.
// pixels1.setPixelColor(i+pixWidth, pixels1.Color(0, 0, 0, 0)); // Moderately bright green color.
// splitStrip();
// showStrip();
// delay(SpeedDelay);
// //}
// }
}
//////////////////////////////////////////////////////////////////
/////////////////////// PIXEL STROBO ////////////////////
//////////////////////////////////////////////////////////////////
void stroboPixel(int stroboTimeOn, int stroboTimeOff)
{
if ( millis() > delayed )
{
if ( stroboFlag )
{
stroboFlag = 0;
for (int i = 0; i < NUMPIXELS1; i++)
{
pixels1.setPixelColor(i, pixels1.Color(0, 0, 0, 255)); // Moderately bright green color.
}
splitStrip();
showStrip();
//analogWrite(WHITE, 255);
delayed = millis() + stroboTimeOn;
}
else if ( !stroboFlag )
{
stroboFlag = 1;
for (int i = 0; i < NUMPIXELS1; i++)
{
pixels1.setPixelColor(i, pixels1.Color(0, 0, 0, 0)); // Moderately bright green color.
}
splitStrip();
showStrip();
//analogWrite(WHITE, 0);
delayed = millis() + stroboTimeOff;
}
}
}
//////////////////////////////////////////////////////////////////
/////////////////////// PIXEL FIRE //////////////////////
//////////////////////////////////////////////////////////////////
void fire(int Cooling, int Sparking, int SpeedDelay)
{
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
for( int j = 0; j < NUMPIXELS1; j++) {
setPixelHeatColor(j, heat[j] );
}
splitStrip();
showStrip();
delay(SpeedDelay);
}
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);
}
}
//////////////////////////////////////////////////////////////////
///////////////////////// 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
//}
//delay(5000);
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(4);
radio.setChannel(ch);
#if RADIOSEND
radio.openWritingPipe(pipe);
#else
radio.openReadingPipe(1, pipe);
radio.startListening();
#endif
radio.printDetails();
}
//////////////////////////////////////////////////////////////////
///////////////////////// LOOP ////////////////////////////////
//////////////////////////////////////////////////////////////////
void loop()
{
if( TEST)
{
colorNeon(255,0,0);
fire(20, 140 ,5); // 55, 120, 15 (cooling 400 bajito e ir bajando para subir el tamaño hasta 20 maximo)
//pixelPoint(5,1,4);
//pixelPoint(5,0,4);
//stroboPixel(10,20);
//pixelBar(15, 0, 0, 0, 255);
}
else
{
if ( radio.available() )
{
while (radio.available())
{
//done = radio.read( CMD, sizeof(CMD) );
radio.read( CMD, sizeof(CMD) );
if (DEBUG)
{
//Serial.println("id: ");
//Serial.print(id());
//Serial.println("Got command");
for (int i = 0 ; i < 4 ; i++)
{
Serial.print(CMD[i]);
Serial.print(",");
}
Serial.println();
}
if ( ( CMD[0] == 201 ) && ( CMD[1] == id() ) ) // CMD 1
{
if (DEBUG)
{
Serial.print("Fuego: ");
}
mode = 1; // modo 1 = fuego
param1 = CMD[2];
param2 = CMD[3];
}
else if ( ( CMD[0] == 202 ) && ( CMD[1] == id() ) ) // CMD 2
{
if (DEBUG)
{
Serial.print("PixelPoint: ");
}
mode = 2; // modo 2 = punto
param1 = CMD[2];
param2 = CMD[3];
}
else if ( ( CMD[0] == 203 ) && ( CMD[1] == id() ) ) // CMD 3
{
if (DEBUG)
{
Serial.print("Strobo: ");
}
mode = 3; // modo 2 = punto
param1 = CMD[2];
param2 = CMD[3];
}
else if ( ( CMD[0] == 204 ) && ( CMD[1] == id() ) ) // CMD 4
{
if (DEBUG)
{
Serial.print("Color: ");
}
mode = 4; // modo 2 = punto
param1 = CMD[2];
param2 = CMD[3];
}
}
}
}
switch (mode)
{
case 1:
fire(param1, param2, 5); // (20,140,5) -> altura, chispas, delay
break;
case 2:
pixelPoint(param1,param2); // (5,1,4) -> pos, width
break;
case 3:
stroboPixel(param1,param2); // (5,1,4) -> delay, dir, width
break;
case 4:
setAll(param1,param2,0,0); // (5,1,4) -> delay, dir, width
colorNeon(param1, param2, 0);
break;
}
}