|
|
|
@ -17,30 +17,38 @@ |
|
|
|
|
#include <SoftwareSerial.h> |
|
|
|
|
#include <LiquidCrystal_I2C.h> |
|
|
|
|
#include <looper.h> |
|
|
|
|
|
|
|
|
|
#define MDNS_NAME "osc2midi" |
|
|
|
|
#define AP_SSID_NAME "OSC2MIDI" |
|
|
|
|
#define AP_PASSWORD "osc2midi" |
|
|
|
|
#define AP_SSID_CONFIG_NAME "OSC2MIDI-Config" |
|
|
|
|
#define AP_CONFIG_PASSWORD "osc2midi" |
|
|
|
|
#define SOFT_SERIAL_RX 18 |
|
|
|
|
#define SOFT_SERIAL_TX 19 |
|
|
|
|
#define AP_DATA_RESET_PIN 35 |
|
|
|
|
#define AP_MODE_PIN 34 |
|
|
|
|
#define LCD_I2C_ADDR 0x27 |
|
|
|
|
#define LCD_COL 16 |
|
|
|
|
#define LCD_ROW 2 |
|
|
|
|
#define UDP_RECV_PORT 8000 |
|
|
|
|
#define UDP_SEND_PORT 9000 |
|
|
|
|
#define KRATE_MODE 200 |
|
|
|
|
#define KRATE_STATE 2000 |
|
|
|
|
#include <SPIFFS.h> |
|
|
|
|
#include <ESPFlash.h> |
|
|
|
|
|
|
|
|
|
#define MDNS_NAME "osc2midi" |
|
|
|
|
#define AP_SSID_NAME "OSC2MIDI" |
|
|
|
|
#define AP_PASSWORD "osc2midi" |
|
|
|
|
#define AP_SSID_CONFIG_NAME "OSC2MIDI-Config" |
|
|
|
|
#define AP_CONFIG_PASSWORD "osc2midi" |
|
|
|
|
#define WIFI_CONNECT_TIMEOUT 30 |
|
|
|
|
#define CFG_PORTAL_TIMEOUT 90 |
|
|
|
|
#define SOFT_SERIAL_RX 18 |
|
|
|
|
#define SOFT_SERIAL_TX 19 |
|
|
|
|
#define AP_DATA_RESET_PIN 25 |
|
|
|
|
#define AP_MODE_PIN 26 |
|
|
|
|
#define LCD_I2C_ADDR 0x27 |
|
|
|
|
#define LCD_COL 16 |
|
|
|
|
#define LCD_ROW 2 |
|
|
|
|
#define UDP_RECV_PORT 8000 |
|
|
|
|
#define UDP_SEND_PORT 9000 |
|
|
|
|
#define KRATE_MODE 200 |
|
|
|
|
#define KRATE_STATE 2000 |
|
|
|
|
#define KRATE_RESET_AP_DATA 5000 |
|
|
|
|
#define KRATE_CHECK_WRITE_STATE 10000 |
|
|
|
|
#define LAST_USAGE_TIMER 5000 |
|
|
|
|
#define FORMAT_SPIFFS_IF_FAILED true |
|
|
|
|
|
|
|
|
|
void OSCToMidiCC(OSCMessage &msg, int offset); |
|
|
|
|
void MidiCCToOSC(uint8_t channel, uint8_t number, uint8_t value); |
|
|
|
|
void change_midi_state(uint8_t midichannel, uint8_t cc, uint8_t value); |
|
|
|
|
void show_midi_state(void); |
|
|
|
|
void set_midi_state(void); |
|
|
|
|
void check_mode(void); |
|
|
|
|
/*void change_midi_state(uint8_t midichannel, uint8_t cc, uint8_t value);
|
|
|
|
|
void show_midi_state(void); |
|
|
|
|
void set_midi_state(void); |
|
|
|
|
void check_mode(void);*/ |
|
|
|
|
|
|
|
|
|
WiFiUDP udp; |
|
|
|
|
IPAddress clientIP; |
|
|
|
@ -54,19 +62,29 @@ HardwareSerial midi1(2); // RX: 16, TX: 17 |
|
|
|
|
//#define TX (1)
|
|
|
|
|
#endif |
|
|
|
|
SoftwareSerial midi2; |
|
|
|
|
bool ap_mode_state = digitalRead(AP_MODE_PIN); |
|
|
|
|
int8_t state[16][128]; |
|
|
|
|
|
|
|
|
|
bool ap_mode_state; |
|
|
|
|
int8_t midistate[16 * 128]; |
|
|
|
|
bool last_reset_ap_check = false; |
|
|
|
|
looper sched; |
|
|
|
|
bool write_state = false; |
|
|
|
|
uint32_t last_usage = millis(); |
|
|
|
|
|
|
|
|
|
MIDI_CREATE_INSTANCE(HardwareSerial, midi1, MIDI1); |
|
|
|
|
|
|
|
|
|
void setup() |
|
|
|
|
{ |
|
|
|
|
pinMode(AP_DATA_RESET_PIN, INPUT_PULLUP); |
|
|
|
|
pinMode(AP_MODE_PIN, INPUT_PULLUP); |
|
|
|
|
|
|
|
|
|
Serial.begin(115200); |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("<SETUP>\n"); |
|
|
|
|
|
|
|
|
|
//Serial.print("FORMAT SPIFFS..."); SPIFFS.format(); Serial.println("done."); while (1);
|
|
|
|
|
|
|
|
|
|
memset(midistate, -1, 16 * 128); |
|
|
|
|
|
|
|
|
|
pinMode(AP_DATA_RESET_PIN, INPUT_PULLDOWN); |
|
|
|
|
pinMode(AP_MODE_PIN, INPUT_PULLDOWN); |
|
|
|
|
ap_mode_state = digitalRead(AP_MODE_PIN); |
|
|
|
|
|
|
|
|
|
Serial.setDebugOutput(true); |
|
|
|
|
Serial.println(F("OSC2MIDI (c)2020 H. Wirtz <wirtz@parasitstudio.de>")); |
|
|
|
|
|
|
|
|
@ -80,6 +98,20 @@ void setup() |
|
|
|
|
lcd.print(F("(c)parasiTstudio")); |
|
|
|
|
delay(1000); |
|
|
|
|
|
|
|
|
|
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
|
|
|
|
|
|
|
|
|
|
if (!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("An Error has occurred while mounting SPIFFS!"); |
|
|
|
|
lcd.clear(); |
|
|
|
|
lcd.setCursor(0, 0); |
|
|
|
|
lcd.print(F("SPIFFS ERROR")); |
|
|
|
|
lcd.setCursor(0, 1); |
|
|
|
|
lcd.print(F("Restarting...")); |
|
|
|
|
delay(1000); |
|
|
|
|
ESP.restart(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (ap_mode_state == LOW) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Mode Access-Point\n"); |
|
|
|
@ -108,31 +140,18 @@ void setup() |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Mode Client\n"); |
|
|
|
|
|
|
|
|
|
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
|
|
|
|
|
|
|
|
|
|
WiFiManager wm; |
|
|
|
|
|
|
|
|
|
if (digitalRead(AP_DATA_RESET_PIN) != LOW) |
|
|
|
|
{ |
|
|
|
|
wm.resetSettings(); |
|
|
|
|
DEBUG_MSG("Resetting AP data\n"); |
|
|
|
|
lcd.clear(); |
|
|
|
|
lcd.setCursor(0, 0); |
|
|
|
|
lcd.print(F("Resetting AP data")); |
|
|
|
|
delay(2000); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Automatically connect using saved credentials,
|
|
|
|
|
// if connection fails, it starts an access point with the specified name ( "AutoConnectAP"),
|
|
|
|
|
// if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect())
|
|
|
|
|
// then goes into a blocking loop awaiting configuration and will return success result
|
|
|
|
|
|
|
|
|
|
lcd.clear(); |
|
|
|
|
lcd.setCursor(0, 0); |
|
|
|
|
lcd.print(F("Mode Config-AP")); |
|
|
|
|
lcd.setCursor(0, 1); |
|
|
|
|
lcd.print(F("192.168.4.1")); |
|
|
|
|
|
|
|
|
|
wm.setConnectTimeout(WIFI_CONNECT_TIMEOUT); |
|
|
|
|
wm.setConfigPortalTimeout(CFG_PORTAL_TIMEOUT); |
|
|
|
|
wm.setBreakAfterConfig(true); |
|
|
|
|
|
|
|
|
|
if (!wm.autoConnect(AP_SSID_CONFIG_NAME, AP_CONFIG_PASSWORD)) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Failed to connect\n"); |
|
|
|
@ -163,8 +182,6 @@ void setup() |
|
|
|
|
lcd.print(WiFi.localIP()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
memset(state, -1, 16 * 128); |
|
|
|
|
|
|
|
|
|
udp.begin(UDP_RECV_PORT); |
|
|
|
|
DEBUG_MSG("Listening for UDP packets on port %d\n", UDP_RECV_PORT); |
|
|
|
|
|
|
|
|
@ -176,10 +193,16 @@ void setup() |
|
|
|
|
MIDI1.setHandleControlChange(MidiCCToOSC); |
|
|
|
|
MIDI1.turnThruOff(); |
|
|
|
|
|
|
|
|
|
//set_midi_state();
|
|
|
|
|
|
|
|
|
|
sched.addJob(check_mode, KRATE_MODE); |
|
|
|
|
sched.addJob(show_midi_state, KRATE_STATE); |
|
|
|
|
sched.addJob(check_reset_ap_data, KRATE_RESET_AP_DATA); |
|
|
|
|
sched.addJob(check_write_state, KRATE_CHECK_WRITE_STATE); |
|
|
|
|
//sched.addJob(show_midi_state, KRATE_STATE);
|
|
|
|
|
|
|
|
|
|
listDir(SPIFFS, "/", 1); |
|
|
|
|
//read_midistate(1);
|
|
|
|
|
show_midi_state(); |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("<LOOP>\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void loop() |
|
|
|
@ -190,10 +213,15 @@ void loop() |
|
|
|
|
|
|
|
|
|
size_t size = udp.parsePacket(); |
|
|
|
|
|
|
|
|
|
while (udp.available()) |
|
|
|
|
if (udp.available()) |
|
|
|
|
{ |
|
|
|
|
IPAddress tmpIP = udp.remoteIP(); |
|
|
|
|
|
|
|
|
|
// Keep track of the client IP address for "talking back"
|
|
|
|
|
if (clientIP != tmpIP) |
|
|
|
|
{ |
|
|
|
|
clientIP = tmpIP; |
|
|
|
|
DEBUG_MSG("New connection from: %d.%d.%d.%d\n", clientIP[0],clientIP[1],clientIP[2],clientIP[3]); |
|
|
|
|
} |
|
|
|
|
// Check if there are any OSC packets to handle
|
|
|
|
|
udp.read(buffer, size); |
|
|
|
|
msg.fill(buffer, size); |
|
|
|
@ -202,6 +230,7 @@ void loop() |
|
|
|
|
{ |
|
|
|
|
DEBUG_OSC_MESSAGE(msg); |
|
|
|
|
msg.route("/midi/cc", OSCToMidiCC); |
|
|
|
|
msg.route("/ping", ping); |
|
|
|
|
//msg.route("/midi/sysex", OSCToMidiSYSEX);
|
|
|
|
|
//msg.route("/midi/note", OSCToMidiNote);
|
|
|
|
|
} |
|
|
|
@ -209,13 +238,6 @@ void loop() |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Error parsing OSC message: %d\n", msg.getError()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Keep track of the client IP address for "talking back"
|
|
|
|
|
if (clientIP == tmpIP) |
|
|
|
|
{ |
|
|
|
|
clientIP = tmpIP; |
|
|
|
|
DEBUG_MSG("Connection from: %s", clientIP); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Check if there are any CC messages from synth itself
|
|
|
|
@ -269,13 +291,13 @@ void OSCToMidiCC(OSCMessage & msg, int offset) |
|
|
|
|
// XY pad, two values
|
|
|
|
|
cc = getVar(address, 1); |
|
|
|
|
value = round(msg.getFloat(0)); |
|
|
|
|
value = value > 127 ? 127 : value; |
|
|
|
|
value = constrain(value, 0, 127); |
|
|
|
|
DEBUG_MSG("MSG: % s\tChannel: % u\t\tCC: % u\tValue: % u\n", address, midichannel, cc, value); |
|
|
|
|
MIDI1.sendControlChange(cc, value, midichannel); |
|
|
|
|
change_midi_state(midichannel, cc, value); |
|
|
|
|
cc = getVar(address, 2); |
|
|
|
|
value = round(msg.getFloat(1)); |
|
|
|
|
value = value > 127 ? 127 : value; |
|
|
|
|
value = constrain(value, 0, 127); |
|
|
|
|
DEBUG_MSG("MSG: % s\tChannel: % u\t\tCC: % u\tValue: % u\n", address, midichannel, cc, value); |
|
|
|
|
MIDI1.sendControlChange(cc, value, midichannel); |
|
|
|
|
change_midi_state(midichannel, cc, value); |
|
|
|
@ -290,9 +312,17 @@ void MidiCCToOSC(uint8_t channel, uint8_t number, uint8_t val) |
|
|
|
|
{ |
|
|
|
|
char buffer[1024]; |
|
|
|
|
|
|
|
|
|
snprintf(buffer, sizeof(buffer), " / midi / cc / % u / % u", channel, number); |
|
|
|
|
if (channel < 1 && channel > 16) |
|
|
|
|
return; |
|
|
|
|
if (number > 127) |
|
|
|
|
return; |
|
|
|
|
val = constrain(val, 0, 127); |
|
|
|
|
|
|
|
|
|
snprintf(buffer, sizeof(buffer), "/midi/cc/%d/%d", channel, number); |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("MidiCCToOsc: %s %f\n", buffer, val); |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("MidiCCToOsc: % s % f\n", buffer, val * 1.0); |
|
|
|
|
change_midi_state(channel, number, val); |
|
|
|
|
|
|
|
|
|
if (clientIP) |
|
|
|
|
{ |
|
|
|
@ -302,12 +332,26 @@ void MidiCCToOSC(uint8_t channel, uint8_t number, uint8_t val) |
|
|
|
|
udp.beginPacket(clientIP, UDP_SEND_PORT); |
|
|
|
|
msg.send(udp); |
|
|
|
|
udp.endPacket(); |
|
|
|
|
|
|
|
|
|
msg.empty(); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("No client IP.\n"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void change_midi_state(uint8_t midichannel, uint8_t cc, uint8_t value) |
|
|
|
|
{ |
|
|
|
|
state[midichannel - 1][cc - 1] = value; |
|
|
|
|
last_usage = millis(); |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Setting internal state of MIDI Channel %2d CC#%02d to %d\n", midichannel, cc, int8_t(value)); |
|
|
|
|
|
|
|
|
|
if (midistate[(midichannel - 1) * 128 + cc - 1] != int8_t(value)) |
|
|
|
|
{ |
|
|
|
|
midistate[(midichannel - 1) * 128 + cc - 1] = int8_t(value); |
|
|
|
|
write_state = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void show_midi_state(void) |
|
|
|
@ -316,52 +360,227 @@ void show_midi_state(void) |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Current MIDI state:\n"); |
|
|
|
|
|
|
|
|
|
listDir(SPIFFS, "/", 1); |
|
|
|
|
|
|
|
|
|
for (m = 0; m < 16; m++) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("MIDI-Channel %d\n", m + 1); |
|
|
|
|
DEBUG_MSG("MIDI-Channel %2d\n", m + 1); |
|
|
|
|
for (c = 0; c < 128; c++) |
|
|
|
|
{ |
|
|
|
|
if (state[m][c] >= 0) |
|
|
|
|
if (midistate[m * 128 + c] >= 0) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("\tCC: %03d = %03d\n", c, state[m][c]); |
|
|
|
|
DEBUG_MSG("\tCC: %3d = %3d\n", c + 1, midistate[m * 128 + c]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
void set_midi_state(void) |
|
|
|
|
void check_mode(void) |
|
|
|
|
{ |
|
|
|
|
if (ap_mode_state != digitalRead(AP_MODE_PIN)) |
|
|
|
|
{ |
|
|
|
|
lcd.clear(); |
|
|
|
|
lcd.setCursor(0, 0); |
|
|
|
|
lcd.print("Changing mode..."); |
|
|
|
|
delay(500); |
|
|
|
|
ESP.restart(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void check_write_state(void) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Checking midi state.\n"); |
|
|
|
|
|
|
|
|
|
if (write_state == true && millis() - last_usage > LAST_USAGE_TIMER) |
|
|
|
|
{ |
|
|
|
|
uint8_t tmp; |
|
|
|
|
uint8_t m; |
|
|
|
|
uint16_t i; |
|
|
|
|
write_midistate(1); |
|
|
|
|
write_state = false; |
|
|
|
|
show_midi_state(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Send MIDI state:\n"); |
|
|
|
|
void write_midistate(uint8_t setup_number) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Write MIDI state\n"); |
|
|
|
|
|
|
|
|
|
for (m = 0; m < 16; m++); |
|
|
|
|
for (uint8_t m = 0; m < 16; m++) |
|
|
|
|
{ |
|
|
|
|
if (state[m].size() > 0) |
|
|
|
|
for (uint8_t c = 0; c < 128; c++) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("MIDI-Channel %d\n"); |
|
|
|
|
for (i = 0; i < state[m].size(); i++) |
|
|
|
|
if (midistate[m * 128 + c] >= 0) |
|
|
|
|
{ |
|
|
|
|
tmp = state[m].get(i); |
|
|
|
|
MIDI1.sendControlChange(tmp >> 4, tmp & 0x0f, m); |
|
|
|
|
DEBUG_MSG("\tSet state of CC: %03d = %03d\n", tmp >> 4, tmp & 0x0f); |
|
|
|
|
DEBUG_MSG("Found MIDI Channel %2d, CC#%2d = %3d\n", m, c, midistate[m * 128 + c]); |
|
|
|
|
|
|
|
|
|
char midi_cc_name[33]; |
|
|
|
|
int16_t tmp_val; |
|
|
|
|
|
|
|
|
|
sprintf(midi_cc_name, "/%d/midistate/%d/%d", setup_number, m, c); |
|
|
|
|
|
|
|
|
|
if (SPIFFS.exists(midi_cc_name)) |
|
|
|
|
{ |
|
|
|
|
File midi_cc = SPIFFS.open(midi_cc_name, "r"); |
|
|
|
|
if (midi_cc) |
|
|
|
|
{ |
|
|
|
|
tmp_val = midi_cc.read(); |
|
|
|
|
DEBUG_MSG("Data for MIDI Channel %d, CC %d exists: %d\n", m, c, tmp_val); |
|
|
|
|
} |
|
|
|
|
close(midi_cc); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
tmp_val = -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (midistate[m * 128 + c] != tmp_val) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG(" Change from %d to %d detected\n", tmp_val, midistate[m * 128 + c]); |
|
|
|
|
|
|
|
|
|
File midi_cc = SPIFFS.open(midi_cc_name, "w"); |
|
|
|
|
if (midi_cc) |
|
|
|
|
{ |
|
|
|
|
midi_cc.write(midistate[m * 128 + c]); |
|
|
|
|
midi_cc.flush(); |
|
|
|
|
DEBUG_MSG("Wrote %d to %s.\n", midistate[m * 128 + c], midi_cc_name); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
DEBUG_MSG("Cannot write to %s.\n", midi_cc_name); |
|
|
|
|
close(midi_cc); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void read_midistate(uint8_t setup_number) |
|
|
|
|
{ |
|
|
|
|
char setup_dir_name[33]; |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Read MIDI state\n"); |
|
|
|
|
|
|
|
|
|
sprintf(setup_dir_name, "/%d/midistate", setup_number); |
|
|
|
|
|
|
|
|
|
File midistate_dir = SPIFFS.open(setup_dir_name); |
|
|
|
|
|
|
|
|
|
if (!midistate_dir) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Failed to open directory %s.\n", setup_dir_name); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
void check_mode(void) |
|
|
|
|
if (!midistate_dir.isDirectory()) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("%s is not a directory.\n", setup_dir_name); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
File channel_cc = midistate_dir.openNextFile(); |
|
|
|
|
|
|
|
|
|
while (channel_cc) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Trying %s (Size: %d)\n", channel_cc.name(), channel_cc.size()); |
|
|
|
|
|
|
|
|
|
if (uint8_t(channel_cc.size()) == 1) |
|
|
|
|
{ |
|
|
|
|
if (!channel_cc.isDirectory()) |
|
|
|
|
{ |
|
|
|
|
char tmp_name[33]; |
|
|
|
|
uint8_t midi_channel; |
|
|
|
|
uint8_t midi_cc; |
|
|
|
|
uint8_t count = 0; |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Using %s\n", channel_cc.name()); |
|
|
|
|
|
|
|
|
|
strcpy(tmp_name, channel_cc.name()); |
|
|
|
|
for (String part = strtok(tmp_name, "/"); part; part = strtok(NULL, "/")) |
|
|
|
|
{ |
|
|
|
|
count++; |
|
|
|
|
if (count == 3) |
|
|
|
|
midi_channel = atoi(part.c_str()); |
|
|
|
|
else if (count == 4) |
|
|
|
|
midi_cc = atoi(part.c_str()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
File cc = SPIFFS.open(channel_cc.name(), "r"); |
|
|
|
|
if (cc) |
|
|
|
|
{ |
|
|
|
|
int8_t val = cc.read(); |
|
|
|
|
DEBUG_MSG(" MIDI-Channel %d CC#%d = %d\n", midi_channel + 1, midi_cc + 1, val); |
|
|
|
|
midistate[midi_channel * 128 + midi_cc] = val; |
|
|
|
|
MidiCCToOSC(midi_channel + 1, midi_cc + 1, val); |
|
|
|
|
cc.close(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Removing %s: not the right size.\n", channel_cc.name()); |
|
|
|
|
SPIFFS.remove(channel_cc.name()); |
|
|
|
|
} |
|
|
|
|
channel_cc = midistate_dir.openNextFile(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void check_reset_ap_data(void) |
|
|
|
|
{ |
|
|
|
|
if (ap_mode_state != digitalRead(AP_MODE_PIN)) |
|
|
|
|
if (digitalRead(AP_DATA_RESET_PIN) == HIGH && last_reset_ap_check == true) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Reset AP data\n"); |
|
|
|
|
|
|
|
|
|
WiFiManager wm; |
|
|
|
|
|
|
|
|
|
lcd.clear(); |
|
|
|
|
lcd.setCursor(0, 0); |
|
|
|
|
lcd.print("Changing mode..."); |
|
|
|
|
delay(500); |
|
|
|
|
lcd.print("Firmware reset"); |
|
|
|
|
wm.resetSettings(); |
|
|
|
|
SPIFFS.format(); |
|
|
|
|
lcd.setCursor(0, 1); |
|
|
|
|
lcd.print("Done."); |
|
|
|
|
delay(1000); |
|
|
|
|
ESP.restart(); |
|
|
|
|
} |
|
|
|
|
else if (digitalRead(AP_DATA_RESET_PIN) == HIGH) |
|
|
|
|
{ |
|
|
|
|
if (digitalRead(AP_DATA_RESET_PIN) == HIGH) |
|
|
|
|
DEBUG_MSG("Reset AP data pressed\n"); |
|
|
|
|
last_reset_ap_check = true; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
last_reset_ap_check = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ping(OSCMessage & msg, int offset) |
|
|
|
|
{ |
|
|
|
|
if (clientIP) |
|
|
|
|
read_midistate(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void listDir(fs::FS & fs, const char * dirname, uint8_t levels) { |
|
|
|
|
Serial.printf("Listing directory: %s\r\n", dirname); |
|
|
|
|
|
|
|
|
|
File root = fs.open(dirname); |
|
|
|
|
if (!root) { |
|
|
|
|
Serial.println("- failed to open directory"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (!root.isDirectory()) { |
|
|
|
|
Serial.println(" - not a directory"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
File file = root.openNextFile(); |
|
|
|
|
while (file) { |
|
|
|
|
if (file.isDirectory()) { |
|
|
|
|
Serial.print(" DIR : "); |
|
|
|
|
Serial.println(file.name()); |
|
|
|
|
if (levels) { |
|
|
|
|
listDir(fs, file.name(), levels - 1); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
Serial.print(" FILE: "); |
|
|
|
|
Serial.print(file.name()); |
|
|
|
|
Serial.print("\tSIZE: "); |
|
|
|
|
Serial.println(file.size()); |
|
|
|
|
} |
|
|
|
|
file = root.openNextFile(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|