Reading more than one Digital Input at the same time

Status
Not open for further replies.

GiGiUK

Active member
Hi

I need to be able to detect the changing states of more than one digital inputs at the same time and then cause an action, for example if two switches are activated. Could someone help me with this problem please. Also, is it better to use digital read or button0.falling edge for example? Ive added my code below:



if (button0.fallingEdge()) {
usbMIDI.sendNoteOn(60, 99, channel); // 60 = C4
}
if (button1.fallingEdge()) {
usbMIDI.sendNoteOn(61, 99, channel); // 61 = C#4
}
if (button2.fallingEdge()) {
usbMIDI.sendNoteOn(62, 99, channel); // 62 = D4
}


if (button0.risingEdge()) {
usbMIDI.sendNoteOff(60, 0, channel); // 60 = C4
}
if (button1.risingEdge()) {
usbMIDI.sendNoteOff(61, 0, channel); // 61 = C#4
}
if (button2.risingEdge()) {
usbMIDI.sendNoteOff(62, 0, channel); // 62 = D4
}
 
What Teensy is in use? How are the inputs changed? If manually by people that leaves a lot more room to determine 'at the same time'.
 
Hi Defragster

Teensy 3.2.

The inputs are changed manually, they are simple tactile switches. Essentially Im trying to create a musical project, the switches turn on the musical notes. Example, switch 1 = C4, switch 2 = D4, switch 2 and 3 together = E4...and so on...

thanks for your support, Im a Newbee
G.
 
Using the button code will remove bounces of [0,1,0,1, ...] on switch change that can trigger on pressing. Doing direct digital read could mistake this chatter as un-pressed when it is really pressed but not yet fully settled.

So the button code handles that uniformly and should give good results. RE: pjrc.com/teensy/td_libs_Bounce.html

Then the process would be reading switches in a way that those 'compounding' or adding to each other are considered before doing the sendNote().

Best if each switch/button value is read once for consideration so a nested if() might work.

In the end fine tuning might require in the end reading and recording the state of each button over a short time to allow for human activated 'at the same time' detection. That is the speed/order of the Teensy detecting one press may precede the arrival of the second simultaneous button.

It seems adjusting for that would suggest reading all button states to local vars at the start of each loop - then processing for the pressed buttons as a group before acting on them - that would need to include presses as well as releases to do needed NoteOff.
 
Hi Defragster

Thanks for the feedback, it makes sense what you said. I was thinking that I could implement a lookup table but I dont know how to do this, any ideas?

Also, Ive listed my complete code as Ive just noticed the forum rules:

#include <Bounce.h>

#define BREATH_CONTROLLER 2
#define MIDI_CHANNEL 1
#define CC_INTERVAL 20 // Send continuous controller message no more than every CC_INTERVAL milliseconds
#define BREATH_THRESHOLD 140 // Only send CC data if the pressure sensor reading a value larger than this.

const int channel = 1; // the MIDI channel number to send messages
unsigned long ccSendTime = 0L; // The last time we sent a CC value
int sensorValue; // The value read from the sensor
int ccVal; // The CC value we will send
int lastCcVal = 0; // The last CC value we sent

int analog_pin = 3;
int current_value;
int previous_value;

Bounce button0 = Bounce(0, 5);
Bounce button1 = Bounce(1, 5);
Bounce button2 = Bounce(2, 5);

void setup() {
pinMode(0, INPUT_PULLUP);
pinMode(1, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);
Serial.begin(9600); // initialize serial communication at 9600 bits per second:
}

void loop() {

button0.update();
button1.update();
button2.update();

if (button0.fallingEdge()) {
usbMIDI.sendNoteOn(60, 99, channel); // 60 = C4
}
if (button1.fallingEdge()) {
usbMIDI.sendNoteOn(61, 99, channel); // 61 = C#4
}
if (button2.fallingEdge()) {
usbMIDI.sendNoteOn(62, 99, channel); // 62 = D4
}


if (button0.risingEdge()) {
usbMIDI.sendNoteOff(60, 0, channel); // 60 = C4
}
if (button1.risingEdge()) {
usbMIDI.sendNoteOff(61, 0, channel); // 61 = C#4
}
if (button2.risingEdge()) {
usbMIDI.sendNoteOff(62, 0, channel); // 62 = D4
}

//This code is for note modulation
if (millis() - ccSendTime > CC_INTERVAL) { // Only read the sensor if enough time has passed
analogReadResolution(10); // set analog read resolution to 10 bits (a range of 0 - 16383)
sensorValue = analogRead(A2); // read the input on analog pin 2
if (sensorValue > BREATH_THRESHOLD) {
ccVal = lastCcVal = map(sensorValue, BREATH_THRESHOLD, 1023, 0, 127); // Map the value, which may range from BREATH_THRESHOLD to 1023, to a value in the range 0 to 127, which is // the valid range for a MIDI continuous controller
usbMIDI.sendControlChange(BREATH_CONTROLLER, ccVal, MIDI_CHANNEL); // And send the value as a MIDI CC message
ccSendTime = millis();

}
else if (lastCcVal > 0) { // The pressure has just dropped below the threshold, so
usbMIDI.sendControlChange(BREATH_CONTROLLER, 0, MIDI_CHANNEL); // send a CC value of zero
ccSendTime = millis();
lastCcVal = 0;
}

//This code is for note pitch bend
analogReadResolution(13); // set analog read resolution to 14 bits (a range of 0 - 16383)
analogReadAveraging(32); // set analg read averaging to 32 samples
previous_value = current_value; // store what was read last time
current_value = analogRead(analog_pin); // get a new reading
if(previous_value != current_value) { // if previous_value is not equal to current_value sendPitchBend
usbMIDI.sendPitchBend(current_value, 1); // send pitchbend message
}

//code for serial printer
Serial.print(sensorValue);
Serial.println();
delay(100); // delay 100 milliseconds (1/10 of a second)
}
}
 
Status
Not open for further replies.
Back
Top