So I'm working on an FSR-based midi controller, something like an M-Audio Trigger Finger. My problem is with the latency and response of the FSR. For extended presses, the velocity responds fine, but for quick touches it is only registering a velocty of 0-4, if that. It will only register different velocities after a continued hold of 100 or 200 ms.
Is this a weakness of FSR sensors, and why many still use piezo sensors? Or is there something sloppy about this code that is slowing it down?
Code:
//credit to thedude77
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
int fsrC = 0; //FSR is on pin 0
int fsrVal = 0; //variable for reading FSR value
int mappedFsrVal = 0; //variable for holding remapped FSR value
int prevFsrVal = 0; //variable for storing our prev FSR value
void setup() {
Serial.begin(115200);
}
void loop(){
fsrVal = analogRead(fsrC); //read input from FSR
mappedFsrVal = map(fsrVal, 0, 1000, 0, 127); //map value to 0-127
if(analogRead(fsrC)){//still too slow for instantaneous hits
// midiOUT(0xB0, 6, mappedFsrVal); //CC Volume message
midiOUT(0x90, 60, mappedFsrVal); //MIDI noteOn
midiOUT(0x80, 60, mappedFsrVal);//MIDI noteOff channel,note,velocity
delay(100);//
}
}
void midiOUT(char command, char value1, char value2) {
Serial.write(command);
Serial.write(value1);
Serial.write(value2);
}
My other issues is with rapid fire messages during a sensor hold, but I'll probably figure that out in time. Thanks all! XD
if(analogRead(fsrC)){//still too slow for instantaneous hits
Not sure why you are reading the analog pin again? Since the value read will always / often be greater than 0, the if statement will always / often execute anyway.
delay(100);//
There is a 100ms delay after sending the MIDI messages and before doing another analogRead(). So, this sets a minimum time before changing the pressure on the FSR will be noticed.
I'm trying to have the FSR trigger only one note when it is continuously pressed. Haven't seen a copy/paste solution yet, so I came up with a sort of placeholder value that changes any continued pressed to velocity CC's with a nested if. Probably not the most elegant approach. Getting a logic error though:
//credit to thedude77, roguescience
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
int fsrC = 0; //FSR is on pin 0
int fsrVal = 0; //variable for reading FSR value
int mappedFsrVal = 0; //variable for holding remapped FSR value
int prevFsrVal = 0; //variable for storing our prev FSR value
int holder = 0;
void setup() {
Serial.begin(115200);
}
void loop(){
fsrVal = analogRead(fsrC); //read input from FSR
mappedFsrVal = map(fsrVal, 100, 1000, 5, 127); //map value to 0-127
if(analogRead(fsrC)) && holder = 0
midiOUT(0x90, 60, mappedFsrVal); //MIDI noteOn
midiOUT(0x80, 60, mappedFsrVal);//MIDI noteOff channel,note,velocity
prevFsrVal = mappedFsrVal;
holder = holder +1
if(holder = 1 && analogRead(FsrC) {//break out of loop to stop rapid fire?
midiOUT(0xB0, 60, mappedFsrVal);
}
delay(100);//
}
}
void midiOUT(char command, char value1, char value2) {
Serial.write(command);
Serial.write(value1);
Serial.write(value2);
}