Lab_interaccio/2020/Audio-Ethernet (iguzzini)/DF-Ethernet-Feather/DF-Ethernet-Feather.ino
2025-02-25 21:29:42 +01:00

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();