#include <i2c_t3.h>
#include <MIDIUSB.h>
#define TARGET 0x10 // All faders to target value as fast as possible. PID state is cleared with each command.
#define FOLLOW 0x20
#define MESSAGE_LEN 17
elapsedMicros sinceFaderRead; // timer for fader check
unsigned int faderReadInterval = 1000;
elapsedMicros sinceFaderWrite; // timer for fader check
unsigned int faderWriteInterval = 20000;
int faderTouchCount;
uint8_t panelAddress = 0x66;
byte faderValueData[MESSAGE_LEN]; // 16 bytes for values, 1 byte for touch
byte faderTargetData[MESSAGE_LEN]; // 16 for target values, 1 byte for indicating which faders should be moved.
boolean faderTouched[8]; // boolean indicating if fader is touched
int faderValue[8]; // fader value ranging 0 to 1023
int faderTarget[8]; // fader target value ranging 0 to 1023
int faderMove[8]; // fader target value ranging 0 to 1023
int hi[8];
int lo[8];
int Gain[8];
void setup() {
//**** I2C *****
// Setup for Master mode, pins 18/19, external pullups, 1MHz, 200ms default timeout
Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, 1000000);
Wire.setDefaultTimeout(200000); // 200ms
usbMIDI.setHandleControlChange(myControlChange);
}
void loop() {
usbMIDI.read();
// substract interval to maintain schedule
// faders
if (sinceFaderRead >=faderReadInterval) {
sinceFaderRead = sinceFaderRead - faderReadInterval;
getFaderData();
}
if (sinceFaderWrite >=faderWriteInterval) {
sinceFaderWrite = sinceFaderWrite - faderWriteInterval;
sendFaderCommand(TARGET);
//if (linkMode!=LINK_OFF) handleLinkMode();
}
}
// get fader values and touch status
void getFaderData() {
size_t idx;
int incomingFaderValue[16]; //
int touchCount=0;
//ZeusPattern *currentPattern=&sequencerChannel[selectedChannel].pattern[sequencerChannel[selectedChannel].selectedPattern];
// Read from Slave
Wire.requestFrom(panelAddress, (size_t)MESSAGE_LEN); // Read from Slave
// Check if error occured
if(Wire.getError())
Serial.print("FAIL\n");
else
{
// If no error then read Rx data into buffer
idx = 0;
while(Wire.available()) faderValueData[idx++] = Wire.readByte();
// Process data in buffer
for (int i=0;i<8;i++){
// combine bytes back to integers and put in temporary array
incomingFaderValue[i]= faderValueData[(i*2)];
incomingFaderValue[i]= incomingFaderValue[i] << 8 | faderValueData[(i*2)+1];
// fill touch boolean array with last byte
faderTouched[i] = 1 & faderValueData[16] >> i;
if (faderTouched[i]) touchCount++;
//Serial.println(faderTouched[i*8]);
// check if faderValue needs to be updated
if (incomingFaderValue[i]!=faderValue[i] and faderTouched[i]){
faderValue[i]=incomingFaderValue[i];
faderValue[i] = map(faderValue[i], 0, 1023, 127, 0);
usbMIDI.sendControlChange(32, faderValue[0] , 1);
usbMIDI.sendControlChange(0, faderValue[0] , 1);
usbMIDI.sendControlChange(33, faderValue[1] , 1);
usbMIDI.sendControlChange(1, faderValue[1] , 1);
usbMIDI.sendControlChange(34, faderValue[2] , 1);
usbMIDI.sendControlChange(2, faderValue[2] , 1);
usbMIDI.sendControlChange(35, faderValue[3] , 1);
usbMIDI.sendControlChange(3, faderValue[3] , 1);
usbMIDI.sendControlChange(36, faderValue[4] , 1);
usbMIDI.sendControlChange(4, faderValue[4] , 1);
usbMIDI.sendControlChange(37, faderValue[5] , 1);
usbMIDI.sendControlChange(5, faderValue[5] , 1);
usbMIDI.sendControlChange(38, faderValue[6] , 1);
usbMIDI.sendControlChange(6, faderValue[6] , 1);
usbMIDI.sendControlChange(39, faderValue[7] , 1);
usbMIDI.sendControlChange(7, faderValue[7] , 1);
// currentPattern->step[i+j*8].value[selectedParameter]=map(faderValue[i+j*8],0,1023,parameterLimit[selectedParameter][0],parameterLimit[selectedParameter][1]);
// updateDisplayData=true;
Serial.print("Fader ");
Serial.print(i);
Serial.print("\t");
Serial.println(faderValue[i]);
}
}
faderTouchCount=touchCount;
}
}
// Send command with faderTarget array values to fader, TARGET or FOLLOW mode
void sendFaderCommand(byte mode){
size_t idx;
faderTargetData[16]=0;
for (int i=0;i<8;i++){
faderTargetData[(i*2)]=(faderTarget[i] >> 8) & 0xFF; // split Target integers over two bytes in array
faderTargetData[(i*2)+1]=faderTarget[i] & 0xFF;
faderTargetData[16] |= faderMove[i] << i; // fill last byte in array with faderMove boolean array
}
Wire.beginTransmission(panelAddress); // Transmit to Slave
Wire.write(mode); // Send mode (TARGET or FOLLOW)
for(idx = 0; idx < MESSAGE_LEN; idx++) Wire.write(faderTargetData[idx]); // Write data to I2C Tx buffer
Wire.endTransmission(); // Transmit to Slave
}
void myControlChange(byte channel, byte control, byte value) { // blink the LED a number of times
//value = map(value, 0, 127, 1023, 0);
//INT FADERS GAINS
if (control == 32) {
hi[0] = value;
}
if (control == 0) {
lo[0] = value;
Gain[0] = (hi[0] >> 7) + lo[0]*8.05;
}
if (control == 33) {
hi[1] = value;
}
if (control == 1) {
lo[1] = value;
Gain[1] = (hi[1] >> 7) + lo[1]*8.05;
}
if (control == 34) {
hi[2] = value;
}
if (control == 2) {
lo[2] = value;
Gain[2] = (hi[2] >> 7) + lo[2]*8.05;
}
if (control == 35) {
hi[3] = value;
}
if (control == 3) {
lo[3] = value;
Gain[3] = (hi[3] >> 7) + lo[3]*8.05;
}
if (control == 36) {
hi[4] = value;
}
if (control == 4) {
lo[4] = value;
Gain[4] = (hi[4] >> 7) + lo[4]*8.05;
}
if (control == 37) {
hi[5] = value;
}
if (control == 5) {
lo[5] = value;
Gain[5] = (hi[5] >> 7) + lo[5]*8.05;
}
if (control == 38) {
hi[6] = value;
}
if (control == 6) {
lo[6] = value;
Gain[6] = (hi[6] >> 7) + lo[6]*8.05;
}
if (control == 39) {
hi[7] = value;
}
if (control == 7) {
lo[7] = value;
Gain[7] = (hi[7] >> 7) + lo[7]*8.05;
}
for (int i=0; i<8; i++) {
// faderTarget[i] = Gain[i];
// faderTarget[i] = map(faderTarget[i], 0, 1023, 1023, 0);
// Serial.println(faderTarget[i]);
// Serial.println(faderMove[i]);
}
}