456 lines
10 KiB
Arduino
456 lines
10 KiB
Arduino
|
|
||
|
|
||
|
#include <SPI.h>
|
||
|
#include <Adafruit_NeoPixel.h>
|
||
|
#include <SD.h>
|
||
|
|
||
|
#include "nRF24L01MOD.h"
|
||
|
#include "RF24MOD.h"
|
||
|
#include "printfMOD.h"
|
||
|
#include "MCP23008.h"
|
||
|
|
||
|
#define DEBUG 0
|
||
|
//#define ALAS
|
||
|
//define ESTRELLA
|
||
|
//#define AROS
|
||
|
//#define VERONAL
|
||
|
#define GUIRNALDA
|
||
|
|
||
|
|
||
|
//Found device at: 0x20
|
||
|
//Found device at: 0xA0
|
||
|
|
||
|
// Radio Settings
|
||
|
#define CE_PIN 7
|
||
|
#define CSN_PIN 6
|
||
|
int radioId;
|
||
|
uint32_t CMD[ 8 ]; // Comando Radio
|
||
|
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
|
||
|
const uint64_t pipe = 0xE8E8F0F0E1LL; // Define the transmit pipe
|
||
|
|
||
|
#ifdef ALAS
|
||
|
int ch = 0x20 ; // 76 por defecto es el canal 76
|
||
|
#endif
|
||
|
#ifdef ESTRELLA
|
||
|
int ch = 0x4C ;
|
||
|
#endif
|
||
|
#ifdef AROS
|
||
|
int ch = 0x76 ; // 76 por defecto es el canal 76
|
||
|
#endif
|
||
|
#ifdef VERONAL
|
||
|
int ch = 0x76 ; // 76 por defecto es el canal 76
|
||
|
#endif
|
||
|
#ifdef GUIRNALDA
|
||
|
int ch = 0x4C ;
|
||
|
#endif
|
||
|
|
||
|
//Definicion de los pines de la tira de led
|
||
|
#define RED 8
|
||
|
#define GREEN 9
|
||
|
#define BLUE 10
|
||
|
#define WHITE 5
|
||
|
|
||
|
//Definicion de los pines de laS tiraS de led PIXELS
|
||
|
#define SDO1 A5
|
||
|
#define SDO2 A2
|
||
|
#define SDO3 A3
|
||
|
|
||
|
|
||
|
#ifdef ALAS
|
||
|
// ALAS
|
||
|
#define NUMPIXELS1 512 // han de ser 576
|
||
|
#define NUMPIXELS2 0
|
||
|
#define NUMPIXELS3 0
|
||
|
#endif
|
||
|
|
||
|
#ifdef AROS
|
||
|
// AROS
|
||
|
#define NUMPIXELS1 297 // ponemos un par mas para corregir errores
|
||
|
#define NUMPIXELS2 0
|
||
|
#define NUMPIXELS3 16 // 16 y GRB al reves que los otros
|
||
|
#endif
|
||
|
|
||
|
#ifdef ESTRELLA
|
||
|
// ESTRELLA
|
||
|
#define NUMPIXELS1 409
|
||
|
#define NUMPIXELS2 0
|
||
|
#define NUMPIXELS3 30
|
||
|
#endif
|
||
|
|
||
|
#ifdef VERONAL
|
||
|
// VERONAL
|
||
|
#define NUMPIXELS1 100
|
||
|
#define NUMPIXELS2 100
|
||
|
#define NUMPIXELS3 100
|
||
|
#endif
|
||
|
|
||
|
#ifdef GUIRNALDA
|
||
|
// VERONAL
|
||
|
#define NUMPIXELS1 120
|
||
|
#define NUMPIXELS2 120
|
||
|
#define NUMPIXELS3 120
|
||
|
#endif
|
||
|
|
||
|
Adafruit_NeoPixel pixels_1(NUMPIXELS1, SDO1, NEO_RGB + NEO_KHZ800);
|
||
|
Adafruit_NeoPixel pixels_2(NUMPIXELS2, SDO2, NEO_RGB + NEO_KHZ800);
|
||
|
Adafruit_NeoPixel pixels_3(NUMPIXELS3, SDO3, NEO_RGB + NEO_KHZ800);
|
||
|
|
||
|
|
||
|
|
||
|
MCP23008 id;
|
||
|
|
||
|
// Artnet settings
|
||
|
const int startUniverse = 0; // CHANGE FOR YOUR SETUP most software this is 1, some software send out artnet first universe as zero.
|
||
|
const int numberOfChannels = (NUMPIXELS1 + NUMPIXELS2 + NUMPIXELS3) * 3; // Total number of channels you want to receive (1 led = 3 channels)
|
||
|
byte channelBuffer[numberOfChannels]; // Combined universes into a single array
|
||
|
|
||
|
// SD card
|
||
|
File datafile;
|
||
|
char fileName[] = "data.txt";
|
||
|
const int chipSelect = 4;
|
||
|
|
||
|
bool playback = 0;
|
||
|
|
||
|
// Check if we got all universes
|
||
|
const int maxUniverses = numberOfChannels / 512 + ((numberOfChannels % 512) ? 1 : 0);
|
||
|
bool universesReceived[maxUniverses];
|
||
|
bool sendFrame = 1;
|
||
|
|
||
|
|
||
|
unsigned long previousMillis = 0;
|
||
|
const long interval = 15000;
|
||
|
|
||
|
|
||
|
void setup()
|
||
|
{
|
||
|
Serial.begin(115200);
|
||
|
//while (!Serial) {
|
||
|
//; // wait for serial port to connect. Needed for Leonardo only
|
||
|
//}
|
||
|
|
||
|
pixels_1.begin();
|
||
|
pixels_2.begin();
|
||
|
pixels_3.begin();
|
||
|
|
||
|
#ifdef ALAS
|
||
|
pixels_1.setBrightness(100); // Set BRIGHTNESS to about 1/5 (max = 255)
|
||
|
pixels_2.setBrightness(100); // Set BRIGHTNESS to about 1/5 (max = 255)
|
||
|
pixels_3.setBrightness(100); // Set BRIGHTNESS to about 1/5 (max = 255)
|
||
|
#endif
|
||
|
|
||
|
Serial.println("LEDs initialization test.");
|
||
|
initTest();
|
||
|
|
||
|
if (!SD.begin(chipSelect)) {
|
||
|
Serial.println("SD initialization failed!");
|
||
|
}
|
||
|
else
|
||
|
Serial.println("SD initialization done.");
|
||
|
|
||
|
radio.begin();
|
||
|
radio.setDataRate( RF24_250KBPS );
|
||
|
radio.setPALevel( RF24_PA_MAX );
|
||
|
radio.setAutoAck(0);
|
||
|
radio.setPayloadSize(8);
|
||
|
radio.setChannel(ch);
|
||
|
//radio.setChannel(0x4c);
|
||
|
radio.openReadingPipe(1, pipe);
|
||
|
radio.startListening();
|
||
|
radio.printDetails();
|
||
|
|
||
|
Serial.println("RADIO initialization done.");
|
||
|
|
||
|
// configure MCP23008 component
|
||
|
id.begin(0x20);
|
||
|
id.pinMode(0xFF);
|
||
|
id.setPullup(0x00);
|
||
|
|
||
|
Serial.print("ID: ");
|
||
|
Serial.println(id.read());
|
||
|
|
||
|
Serial.print("Num Pixels: ");
|
||
|
Serial.println(NUMPIXELS1 + NUMPIXELS2 + NUMPIXELS3);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void loop()
|
||
|
{
|
||
|
|
||
|
if (Serial.available() > 0)
|
||
|
{
|
||
|
char c = Serial.read();
|
||
|
//Serial.println(c);
|
||
|
|
||
|
if (c == 'p')
|
||
|
{
|
||
|
playback = 1;
|
||
|
datafile = SD.open(fileName, FILE_READ);
|
||
|
Serial.print("datafile play: ");
|
||
|
}
|
||
|
else if ( c == 's')
|
||
|
{
|
||
|
playback = 0;
|
||
|
datafile.close();
|
||
|
Serial.print("datafile stop: ");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
if ( radio.available() )
|
||
|
{
|
||
|
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 < 8 ; i++)
|
||
|
{
|
||
|
Serial.print(CMD[i]);
|
||
|
Serial.print(",");
|
||
|
}
|
||
|
Serial.println();
|
||
|
}
|
||
|
|
||
|
if (CMD[0] == 1) // play
|
||
|
{
|
||
|
playback = 1;
|
||
|
datafile = SD.open(fileName, FILE_READ);
|
||
|
Serial.print("datafile Radio play: ");
|
||
|
}
|
||
|
else if (CMD[0] == 0) // stop
|
||
|
{
|
||
|
playback = 0;
|
||
|
datafile.close();
|
||
|
Serial.print("datafile Radio stop: ");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// we call the read function inside the loop
|
||
|
if (playback)
|
||
|
{
|
||
|
|
||
|
//while (datafile.available() && playback) // bloqueante hasta que termine de leer
|
||
|
if ( datafile.available() && playback ) // NO BLOQUEANTE hasta que termine de leer
|
||
|
{
|
||
|
//Serial.println("playback_while");
|
||
|
datafile.read(channelBuffer, numberOfChannels);
|
||
|
if (NUMPIXELS1)
|
||
|
{
|
||
|
for (int i = 0; i < NUMPIXELS1; i++)
|
||
|
{
|
||
|
pixels_1.setPixelColor(i, channelBuffer[(i) * 3], channelBuffer[(i * 3) + 1], channelBuffer[(i * 3) + 2]);
|
||
|
//Serial.println(channelBuffer[(i) * 3]);
|
||
|
}
|
||
|
pixels_1.show();
|
||
|
}
|
||
|
|
||
|
#ifdef VERONAL
|
||
|
if (NUMPIXELS2)
|
||
|
{
|
||
|
for (int i = NUMPIXELS1; i < NUMPIXELS1 + NUMPIXELS2; i++)
|
||
|
{
|
||
|
pixels_2.setPixelColor(i - NUMPIXELS1, channelBuffer[(i) * 3], channelBuffer[(i * 3) + 1], channelBuffer[(i * 3) + 2]);
|
||
|
//Serial.println(channelBuffer[(i) * 3]);
|
||
|
}
|
||
|
pixels_2.show();
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef GUIRNALDA
|
||
|
if (NUMPIXELS2)
|
||
|
{
|
||
|
for (int i = NUMPIXELS1; i < NUMPIXELS1 + NUMPIXELS2; i++)
|
||
|
{
|
||
|
pixels_2.setPixelColor(i - NUMPIXELS1, channelBuffer[(i) * 3], channelBuffer[(i * 3) + 1], channelBuffer[(i * 3) + 2]);
|
||
|
//Serial.println(channelBuffer[(i) * 3]);
|
||
|
}
|
||
|
pixels_2.show();
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (NUMPIXELS3)
|
||
|
{
|
||
|
for (int i = NUMPIXELS1 + NUMPIXELS2; i < NUMPIXELS1 + NUMPIXELS2 + NUMPIXELS3; i++)
|
||
|
{
|
||
|
pixels_3.setPixelColor(i - NUMPIXELS1 - NUMPIXELS2, channelBuffer[(i) * 3], channelBuffer[(i * 3) + 1], channelBuffer[(i * 3) + 2]);
|
||
|
//Serial.println(channelBuffer[(i) * 3]);
|
||
|
}
|
||
|
pixels_3.show();
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifdef AROS
|
||
|
//delayMicroseconds(19390); // 30 fps y 300 pixels) -> AROSx
|
||
|
delayMicroseconds(17900); // 30 fps y 313 pixels) -> AROS
|
||
|
#endif
|
||
|
|
||
|
#ifdef ALAS
|
||
|
//delayMicroseconds(9475); // 30 fps y 576 pixels ) -> ALAS grabadas a 512 pixels temporalmente
|
||
|
delayMicroseconds(9475); // 30 fps y 576 pixels ) -> ALAS grabadas a 512 pixels temporalmente
|
||
|
#endif
|
||
|
|
||
|
#ifdef ESTRELLA
|
||
|
delayMicroseconds(13185); // 30 fps y 409 pixels + 30 pixels) -> ESTRELLA grabada a 439 pixels
|
||
|
#endif
|
||
|
|
||
|
#ifdef VERONAL
|
||
|
delayMicroseconds(19150); // 30 fps y 409 pixels + 30 pixels) -> ESTRELLA grabada a 439 pixels
|
||
|
#endif
|
||
|
|
||
|
#ifdef GUIRNALDA
|
||
|
delayMicroseconds(16000); // 30 fps y 409 pixels + 30 pixels) -> ESTRELLA grabada a 439 pixels
|
||
|
#endif
|
||
|
}
|
||
|
else if ( !datafile.available() && playback ) // Cuando termina de leer el file cierra y para. NO BLOQUEANTE
|
||
|
{
|
||
|
playback = 0;
|
||
|
datafile.close();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
unsigned long currentMillis = millis();
|
||
|
|
||
|
if (currentMillis - previousMillis >= interval)
|
||
|
{
|
||
|
// save the last time you blinked the LED
|
||
|
previousMillis = currentMillis;
|
||
|
playback = 1;
|
||
|
datafile = SD.open(fileName, FILE_READ);
|
||
|
Serial.print("datafile timer play: ");
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void initTest()
|
||
|
{
|
||
|
for (int i = 0 ; i < NUMPIXELS1 ; i++)
|
||
|
pixels_1.setPixelColor(i, 127, 0, 0);
|
||
|
pixels_1.show();
|
||
|
delay(500);
|
||
|
|
||
|
for (int i = 0 ; i < NUMPIXELS2 ; i++)
|
||
|
pixels_2.setPixelColor(i, 0, 127, 0);
|
||
|
pixels_2.show();
|
||
|
delay(500);
|
||
|
|
||
|
for (int i = 0 ; i < NUMPIXELS3 ; i++)
|
||
|
pixels_3.setPixelColor(i, 0, 0, 127);
|
||
|
pixels_3.show();
|
||
|
delay(1000);
|
||
|
|
||
|
for (int i = 0 ; i < NUMPIXELS1 ; i++)
|
||
|
pixels_1.setPixelColor(i, 0, 0, 0);
|
||
|
pixels_1.show();
|
||
|
delay(500);
|
||
|
|
||
|
for (int i = 0 ; i < NUMPIXELS2 ; i++)
|
||
|
pixels_2.setPixelColor(i, 0, 0, 0);
|
||
|
pixels_2.show();
|
||
|
delay(500);
|
||
|
|
||
|
for (int i = 0 ; i < NUMPIXELS3 ; i++)
|
||
|
pixels_3.setPixelColor(i, 0, 0, 0);
|
||
|
pixels_3.show();
|
||
|
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
void onDmxFrame(uint16_t universe, uint16_t length, uint8_t sequence, uint8_t* data, IPAddress remoteIP)
|
||
|
{
|
||
|
sendFrame = 1;
|
||
|
// set brightness of the whole strip
|
||
|
if (universe == 15)
|
||
|
{
|
||
|
leds.setBrightness(data[0]);
|
||
|
leds.show();
|
||
|
}
|
||
|
|
||
|
if (universe == 14)
|
||
|
{
|
||
|
// record
|
||
|
if (data[0] == 255)
|
||
|
{
|
||
|
if (SD.exists(fileName))
|
||
|
{
|
||
|
SD.remove(fileName);
|
||
|
}
|
||
|
datafile = SD.open(fileName, FILE_WRITE);
|
||
|
record = 1;
|
||
|
playback = 0;
|
||
|
}
|
||
|
// play
|
||
|
if (data[0] == 127)
|
||
|
{
|
||
|
record = 0;
|
||
|
playback = 1;
|
||
|
datafile = SD.open(fileName, FILE_READ);
|
||
|
}
|
||
|
// stop
|
||
|
if (data[0] == 0)
|
||
|
{
|
||
|
record = 0;
|
||
|
playback = 0;
|
||
|
datafile.close();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Store which universe has got in
|
||
|
if (universe < maxUniverses)
|
||
|
universesReceived[universe] = 1;
|
||
|
|
||
|
for (int i = 0 ; i < maxUniverses ; i++)
|
||
|
{
|
||
|
if (universesReceived[i] == 0)
|
||
|
{
|
||
|
//Serial.println("Broke");
|
||
|
sendFrame = 0;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!playback)
|
||
|
{
|
||
|
// read universe and put into the right part of the display buffer
|
||
|
for (int i = 0 ; i < length ; i++)
|
||
|
{
|
||
|
int bufferIndex = i + ((universe - startUniverse) * length);
|
||
|
if (bufferIndex < numberOfChannels) // to verify
|
||
|
channelBuffer[bufferIndex] = byte(data[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (record && sendFrame)
|
||
|
{
|
||
|
datafile.write(channelBuffer, numberOfChannels);
|
||
|
memset(universesReceived, 0, maxUniverses);
|
||
|
}
|
||
|
|
||
|
if (!playback && !record)
|
||
|
{
|
||
|
// send to leds
|
||
|
for (int i = 0; i < numLeds; i++)
|
||
|
{
|
||
|
leds.setPixelColor(i, channelBuffer[(i) * 3], channelBuffer[(i * 3) + 1], channelBuffer[(i * 3) + 2]);
|
||
|
}
|
||
|
|
||
|
if (sendFrame)
|
||
|
{
|
||
|
leds.show();
|
||
|
// Reset universeReceived to 0
|
||
|
memset(universesReceived, 0, maxUniverses);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
*/
|