intergalatico
Well-known member
Hello folks,
would someone help me to write a function to control my Boss SY 300 Guitar Synthesizer?
I managed to build and write the code for my Teensy based expression pedal with multiple CV outputs. (https://forum.pjrc.com/threads/44499-One-expression-pedal-multiple-devices)
Now I have this Boss unity and need to control with my expression pedal too. I am already using all CV outputs and the good thing is that the Boss accept MIDI messages from USB and Teensy can send MIDI messages from the USB jack.
I am not a programmer and with much stroggle (and help from you guys here) I wrote this code. But dealing with SysEx is a little beyond of me.
I would like to have a function just like the midi library, like:
MIDI.sendControlChange(controlNumber, controlValue, channel);
Here is the MIDI implementation pdf from the BOSS SY 300: https://static.roland.com/assets/media/pdf/SY-300_MIDI_Imple_e02.pdf
And here is what I suppose to be what I need:
And here is my code for the mentioned "Expressionator" (sorry for the mess):
I really appreciate any help!
Cheers!
would someone help me to write a function to control my Boss SY 300 Guitar Synthesizer?
I managed to build and write the code for my Teensy based expression pedal with multiple CV outputs. (https://forum.pjrc.com/threads/44499-One-expression-pedal-multiple-devices)
Now I have this Boss unity and need to control with my expression pedal too. I am already using all CV outputs and the good thing is that the Boss accept MIDI messages from USB and Teensy can send MIDI messages from the USB jack.
I am not a programmer and with much stroggle (and help from you guys here) I wrote this code. But dealing with SysEx is a little beyond of me.
I would like to have a function just like the midi library, like:
MIDI.sendControlChange(controlNumber, controlValue, channel);
Here is the MIDI implementation pdf from the BOSS SY 300: https://static.roland.com/assets/media/pdf/SY-300_MIDI_Imple_e02.pdf
And here is what I suppose to be what I need:
Code:
Control Change Number #1 - #31, #64 - #95
Status 2nd Byte 3rd Byte
------ -------- --------
BnH ccH vvH
n = MIDI Channel Number : 0H - FH(0 - 15) 0=ch.1 15=ch.16
cc = Control Change Number : 01H - 1FH(1 - 31) 40H - 5FH(64-95)
vv = Value : 00H - 7FH(0 - 127)
You can use control change messages from an USB (computer) to control functions that would bedifficult to control using the SY-300's own controllers.
"MIDI" In "Editing: Assigning Favorite Parameters to the Switches and External Pedals" of Owner's Manual, set "SOURCE NUMBER" to "CC#1-#31, CC#64-#95" and set "TARGET" to specify the parameter that will be controlled.
And here is my code for the mentioned "Expressionator" (sorry for the mess):
Code:
#include<ButtonV2.h>
#include <AH_MCP4922.h>
#include <ResponsiveAnalogRead.h>
// ButtonV2 Library
ButtonV2 Button1;
ButtonV2 Button2;
ButtonV2 Button3;
const byte ButtonPin1 = 18;
const byte ButtonPin2 = 17;
const byte ButtonPin3 = 16;
//MCP4922 Liybrary
//define AnalogOutput (MOSI_pin, SCK_pin, CS_pin, DAC_x, GAIN)
// Chip 1
AH_MCP4922 AnalogOutput1(11,13,10,LOW,HIGH); // DAC_A = LOW, DAC_B = High
AH_MCP4922 AnalogOutput2(11,13,10,HIGH,HIGH); // Gain 1x = HIGH, Gain 2x = LOW
// Chip 2
AH_MCP4922 AnalogOutput12(7,13,15,LOW,HIGH);
AH_MCP4922 AnalogOutput22(7,13,15,HIGH,HIGH);
ResponsiveAnalogRead analogOne(A5, true); // Define Pin and Sleep Enable
// For the Calibration:
const int sensorPin = A5;
int sensorValue = 0; // the sensor value
int hallSensorMin = 275; // minimum sensor value 1023
int hallSensorMax = 698; // maximum sensor value 0
int holdButtonInstant = 0;
//#define hallSensorMin 252 // The Hall Sensor is not already definetly fixed. This helps to quick adapt the values when the sensor moves
//#define hallSensorMax 772
int expressionPedalValueOld = 0;
int expressionPedalValue = 0;
int expressionPedalValueH9 = 0; // For the Eventide H9 the Max Vout should be 3.2V, the other ones 5V
int Vout1 = 0;
int Vout2 = 0;
int Vout3 = 0;
// Taper
int expressionTaper100 = 0;
int hallSensor = 0; // Raw hall sensor output
int taper = 0;
int val = 0;
//Arrays:
//out[] holds the values wanted in %
int out[] = { 0, 30, 45, 60, 65, 67, 70, 75, 80, 85, 90, 95, 100 };//13
// in[] holds the measured analogRead() values for defined % outputs
// note: the in array should have increasing values
int in[] = { 0, 5, 10, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100}; // 13
// RGB LEDS
int redPin1 = 4;
int greenPin1 = 3;
int bluePin1 = 5;
int redPin2 = 6;
int greenPin2 = 9;
int bluePin2 = 23;
int redPin3 = 22;
int greenPin3 = 21;
int bluePin3 = 20;
//Led State
bool led1State = false;
bool led2State = false;
bool led3State = false;
bool led4State = false;
//
void setup()
{
pinMode(ButtonPin1, INPUT_PULLUP);
pinMode(ButtonPin2, INPUT_PULLUP);
pinMode(ButtonPin3, INPUT_PULLUP);
//pinMode(LEDpin, OUTPUT);
pinMode(redPin1, OUTPUT);
pinMode(greenPin1, OUTPUT);
pinMode(bluePin1, OUTPUT);
pinMode(redPin2, OUTPUT);
pinMode(greenPin2, OUTPUT);
pinMode(bluePin2, OUTPUT);
pinMode(redPin3, OUTPUT);
pinMode(greenPin3, OUTPUT);
pinMode(bluePin3, OUTPUT);
Serial.begin(115200);
Serial.println("ready");
Button1.SetStateAndTime(LOW, 250);
Button2.SetStateAndTime(LOW, 250);
Button3.SetStateAndTime(LOW, 250);
// Calibration of the Hall Sensor on the first 5 seconds
/*while (millis() < 5000) {
analogOne.update();
sensorValue = analogOne.getValue();
// record the maximum sensor value
if (sensorValue > hallSensorMax) {
hallSensorMax = sensorValue;
}
// record the minimum sensor value
if (sensorValue < hallSensorMin) {
hallSensorMin = sensorValue;
}
setColor1(0, 20, 0);
setColor2(15, 0, 0);
setColor3(0, 0, 20);
}
setColor1(0, 0, 0);
setColor2(0, 0, 0);
setColor3(0, 0, 0);
*/
// Initial Value:
AnalogOutput1.setValue(1330); // H9 50%
AnalogOutput2.setValue(4095);
AnalogOutput12.setValue(4095);
AnalogOutput22.setValue(4095);
}
void loop()
{
analogOne.update();
hallSensor = analogOne.getValue();
//multiMap:
expressionTaper100 = map(hallSensor, hallSensorMin, hallSensorMax, 100, 0); // Turn the Values to 0 - 100 Range
val = expressionTaper100;
taper = multiMap(val, in, out, 13);
expressionPedalValue = map(taper, 0, 100, 0, 4095); // max 5V Vref=5.14 Vcc= 5.15
expressionPedalValueH9 = map(taper, 0, 100, 0, 2650); //max 3.2V
byte type1 = Button1.CheckButton(ButtonPin1); // current time and length of time to press the button as many times as you can ie. 1.5 seconds
switch (type1)
{
case WAITING:
break;
case PRESSED:
//AnalogOutput1.setValue(expressionPedalValue);
Serial.println("B1 pressed 1 time");
break;
case DOUBLE_PRESSED:
Serial.println("B1 pressed 2 times");
break;
case MULTI_PRESSED:
Serial.println("B1 pressed 3 times");
break;
case HELD:
Serial.println("B1 Button HELD");
holdButtonInstant = millis();
break;
}
byte type2 = Button2.CheckButton(ButtonPin2); // current time and length of time to press the button as many times as you can ie. 1.5 seconds
switch (type2)
{
case WAITING:
break;
case PRESSED:
Serial.println("B2 pressed 1 time");
break;
case DOUBLE_PRESSED:
Serial.println("B2 pressed 2 times");
break;
case MULTI_PRESSED:
Serial.println("B2 pressed 3 times");
break;
case HELD:
Serial.println("B2 Button HELD");
break;
}
byte type3 = Button3.CheckButton(ButtonPin3); // current time and length of time to press the button as many times as you can ie. 1.5 seconds
switch (type2)
{
case WAITING:
break;
case PRESSED:
Serial.println("B2 pressed 1 time");
break;
case DOUBLE_PRESSED:
Serial.println("B2 pressed 2 times");
break;
case MULTI_PRESSED:
Serial.println("B2 pressed 3 times");
break;
case HELD:
Serial.println("B2 Button HELD");
break;
}
Vout1 = map(expressionPedalValue, 4095, 0, 514, 0); // Output in Volts (5.14V = 514)
Vout2 = map(expressionPedalValue, 4095, 0, 514, 0); // Output in Volts (5.14V = 514)
Vout3 = map(expressionPedalValueH9, 2650, 0, 320, 0); // Output in Volts (3.2V = 320)
//Button 1
if (led1State == false) {
if (type1 == PRESSED){
setColor1(0, 20, 0); //Green
led1State = true;
}
}
else {
if (type1 == PRESSED){
setColor1(0, 0, 0);
led1State = false;
//AnalogOutput1.setValue(0);// Set the Vout when the Button is OFF
}
}
if (led1State == true && expressionPedalValue != expressionPedalValueOld){
AnalogOutput1.setValue(expressionPedalValueH9);
Serial.println("Vout1: ");
Serial.println(Vout1);
}
//expressionPedalValueOld = expressionPedalValue;
if (type1 == HELD) {
setColor1(10, 0, 10);
AnalogOutput1.setValue(2000);
led1State = false;
}
//Button 2
if (led2State == false) {
if (type2 == PRESSED){
setColor2(0, 15, 5); //Aqua
led2State = true;
}
}
else {
if (type2 == PRESSED){
setColor2(0, 0, 0);
led2State = false;
AnalogOutput2.setValue(4095);// Set the Vout when the Button is OFF
}
}
if (led2State == true && expressionPedalValue != expressionPedalValueOld){
AnalogOutput2.setValue(expressionPedalValue);
Serial.println("Vout2: ");
Serial.println(Vout2);
}
//expressionPedalValueOld = expressionPedalValue;
if (type2 == HELD) {
setColor2(10, 0, 10);
AnalogOutput2.setValue(2000);
led2State = false;
}
//Button 3
if (led3State == false) {
if (type3 == PRESSED){
setColor3(0, 0, 20);
led3State = true;
}
}
else {
if (type3 == PRESSED){
setColor3(0, 0, 0);
led3State = false;
led4State = false;
//AnalogOutput12.setValue(0);// Set the Vout when the Button is OFF
}
}
if (led3State == true && expressionPedalValue != expressionPedalValueOld){
AnalogOutput12.setValue(expressionPedalValue);
Serial.println("Vout3: ");
Serial.println(Vout3);
}
if (type3 == HELD) {
//setColor3(10, 0, 10);
//AnalogOutput12.setValue(2000);
//led3State = false;
}
// Output 4 (Ravish)
//Button 4
if (led4State == false) {
if (type3 == PRESSED){
}
}
else {
if (type3 == PRESSED){
//AnalogOutput12.setValue(0);// Set the Vout when the Button is OFF
}
}
if (led4State == true && expressionPedalValue != expressionPedalValueOld){
AnalogOutput22.setValue(expressionPedalValue);
}
if (type3 == HELD) {
setColor3(0, 10, 10);
led4State = true;
}
expressionPedalValueOld = expressionPedalValue;
delay(1);
// CALIBRATION
if (type1 == HELD && type2 == HELD){
// Calibration of the Hall Sensor on the first 5 seconds
while (millis() - holdButtonInstant < 5000) {
analogOne.update();
sensorValue = analogOne.getValue();
// record the maximum sensor value
if (sensorValue > hallSensorMax) {
hallSensorMax = sensorValue;
}
// record the minimum sensor value
if (sensorValue < hallSensorMin) {
hallSensorMin = sensorValue;
}
setColor1(5, 0, 0);
setColor2(10, 0, 0);
setColor3(15, 0, 0);
}
setColor1(0, 0, 0);
setColor2(0, 0, 0);
setColor3(0, 0, 0);
led1State = false;
led2State = false;
led3State = false;
}
delay(1);
Serial.print(" Min: ");
Serial.print(hallSensorMin);
Serial.print(" Max: ");
Serial.print(hallSensorMax);
Serial.print(" Hall Sensor: ");
Serial.print(hallSensor);
Serial.print(" Hall Sensor Constrain: ");
Serial.println(" ");
Serial.print("Vout1: ");
Serial.print(Vout1);
Serial.print(" Vout2: ");
Serial.print(Vout2);
Serial.print(" Vout3: ");
Serial.print(Vout3);
delay(1);
}
// RGB LED VOID
void setColor1(int red, int green, int blue)
{
#ifdef COMMON_ANODE
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
#endif
analogWrite(redPin1, red);
analogWrite(greenPin1, green);
analogWrite(bluePin1, blue);
}
void setColor2(int red, int green, int blue)
{
#ifdef COMMON_ANODE
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
#endif
analogWrite(redPin2, red);
analogWrite(greenPin2, green);
analogWrite(bluePin2, blue);
}
void setColor3(int red, int green, int blue)
{
#ifdef COMMON_ANODE
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
#endif
analogWrite(redPin3, red);
analogWrite(greenPin3, green);
analogWrite(bluePin3, blue);
}
/*
setColor(80, 0, 0); // red
setColor(0, 80, 0); // green
setColor(0, 0, 80); // blue
setColor(80, 80, 0); // yellow
setColor(80, 0, 80); // purple
setColor(0, 80, 80); // aqua
*/
// note: the _in array should have increasing values
int multiMap(int val, int* _in, int* _out, uint8_t size)
{
// take care the value is within range
// val = constrain(val, _in[0], _in[size-1]);
if (val <= _in[0]) return _out[0];
if (val >= _in[size-1]) return _out[size-1];
// search right interval
uint8_t pos = 1; // _in[0] allready tested
while(val > _in[pos]) pos++;
// this will handle all exact "points" in the _in array
if (val == _in[pos]) return _out[pos];
// interpolate in the right segment for the rest
return (val - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1];
}
I really appreciate any help!
Cheers!