627 lines
15 KiB
C++
627 lines
15 KiB
C++
|
|
#include <SD.h>
|
|
#include <SPI.h>
|
|
#include <Artnet.h>
|
|
#include <Ethernet.h>
|
|
#include <EthernetUdp.h>
|
|
#include <DFMiniMp3.h>
|
|
|
|
#define DEBUG 1
|
|
#define ARTNET_RX 1
|
|
|
|
Artnet artnet; // Esto es para recepción solo!
|
|
|
|
//HARDWARE
|
|
byte IPnum = 102;
|
|
const int globalUniverse = 0;
|
|
const int DMX_Universe = (globalUniverse / 16 << 8) + (globalUniverse % 16); // universo (8bit) + subnet (7bit)
|
|
const int number_of_channels = 10; // MAX=512
|
|
|
|
byte mac[] = {0x04, 0xE9, 0xE5, 0x00, 0x69, 0xEC};
|
|
byte ip[] = { 10, 0, 0, IPnum };// the IP adress of your device, that should be in same universe of the network you are using, here: 192.168.1.x
|
|
byte destination_Ip[] = { 10, 0, 0, 100 }; // the ip to send data, 255,255,255,255 is broadcast sending
|
|
byte broadcast[] = {10, 0, 0, 255};
|
|
|
|
// art net parameters
|
|
//unsigned int localPort = 6454; // artnet UDP port is by default 6454
|
|
unsigned int destPort = 6454; // artnet UDP port is by default 6454
|
|
|
|
EthernetUDP Udp;
|
|
|
|
//ART-NET variables
|
|
char ArtNetHead[8] = "Art-Net";
|
|
const int art_net_header_size = 17;
|
|
|
|
short OpOutput = 0x5000 ; //output
|
|
|
|
byte buffer_dmx[number_of_channels]; //buffer used for DMX data
|
|
|
|
//Artnet PACKET
|
|
byte ArtDmxBuffer[(art_net_header_size + number_of_channels) + 8 + 1];
|
|
|
|
int temp_val = 0; // con signo para comparar menor que 0
|
|
uint8_t sensorPin = A5;
|
|
bool sensorFlag = 0;
|
|
uint8_t rampState = 0;
|
|
bool resetFlag = 0;
|
|
bool resetEthFlag = 0;
|
|
uint8_t prevSoundVol;
|
|
uint8_t prevTimeSensor;
|
|
bool triggerSoundFlag = 0;
|
|
|
|
int increment = 3;
|
|
int inc = 1;
|
|
|
|
unsigned long previousMillis = 0;
|
|
unsigned long currentMillis = 0;
|
|
unsigned long interval = 15000; // interval at which to check sensors
|
|
|
|
|
|
// implement a notification class,
|
|
// its member methods will get called
|
|
|
|
class Mp3Notify
|
|
{
|
|
public:
|
|
static void PrintlnSourceAction(DfMp3_PlaySources source, const char* action)
|
|
{
|
|
if (source & DfMp3_PlaySources_Sd)
|
|
{
|
|
Serial.print("SD Card, ");
|
|
}
|
|
if (source & DfMp3_PlaySources_Usb)
|
|
{
|
|
Serial.print("USB Disk, ");
|
|
}
|
|
if (source & DfMp3_PlaySources_Flash)
|
|
{
|
|
Serial.print("Flash, ");
|
|
}
|
|
Serial.println(action);
|
|
}
|
|
static void OnError(uint16_t errorCode)
|
|
{
|
|
// see DfMp3_Error for code meaning
|
|
Serial.println();
|
|
Serial.print("Com Error ");
|
|
Serial.println(errorCode);
|
|
}
|
|
static void OnPlayFinished(DfMp3_PlaySources source, uint16_t track)
|
|
{
|
|
Serial.print("Play finished for #");
|
|
Serial.println(track);
|
|
}
|
|
static void OnPlaySourceOnline(DfMp3_PlaySources source)
|
|
{
|
|
PrintlnSourceAction(source, "online");
|
|
}
|
|
static void OnPlaySourceInserted(DfMp3_PlaySources source)
|
|
{
|
|
PrintlnSourceAction(source, "inserted");
|
|
}
|
|
static void OnPlaySourceRemoved(DfMp3_PlaySources source)
|
|
{
|
|
PrintlnSourceAction(source, "removed");
|
|
}
|
|
};
|
|
|
|
// instance a DFMiniMp3 object,
|
|
// defined with the above notification class and the hardware serial class
|
|
//
|
|
DFMiniMp3<HardwareSerial, Mp3Notify> mp3(Serial1);
|
|
static uint16_t mp3vol, mp3state, mp3eq, mp3fileCounts, mp3currentTrack;
|
|
uint8_t soundBank = 1;
|
|
|
|
|
|
void setup()
|
|
{
|
|
|
|
pinMode(sensorPin, INPUT_PULLUP); // sensor digital! Conectar a GND el otro pin, chequear tester!
|
|
|
|
if (DEBUG)
|
|
{
|
|
Serial.begin(115200);
|
|
while (!Serial) {
|
|
// ; // wait for Serial port to connect. Needed for native USB port only
|
|
}
|
|
}
|
|
// Open Serial communications and wait for port to open:
|
|
|
|
|
|
if (ARTNET_RX)
|
|
{
|
|
artnet.begin(mac, ip);
|
|
//artnet.setBroadcast(broadcast);
|
|
if (DEBUG)
|
|
Serial.println("Artnet Reader OK!");
|
|
}
|
|
|
|
Ethernet.begin(mac, ip);
|
|
Udp.begin(destPort); // se usa para enviar Artnet manualmente
|
|
|
|
if (DEBUG)
|
|
{
|
|
// Check for Ethernet hardware present
|
|
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
|
|
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
|
|
while (true) {
|
|
delay(1); // do nothing, no point running without Ethernet hardware
|
|
}
|
|
}
|
|
|
|
if (Ethernet.linkStatus() == LinkOFF) {
|
|
Serial.println("Ethernet cable is not connected.");
|
|
}
|
|
|
|
Serial.println("Initialization Ethernet done.");
|
|
}
|
|
|
|
construct_arnet_packet(); // constructor de paquete ARTNET
|
|
|
|
mp3.begin();
|
|
mp3.reset();
|
|
|
|
uint16_t volume = mp3.getVolume();
|
|
uint16_t count = mp3.getTotalTrackCount(DfMp3_PlaySource_Sd);
|
|
|
|
if (DEBUG)
|
|
{
|
|
Serial.print("volume ");
|
|
Serial.println(volume);
|
|
Serial.print("files ");
|
|
Serial.println(count);
|
|
Serial.println("Starting Audio...");
|
|
}
|
|
|
|
mp3.setVolume(20); // ajustar vol en el altavoz final! Implmentar volumen en tiempo real!
|
|
prevSoundVol = 20;
|
|
|
|
randomSeed(13);
|
|
|
|
|
|
if (DEBUG)
|
|
{
|
|
Serial.print("DMX Universe: ");
|
|
Serial.println( DMX_Universe );
|
|
Serial.print("Universo: ");
|
|
Serial.print( DMX_Universe & 0xFF);
|
|
Serial.print(" Subnet: ");
|
|
Serial.println( DMX_Universe >> 8);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void loop() {
|
|
|
|
// calling mp3.loop() periodically allows for notifications
|
|
// to be handled without interrupts
|
|
|
|
if (DEBUG)
|
|
mp3.loop();
|
|
|
|
currentMillis = millis();
|
|
if (currentMillis - previousMillis >= interval)
|
|
{
|
|
//previousMillis = currentMillis;
|
|
check_sensor();
|
|
}
|
|
|
|
if (rampState == 1)
|
|
ramp_down();
|
|
else if (rampState == 2)
|
|
ramp_up();
|
|
else if (rampState == 3) // triangle
|
|
triangle();
|
|
|
|
if (rampState) // solo envia cuando hay movimiento
|
|
{
|
|
construct_arnet_packet();
|
|
//Serial.println( buffer_dmx[0] );
|
|
Udp.beginPacket( destination_Ip , destPort );
|
|
Udp.write(ArtDmxBuffer, (art_net_header_size + number_of_channels + 1));
|
|
Udp.endPacket();
|
|
}
|
|
|
|
|
|
if (ARTNET_RX)
|
|
{
|
|
uint16_t r = artnet.read();
|
|
//Serial.println("listening artnet");
|
|
if (r == ART_POLL)
|
|
{
|
|
if (DEBUG)
|
|
Serial.println("POLL");
|
|
}
|
|
if (r == ART_DMX)
|
|
{
|
|
if (DEBUG)
|
|
{
|
|
// print out our data
|
|
Serial.print("universe number = ");
|
|
Serial.print(artnet.getUniverse());
|
|
Serial.print("\tdata length = ");
|
|
Serial.print(artnet.getLength());
|
|
Serial.print("\tsequence n0. = ");
|
|
Serial.println(artnet.getSequence());
|
|
Serial.print("DMX data: ");
|
|
for (int i = 0 ; i < artnet.getLength() ; i++)
|
|
{
|
|
Serial.print(artnet.getDmxFrame()[i]);
|
|
Serial.print(" ");
|
|
}
|
|
Serial.println();
|
|
Serial.println();
|
|
}
|
|
if (artnet.getUniverse() == 99) // Universo 100 MADRIX de control
|
|
{
|
|
byte soundBankSel = artnet.getDmxFrame()[0];
|
|
byte soundVol = map(artnet.getDmxFrame()[1], 0, 255, 0, 30); // ojo con esto! mapear 30 a 255
|
|
byte timeSensor = artnet.getDmxFrame()[2];
|
|
byte triggerSound = artnet.getDmxFrame()[3];
|
|
byte resetByte = artnet.getDmxFrame()[127];
|
|
byte resetEthByte = artnet.getDmxFrame()[128]; // solo en la placa Audio Ethernet (feather NO)
|
|
|
|
//Serial.print("Reset");
|
|
//Serial.print(resetByte);
|
|
|
|
if ( soundBankSel < 10 )
|
|
soundBank = 1;
|
|
else if ( (soundBankSel >= 10) & (soundBankSel < 20) )
|
|
soundBank = 2;
|
|
else if ( (soundBankSel >= 20) & (soundBankSel < 30) )
|
|
soundBank = 3;
|
|
else if ( (soundBankSel >= 30) & (soundBankSel < 40) )
|
|
soundBank = 4;
|
|
else if ( soundBankSel >= 40 )
|
|
soundBank = 5;
|
|
|
|
if (soundVol != prevSoundVol)
|
|
{
|
|
prevSoundVol = soundVol;
|
|
mp3.setVolume(soundVol); //
|
|
if (DEBUG)
|
|
{
|
|
Serial.print("Vol: ");
|
|
Serial.println(soundVol);
|
|
}
|
|
}
|
|
|
|
if (timeSensor != prevTimeSensor)
|
|
{
|
|
interval = timeSensor * 100; // 0 - 25,5 segundos
|
|
prevTimeSensor = timeSensor;
|
|
if (DEBUG)
|
|
{
|
|
Serial.print("Time inverval: ");
|
|
Serial.println(soundVol);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if ( ( triggerSound ) && !triggerSoundFlag )
|
|
{
|
|
triggerSoundFlag = 1;
|
|
if (DEBUG)
|
|
Serial.println("Trigger Sound");
|
|
mp3.playGlobalTrack(soundBank); //Play next mp3
|
|
}
|
|
else if ( ( !triggerSound ) && triggerSoundFlag )
|
|
triggerSoundFlag = 0;
|
|
|
|
|
|
|
|
if ( ( resetByte ) && !resetFlag )
|
|
{
|
|
resetFlag = 1;
|
|
if (DEBUG)
|
|
Serial.println("Reset CPU");
|
|
|
|
NVIC_SystemReset(); // RESET SAMD21
|
|
}
|
|
else if ( ( !resetByte ) && resetFlag )
|
|
resetFlag = 0;
|
|
|
|
|
|
if ( ( resetEthByte ) && !resetEthFlag )
|
|
{
|
|
if (DEBUG)
|
|
Serial.println("Reset Ethernet");
|
|
|
|
digitalWrite(11, LOW); // Reset Ethernet Chip
|
|
delay(100);
|
|
digitalWrite(11, HIGH);
|
|
delay(100);
|
|
|
|
Ethernet.begin(mac, ip);
|
|
Udp.begin(destPort);
|
|
|
|
if (ARTNET_RX)
|
|
{
|
|
artnet.begin(mac, ip);
|
|
//artnet.setBroadcast(broadcast);
|
|
if (DEBUG)
|
|
Serial.println("Artnet Reader OK!");
|
|
}
|
|
}
|
|
else if ( ( !resetEthByte ) && resetEthFlag )
|
|
resetEthFlag = 0;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
// RESET ETHERNET SI SE DESCONECTA
|
|
if (Ethernet.linkStatus() == LinkOFF)
|
|
{
|
|
Serial.println("Ethernet cable is not connected.");
|
|
//NVIC_SystemReset(); // RESET SAMD21
|
|
//digitalWrite(11, LOW); // Reset Ethernet Chip
|
|
//delay(100);
|
|
//digitalWrite(11, HIGH);
|
|
delay(1000);
|
|
}
|
|
*/
|
|
|
|
if (DEBUG) // SERIAL COMMANDS
|
|
{
|
|
if (Serial.available())
|
|
{
|
|
char c = Serial.read();
|
|
//Serial.print(c);
|
|
|
|
if (c == 'r') // RESET
|
|
{
|
|
Serial.println("Reset CPU");
|
|
NVIC_SystemReset(); // RESET SAMD21
|
|
}
|
|
else if (c == 's') // pista 1
|
|
{
|
|
Serial.println("Stop");
|
|
mp3.stop(); //Play next mp3
|
|
}
|
|
else if (c == '1') // pista 1
|
|
{
|
|
Serial.println("Play 0001.mp3");
|
|
mp3.playGlobalTrack(1); //Play next mp3
|
|
}
|
|
else if (c == '2') // pista 2
|
|
{
|
|
Serial.println("Play 0002.mp3");
|
|
mp3.playGlobalTrack(2); //Play next mp3
|
|
}
|
|
else if (c == '3') // pista 3
|
|
{
|
|
Serial.println("Play 0003.mp3");
|
|
mp3.playGlobalTrack(3); //Play next mp3
|
|
}
|
|
else if (c == '4') // pista 4
|
|
{
|
|
Serial.println("Play 0004.mp3");
|
|
mp3.playGlobalTrack(4); //Play next mp3
|
|
}
|
|
else if (c == '5') // pista 5
|
|
{
|
|
Serial.println("Play 0005.mp3");
|
|
mp3.playGlobalTrack(5); //Play next mp3
|
|
}
|
|
else if (c == '+') // RESET
|
|
{
|
|
//Serial.println("stopping...");
|
|
//mp3.stop(); // stop
|
|
//readMP3state();
|
|
//delay(1000);
|
|
//readMP3state();
|
|
mp3.nextTrack(); //Play next mp3
|
|
Serial.print("Play ");
|
|
Serial.println(mp3.getCurrentTrack(DfMp3_PlaySource_Sd));
|
|
//readMP3state();
|
|
}
|
|
else if (c == '-') // RESET
|
|
{
|
|
mp3.prevTrack(); //Play next mp3
|
|
Serial.print("Play ");
|
|
Serial.println(mp3.getCurrentTrack(DfMp3_PlaySource_Sd));
|
|
//readMP3state();
|
|
}
|
|
else if (c == 'h') // RESET
|
|
{
|
|
readMP3state();
|
|
}
|
|
else if (c == 'r') // RESET
|
|
{
|
|
Serial.println("Reset CPU");
|
|
NVIC_SystemReset(); // RESET SAMD21
|
|
}
|
|
else if (c == 'e') // RESET
|
|
{
|
|
Serial.println("Reset Ethernet");
|
|
digitalWrite(11, LOW); // Reset Ethernet Chip
|
|
delay(100);
|
|
digitalWrite(11, HIGH);
|
|
delay(100);
|
|
|
|
Ethernet.begin(mac, ip);
|
|
Udp.begin(destPort);
|
|
|
|
if (ARTNET_RX)
|
|
{
|
|
artnet.begin(mac, ip);
|
|
//artnet.setBroadcast(broadcast);
|
|
if (DEBUG)
|
|
Serial.println("Artnet Reader OK!");
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
delay(30); // 33 fps
|
|
|
|
}
|
|
|
|
|
|
void construct_arnet_packet()
|
|
{
|
|
//preparation pour tests
|
|
for (int i = 0; i < 7; i++)
|
|
{
|
|
ArtDmxBuffer[i] = ArtNetHead[i];
|
|
}
|
|
|
|
//Operator code low byte first
|
|
ArtDmxBuffer[8] = OpOutput;
|
|
ArtDmxBuffer[9] = OpOutput >> 8;
|
|
//protocole
|
|
ArtDmxBuffer[10] = 0;
|
|
ArtDmxBuffer[11] = 14;
|
|
//sequence
|
|
ArtDmxBuffer[12] = 0;
|
|
//physical
|
|
ArtDmxBuffer[13] = 0;
|
|
// universe
|
|
ArtDmxBuffer[14] = DMX_Universe ; // UNIVERSO
|
|
ArtDmxBuffer[15] = DMX_Universe >> 8; // SUBNET
|
|
//data length
|
|
ArtDmxBuffer[16] = number_of_channels >> 8;
|
|
ArtDmxBuffer[17] = number_of_channels;
|
|
|
|
for (int t = 0; t < number_of_channels; t++)
|
|
{
|
|
ArtDmxBuffer[t + art_net_header_size + 1] = buffer_dmx[t];
|
|
}
|
|
|
|
//Serial.println("Artnet universe");
|
|
//Serial.println(ArtDmxBuffer[14]);
|
|
//Serial.println(ArtDmxBuffer[15]);
|
|
|
|
}
|
|
|
|
|
|
void readMP3state()
|
|
{
|
|
|
|
mp3state = mp3.getPlaybackMode(); //read mp3 state
|
|
mp3vol = mp3.getVolume(); //read current volume
|
|
mp3eq = mp3.getEq(); //read EQ setting
|
|
mp3fileCounts = mp3.getTotalTrackCount(DfMp3_PlaySource_Sd); //read all file counts in SD card
|
|
mp3currentTrack = mp3.getCurrentTrack(DfMp3_PlaySource_Sd); //read current play file number
|
|
Serial.print("State: ");
|
|
Serial.println(mp3state);
|
|
Serial.print("Vol: ");
|
|
Serial.println(mp3vol);
|
|
Serial.print("Eq: ");
|
|
Serial.println(mp3eq);
|
|
Serial.print("Track: ");
|
|
Serial.println(mp3currentTrack);
|
|
|
|
}
|
|
|
|
|
|
void check_arduino_inputs()
|
|
{
|
|
//data from arduino aquisition
|
|
|
|
for (int i = 0; i < 6; i++) //reads the 6 analogic inputs and set the data from 1023 steps to 255 steps (dmx)
|
|
{
|
|
temp_val++;
|
|
if (temp_val > 255)
|
|
temp_val = 0;
|
|
|
|
//Serial.println(temp_val);
|
|
buffer_dmx[i] = byte(temp_val);
|
|
}
|
|
}
|
|
|
|
void check_sensor()
|
|
{
|
|
if ((digitalRead(sensorPin) == 0) && (sensorFlag == 0) )
|
|
{
|
|
if (DEBUG)
|
|
Serial.println("Sensor ON!");
|
|
|
|
delay(50); // antirebotes
|
|
sensorFlag = 1;
|
|
//rampState = 2;
|
|
rampState = 3;
|
|
inc = increment;
|
|
previousMillis = currentMillis; // activamos counter de inactividad
|
|
|
|
//int track = random(3) + 1;
|
|
|
|
//setPlaybackSource(DfMp3_PlaySource_Sd); //en caso de que este un tiempo encendido se despierta
|
|
mp3.stop(); // en caso de que este un tiempo encendido se despierta
|
|
delay(5);
|
|
mp3.playGlobalTrack(soundBank); //Play next mp3
|
|
|
|
if (DEBUG)
|
|
{
|
|
Serial.print("Play Track: ");
|
|
Serial.println(soundBank);
|
|
}
|
|
|
|
}
|
|
else if ((digitalRead(sensorPin) == 1) && (sensorFlag == 1 ) )
|
|
{
|
|
|
|
if (DEBUG)
|
|
Serial.println("Sensor OFF!");
|
|
|
|
delay(50); // antirebotes
|
|
sensorFlag = 0;
|
|
rampState = 1;
|
|
}
|
|
}
|
|
|
|
|
|
void ramp_up()
|
|
{
|
|
temp_val++;
|
|
if (temp_val > 255)
|
|
{
|
|
rampState = 0;
|
|
temp_val = 255;
|
|
}
|
|
//Serial.println(temp_val);
|
|
buffer_dmx[0] = byte(temp_val); // canal 1
|
|
}
|
|
|
|
|
|
void ramp_down()
|
|
{
|
|
temp_val--;
|
|
if (temp_val < 0)
|
|
{
|
|
rampState = 0;
|
|
temp_val = 0;
|
|
}
|
|
//Serial.println(temp_val);
|
|
buffer_dmx[0] = byte(temp_val); // canal 1
|
|
|
|
}
|
|
|
|
void triangle()
|
|
{
|
|
|
|
temp_val = temp_val + inc;
|
|
|
|
if (temp_val > 255)
|
|
{
|
|
inc = -increment;
|
|
temp_val = 255;
|
|
}
|
|
else if (temp_val < 0)
|
|
{
|
|
inc = increment;
|
|
rampState = 0;
|
|
temp_val = 0;
|
|
}
|
|
|
|
buffer_dmx[0] = byte(temp_val); // canal 1
|
|
|
|
}
|
|
|
|
//void sinus();
|