213 lines
5.5 KiB
Arduino
213 lines
5.5 KiB
Arduino
|
// Play a file from the SD card in looping mode, from the SD card.
|
||
|
// Example program to demonstrate the use of the MIDFile library
|
||
|
//
|
||
|
// Hardware required:
|
||
|
// SD card interface - change SD_SELECT for SPI comms
|
||
|
#include <SPI.h>
|
||
|
#include "wiring_private.h"
|
||
|
|
||
|
#include <Ethernet.h>
|
||
|
#include <EthernetUdp.h>
|
||
|
|
||
|
#include <SdFat.h>
|
||
|
#include <MD_MIDIFile.h>
|
||
|
|
||
|
#define DEBUG_ON 0 // set to 1 for MIDI output, 0 for debug output
|
||
|
#define GENERATE_TICKS 1
|
||
|
|
||
|
#define DEBUGS(s) SerialUSB.print(s)
|
||
|
#define DEBUG(s, x) { SerialUSB.print(F(s)); SerialUSB.print(x); }
|
||
|
#define DEBUGX(s, x) { SerialUSB.print(F(s)); SerialUSB.print(x, HEX); }
|
||
|
#define SERIAL_RATE 115200
|
||
|
|
||
|
|
||
|
byte mac[] = {
|
||
|
//0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01 // FEATHER 1
|
||
|
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x02 // FEATHER 2
|
||
|
};
|
||
|
|
||
|
IPAddress ip(192, 168, 8, 10); // IP FEATHER2
|
||
|
|
||
|
//const char ip[] = "192.168.8.10";
|
||
|
|
||
|
|
||
|
unsigned int localPort = 8888; // local port to listen on
|
||
|
unsigned int destPort[7] = { 2345, 2346, 2347, 2348, 2349, 2350, 2351 }; // TO SET SENDING PORT PLAYER
|
||
|
|
||
|
|
||
|
EthernetUDP Udp;
|
||
|
|
||
|
#define UDP_RX_PACKET_MAX_SIZE 8
|
||
|
|
||
|
// SD chip select pin for SPI comms.
|
||
|
// Arduino Ethernet shield, pin 4.
|
||
|
// Default SD chip select is the SPI SS pin (10).
|
||
|
// Other hardware will be different as documented for that hardware.
|
||
|
#define SD_SELECT 4
|
||
|
|
||
|
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
|
||
|
|
||
|
// The files in the tune list should be located on the SD card
|
||
|
// or an error will occur opening the file and the next in the
|
||
|
// list will be opened (skips errors).
|
||
|
const char *loopfile = "final.mid"; // simple and short file
|
||
|
#if GENERATE_TICKS
|
||
|
uint32_t lclBPM = 105;
|
||
|
//uint32_t lclBPM = 60;
|
||
|
//uint32_t lclBPM = 30;
|
||
|
#endif
|
||
|
|
||
|
SdFat SD;
|
||
|
MD_MIDIFile SMF;
|
||
|
|
||
|
byte state_ = 0;
|
||
|
byte channel_ = 0;
|
||
|
byte intensity_ = 0;
|
||
|
|
||
|
char* outIp[8] = {"192.168.8.116", "192.168.8.117", "192.168.8.118", "192.168.8.119", "192.168.8.120", "192.168.8.121", "192.168.8.122", "192.168.8.255"};;
|
||
|
int pinOut[6] = {A0, A1, A2, A3, A4, A5};
|
||
|
|
||
|
void OSCSend(int out, char* val)
|
||
|
{
|
||
|
// Udp.beginPacket(outIp[7], destPort[out]);
|
||
|
// Udp.printf(val);
|
||
|
// Udp.endPacket(); // mark the end of the OSC Packet
|
||
|
}
|
||
|
|
||
|
void midiCallback(midi_event *pev)
|
||
|
{
|
||
|
#if DEBUG_ON
|
||
|
DEBUG("M T", pev->track);
|
||
|
DEBUG(": Ch ", pev->channel+1);
|
||
|
DEBUGS(" Data");
|
||
|
#endif
|
||
|
state_ = pev->data[0];
|
||
|
channel_ = pev->data[1];
|
||
|
intensity_ = pev->data[2];
|
||
|
#if DEBUG_ON
|
||
|
DEBUGX(" ", state_);
|
||
|
DEBUGX(" ", channel_);
|
||
|
DEBUGX(" ", intensity_);
|
||
|
SerialUSB.print(" ");
|
||
|
SerialUSB.print((channel_-0x24), HEX);
|
||
|
#endif
|
||
|
if (intensity_>0)
|
||
|
{
|
||
|
OSCSend(channel_-0x24, "1");
|
||
|
digitalWrite(pinOut[channel_-0x24], HIGH);
|
||
|
//digitalWrite(pin_out[channel_-0x24], HIGH);
|
||
|
#if DEBUG_ON
|
||
|
SerialUSB.println(" Solenoide ON");
|
||
|
#endif
|
||
|
}
|
||
|
else digitalWrite(pinOut[channel_-0x24], LOW);
|
||
|
}
|
||
|
|
||
|
#if GENERATE_TICKS
|
||
|
uint16_t tickClock(void)
|
||
|
// Check if enough time has passed for a MIDI tick and work out how many!
|
||
|
{
|
||
|
static uint32_t lastTickCheckTime, lastTickError;
|
||
|
uint8_t ticks = 0;
|
||
|
lclBPM= map(analogRead(A5), 0, 1023, 60, 300);
|
||
|
SerialUSB.println(lclBPM);
|
||
|
uint32_t elapsedTime = lastTickError + micros() - lastTickCheckTime;
|
||
|
uint32_t tickTime = (60 * 1000000L) / (lclBPM * SMF.getTicksPerQuarterNote()); // microseconds per tick
|
||
|
tickTime = (tickTime * 4) / (SMF.getTimeSignature() & 0xf); // Adjusted for time signature
|
||
|
|
||
|
if (elapsedTime >= tickTime)
|
||
|
{
|
||
|
ticks = elapsedTime/tickTime;
|
||
|
lastTickError = elapsedTime - (tickTime * ticks);
|
||
|
lastTickCheckTime = micros(); // save for next round of checks
|
||
|
}
|
||
|
|
||
|
return(ticks);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
void setup(void)
|
||
|
{
|
||
|
int err;
|
||
|
SerialUSB.begin(SERIAL_RATE);
|
||
|
delay(4000);
|
||
|
SerialUSB.println("Hola");
|
||
|
|
||
|
// start the Ethernet and UDP:
|
||
|
Ethernet.begin(mac, ip);
|
||
|
|
||
|
// Check for Ethernet hardware present
|
||
|
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
|
||
|
SerialUSB.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) {
|
||
|
SerialUSB.println("Ethernet cable is not connected.");
|
||
|
}
|
||
|
|
||
|
Udp.begin(localPort);
|
||
|
|
||
|
for (int i= 0; i<6; i++)
|
||
|
{
|
||
|
pinMode(pinOut[i], OUTPUT);
|
||
|
digitalWrite(pinOut[i], LOW);
|
||
|
}
|
||
|
|
||
|
DEBUGS("\n[MidiFile Looper]");
|
||
|
// Initialize SD
|
||
|
if (!SD.begin(SD_SELECT, SPI_FULL_SPEED))
|
||
|
{
|
||
|
DEBUGS("\nSD init fail!");
|
||
|
while (true) ;
|
||
|
}
|
||
|
|
||
|
// Initialize MIDIFile
|
||
|
SMF.begin(&SD);
|
||
|
SMF.setMidiHandler(midiCallback);
|
||
|
SMF.looping(true);
|
||
|
|
||
|
// use the next file name and play it
|
||
|
DEBUG("\nFile: ", loopfile);
|
||
|
SMF.setFilename(loopfile);
|
||
|
err = SMF.load();
|
||
|
if (err != -1)
|
||
|
{
|
||
|
DEBUG("\nSMF load Error ", err);
|
||
|
while (true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void loop(void)
|
||
|
{
|
||
|
// OSCSend(0, "1");
|
||
|
// delay(500);
|
||
|
#if GENERATE_TICKS
|
||
|
static bool fBeat = false;
|
||
|
static uint16_t sumTicks = 0;
|
||
|
uint32_t ticks = tickClock();
|
||
|
|
||
|
if (ticks > 0)
|
||
|
{
|
||
|
//LCDBeat(fBeat);
|
||
|
SMF.processEvents(ticks);
|
||
|
SMF.isEOF(); // side effect to cause restart at EOF if looping
|
||
|
//LCDbpm();
|
||
|
|
||
|
sumTicks += ticks;
|
||
|
if (sumTicks >= SMF.getTicksPerQuarterNote())
|
||
|
{
|
||
|
sumTicks = 0;
|
||
|
fBeat = !fBeat;
|
||
|
}
|
||
|
}
|
||
|
#else
|
||
|
// play the file
|
||
|
if (!SMF.isEOF())
|
||
|
{
|
||
|
SMF.getNextEvent();
|
||
|
}
|
||
|
#endif
|
||
|
}
|