Somehow, at some point, some weeks ago, I pictured myself with a kaputt Hammond from the 70s with 88 keys somehow repaired and even converted to the MIDI religion. That happened maybe one week ago, while I found out that some midi could be not bad as an additional protocol for a musical project that I´m currently developing. So, I discovered that the best way would be the Teensy and I went for it even knowing that I would have to better have some notions of programming which i knew i just didnt have, and that already deciding to try to acquire them if it would be extremely necessary to maybe really acquire them for really being able to fulfill the ambicious obsession of conveying the dusty soul of the hammond into a Midified corpse.
So, I guess I have the elements (Teensy 3.2, Multiplexers, cables, 10K resistors, Kraft, etc) and I have aswell a week of info from here and other places and tryouts by trying to mix one of the codes I found from Oddson for MUXes with potentiometers and buttons with some multiplexers and another code from this same forum (that I modified a bit) about some Force sensitive Resistors working as triggers of notes with sensibility. The problem is this: I just cannot get this code (below) work with the other code (more below) even that I tried to tweak it (not really knowing the sources or really understanding the source or the functions of certain symbols of the code) so far achieving all sorts of crazy behaviours from the midi electric piano vst and another midi-thing, mostly related to triggering just all the 16 notes of one of the 74hc4076 MUX (only one for trying out) by pressing only one of the multiplexed analog inputs and shaping like this only odd strange eclectic melodies that were playd by itself or by a rather invisible entity rather than me and other weird things like emulating some sort of sinthetizersounds.. which I liked and not at the same time, and so on...
This are the codes (I would really apreciate some help with this. since I´m really far from being a programmer even though I really like playing with keys)
IVe tryied withe THE MUX ONE (from Oddson) ....
(THE FSR ONE)
And as well with this other code that already contains my sort of interaction with it (which consisted mostly in copy past and then tweaking it till I could understand a bit more and more getting excited with it till I didnt have no clue anymore and getting very frustrated by it) (Originally the code its supposed to be for more than one MUX and for POTS and BUTTONS but I reduced it into 1 MUX of 16 inputs for Testing (6 connected to homemade FSR´s that worked so far with the first code above and without the multiplexer, and with this one (one MUX) being just peaks of voltage going up after some aplied pressure according to the Serial Plotter of the Arduino... and being just the sixteen notes of the array Note[A_PINS] played very fast one after another or in weird secuences after pressing one single FSR sensor... and the same with each one of them...
Thanks in advance !
So, I guess I have the elements (Teensy 3.2, Multiplexers, cables, 10K resistors, Kraft, etc) and I have aswell a week of info from here and other places and tryouts by trying to mix one of the codes I found from Oddson for MUXes with potentiometers and buttons with some multiplexers and another code from this same forum (that I modified a bit) about some Force sensitive Resistors working as triggers of notes with sensibility. The problem is this: I just cannot get this code (below) work with the other code (more below) even that I tried to tweak it (not really knowing the sources or really understanding the source or the functions of certain symbols of the code) so far achieving all sorts of crazy behaviours from the midi electric piano vst and another midi-thing, mostly related to triggering just all the 16 notes of one of the 74hc4076 MUX (only one for trying out) by pressing only one of the multiplexed analog inputs and shaping like this only odd strange eclectic melodies that were playd by itself or by a rather invisible entity rather than me and other weird things like emulating some sort of sinthetizersounds.. which I liked and not at the same time, and so on...
This are the codes (I would really apreciate some help with this. since I´m really far from being a programmer even though I really like playing with keys)
IVe tryied withe THE MUX ONE (from Oddson) ....
Code:
//************LIBRARIES USED**************
// include the ResponsiveAnalogRead library for analog smoothing
#include <ResponsiveAnalogRead.h>
#include <Bounce.h> // need the bounce library to stabilize signals from switch contacts
//usbMIDI.h library is added automatically when code is compiled as a MIDI device
// ******CONSTANT VALUES********
// customize code behaviour here!
//**TIMING -- higher is more stable, lower more responsive
const int muxTimeMin = 500; // minimum micro-seconds between MUX reads - 500 = half a millisecond!
const int BOUNCE_TIME = 15; // max time before the physical contacts of switches settle.
//**HARDWARE
const int MUX_PINS = 16; // number of MUX Channnels
//mux control out pin assignement
const int pin_Out_S0 = 0;
const int pin_Out_S1 = 1;
const int pin_Out_S2 = 2;
const int pin_Out_S3 = 3;
//data from mux pin assignement
const int pin_In_Mux1 = A1;
const int pin_In_Mux2 = A2;
const int pin_In_Mux3 = 4; // data pin of 'digital' MUX
//**MIDI
const int channel = 1; // MIDI channel
const int CCID1[MUX_PINS] = {21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36}; // CC (D1) values for analog MUX one
const int CCID2[MUX_PINS] = {41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56}; // CC (D1) values for analog MUX two
const int note[MUX_PINS] = {48,49,50,54,52,53,54,55,56,57,58,59}; // note values for MUX3 (digital section)
const int ON_VELOCITY = 105; // note velocity for note on events
//******VARIABLES***********
// a data array and a lagged copy to tell when MIDI changes are required
byte data1[MUX_PINS];
byte data1Lag[MUX_PINS]; // when lag and new are not the same then update MIDI CC value
//amd again for second MUX
byte data2[MUX_PINS];
byte data2Lag[MUX_PINS]; // ditto
//third mux don't need memory!
//NB - index variable i is incremented and rolled over manually inside the main loop so that on each pass one MUX pin is read.
byte i=0; // global index for MUX channel reads
//****** TIMER VARIABLE *** change scale here!
elapsedMicros muxUpdated; // switch to micros to run at speed and tune with muxTimeMin setting above
//elapsedMillis muxUpdated; // switch to millis to troubleshoot
//************INITIALIZE LIBRARY OBJECTS**************
// initialize the ReponsiveAnalogRead objects
ResponsiveAnalogRead analog1[]{
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true},
{pin_In_Mux1 ,true}
};
ResponsiveAnalogRead analog2[]{
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true},
{pin_In_Mux2 ,true}
};
// initialize the bounce objects all to the same MUX data pin
Bounce digital[] = {
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME),
Bounce(pin_In_Mux3,BOUNCE_TIME)
};
//************SETUP**************
void setup() {
//! don't forget to set for output!
pinMode(pin_Out_S0, OUTPUT);
pinMode(pin_Out_S1, OUTPUT);
pinMode(pin_Out_S2, OUTPUT);
pinMode(pin_Out_S3, OUTPUT);
}
//************LOOP**************
void loop() {
nextMUXpin();
while (usbMIDI.read()) {
// controllers must call .read() to keep the queue clear even if they are not responding to MIDI
}
}
//************MUX SECTION**************
void nextMUXpin(){
if (muxUpdated>muxTimeMin) {
// update the ResponsiveAnalogRead object every loop
// read PIN i of MUX 1
analog1[i].update();
// if the repsonsive value has change, print out 'changed'
if(analog1[i].hasChanged()) {
data1[i] = analog1[i].getValue()>>3;
if (data1[i] != data1Lag[i]){
data1Lag[i] = data1[i];
usbMIDI.sendControlChange(CCID1[i], data1[i], channel);
}
}
// read PIN i of MUX 2
analog2[i].update();
// if the repsonsive value has change, print out 'changed'
if(analog2[i].hasChanged()) {
data2[i] = analog2[i].getValue()>>3;
if (data2[i] != data2Lag[i]){
data2Lag[i] = data2[i];
usbMIDI.sendControlChange(CCID2[i], data2[i], channel);
}
}
// read PIN i of MUX 3 (DIGITAL!)
digital[i].update();
if (digital[i].fallingEdge()) {
usbMIDI.sendNoteOn(note[i], ON_VELOCITY, channel);
}
// Note Off messages when each button is released
if (digital[i].risingEdge()) {
usbMIDI.sendNoteOff(note[i], 0, channel);
}
}
//reset timer
muxUpdated = 0;
//increment index
i++;
if (i>15) {i=0;}
// set mux control pins for next pass
digitalWrite(pin_Out_S0, HIGH && (i & B00000001));
digitalWrite(pin_Out_S1, HIGH && (i & B00000010));
digitalWrite(pin_Out_S2, HIGH && (i & B00000100));
digitalWrite(pin_Out_S3, HIGH && (i & B00001000));
}
(THE FSR ONE)
Code:
#include <ResponsiveAnalogRead.h>
const int pinCount = 1;
const int velocityThreshold = 45;
const int afterThreshold = 50;
const int velocityTime = 500;
const int afterTime = 2500;
const int defaultMax = 100;
const float chargeTime = 1; //rise time for external capacitors in us.
int VELMASK = 0;
int ATMASK = 0;
ResponsiveAnalogRead pinReader[pinCount] = {
ResponsiveAnalogRead(A4,true),
};
int pin[] = {A4};
int note[] = {38}; //MIDI notes
const int midiMin = 20;
int pinMin[pinCount];
int pinMax[pinCount];
int pinTimer[pinCount];
void setup() {
Serial.begin (32500);
}
void loop () {
for (int i = 0; i < pinCount; i++) {
pinReader[i].update();
int value = pinReader[i].getValue();
int velocity = map (value, 0, 800, midiMin, 127);
int aftertouch = map (value, 0, 800, midiMin, 127);
if (value > velocityThreshold)
{
pin[i] ++;
if (!(VELMASK & (1 << i)) && (pin[i] == velocityTime)) {
usbMIDI.sendNoteOn (note[i], velocity, 1);
VELMASK |= (1 << i);
pin[i] = 0;
}
if (pin[i] == afterTime) {
usbMIDI.sendPolyPressure (note[i], aftertouch, 1);
pin[i] = 0;
}
}
else {
if (VELMASK & (1 << i)) {
usbMIDI.sendNoteOff (note[i], 0, 1);
VELMASK &= ~ (1 << i);
pin[i] = 0;
}
}
}
}
And as well with this other code that already contains my sort of interaction with it (which consisted mostly in copy past and then tweaking it till I could understand a bit more and more getting excited with it till I didnt have no clue anymore and getting very frustrated by it) (Originally the code its supposed to be for more than one MUX and for POTS and BUTTONS but I reduced it into 1 MUX of 16 inputs for Testing (6 connected to homemade FSR´s that worked so far with the first code above and without the multiplexer, and with this one (one MUX) being just peaks of voltage going up after some aplied pressure according to the Serial Plotter of the Arduino... and being just the sixteen notes of the array Note[A_PINS] played very fast one after another or in weird secuences after pressing one single FSR sensor... and the same with each one of them...
Code:
// ******CONSTANT VALUES********
// customize code behaviour here!
const int muxTimeMin = 50; // minimum micro-seconds between MUX reads
const int channel = 0; // MIDI channel
const int A_PINS = 16; // number of Analog PINS (these are now MUX pins)
// define the CC ID numbers on which to send them..
const int Note[A_PINS] = {51,52,53,54,55,56,57,58,59,20,31,55,39,34,35,36}; // set your own CC values for the 16 MUX pins
int midiMin = 20;
const int dbt = 100; // a threshold value for how big the dead-band is before recalc
const int velocityTime = 80;
const int afterTime = 1500;
const int defaultMax = 100;
const float chargeTime = 1; //rise time for external capacitors in us.
int VELMASK = 0;
int ATMASK = 0;
int VELTHRESH = 0;
//******VARIABLES***********
//mapping of mux to teensy digital pins
int pin_Out_S0 = 1;
int pin_Out_S1 = 2;
int pin_Out_S2 = 3;
int pin_Out_S3 = 4;
int pin_In_Mux1 = {A4};
//the state of the mux channels(initialized to zero)
int Mux1_State[16] = {0};
int Mux1_State_Lagged[16] = {0};
elapsedMicros mux1Updated;
//elapsedMillis mux1Updated; // switch to millis to troubleshoot
byte i = 0; // index for mux loop
void setup() {
//! don't forget to set for output!
pinMode(pin_Out_S0, OUTPUT);
pinMode(pin_Out_S1, OUTPUT);
pinMode(pin_Out_S2, OUTPUT);
pinMode(pin_Out_S3, OUTPUT);
}
//************LOOP**************
void loop() {
getMUX1Data();
// other work here... mux is called once in each loop rather than updating all in every loop
while (usbMIDI.read()) {
// controllers must call .read() to keep the queue clear even if they are not responding to MIDI
}
}
//************MUX1 SECTION**************
void getMUX1Data(){
if (mux1Updated>muxTimeMin)
delayMicroseconds(80);
{
Mux1_State[i] = analogRead(pin_In_Mux1);
if(abs(Mux1_State[i] - Mux1_State_Lagged[i]) > dbt ) {
(Mux1_State_Lagged[i] = Mux1_State[i]);
int velocity = map (Mux1_State[i]>>3, 0, 800, midiMin, 127);
int aftertouch = map (Mux1_State[i]>>3, 0, 800, midiMin, 127);
if ((VELMASK & (2 << Mux1_State[i])) && (Mux1_State[i]>>3 == velocityTime)) {
usbMIDI.sendNoteOn (Note[i], velocity, channel);
}
if (Mux1_State[i]>>3 == afterTime) {
usbMIDI.sendPolyPressure (Note[i], aftertouch, channel);
}
}
else {
if (VELMASK & (1 << Mux1_State[i]>>3)) {
usbMIDI.sendNoteOff (Note[i], 0, channel);
VELMASK = (1 << Mux1_State[i]);
}
serialPringMIDIdata(); // use to troublshoot
delayMicroseconds(50);
}
//reset timer
mux1Updated = 0;
//increment index
i++;
if (i>15) {i=0;}
// set mux control pins for next pass
digitalWrite(pin_Out_S0, HIGH && (i & B00000001));
digitalWrite(pin_Out_S1, HIGH && (i & B00000010));
digitalWrite(pin_Out_S2, HIGH && (i & B00000100));
digitalWrite(pin_Out_S3, HIGH && (i & B00001000));
}
}
// ****useful for debugging, comment out function call to run full speed
void serialPringMIDIdata(){
Serial.print(i,DEC);
Serial.print(" :");
Serial.print(HIGH && (i & B00000001),BIN);
Serial.print(HIGH && (i & B00000010),BIN);
Serial.print(HIGH && (i & B00000100),BIN);
Serial.print(HIGH && (i & B00001000),BIN);
Serial.print(" MUX_PIN: ");
Serial.print(i,DEC);
Serial.print(" Note: ");
Serial.print(Note[i],DEC);
Serial.print(" MUX1 HEX: ");
Serial.println(Mux1_State[i],HEX);
}