0

I have an issue with this piece of code concerning the use of 3 capcitance sensors each outputting a midi note chosen from one of three scales selected with a pot. Regarding the sensors triggering notes and the pot selecting scales, everything is perfect. However, each sensor will play each of the scale's notes by itself with each finger press. This of course is not what I am intending as each sensor should only trigger its corresponding note. Thanks for any clues and tips!!

    #include <SPI.h>
#include <CapacitiveSensor.h>
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
// midi notes
int c3 = 36;
int d3 = 38;
int e3 = 40;
int g3 = 43;
int a3 = 45;
int c4 = 48;
int d4 = 50;
int e4 = 52;
int g4 = 55;
int a4 = 57;
int c5 = 60;
int d5 = 62;
int e5 = 64;
int g5 = 67;
int a5 = 69;
int c6 = 72;

/////// code & 2d array for scale selection
const int columns = 3;
const int scales = 3;
int potVal = 0;
const int  notes[scales][columns] = {
  {c3, d3, e3},
  {c4, d4, e4},
  {c5, d5, e5}
};

const int numberOfSensors = 3;
int sensorPin[numberOfSensors] = {38, 39, 40};
/////////

static const unsigned ledPin1 = 22;      // LED pin on Arduino Mega
static const unsigned ledPin2 = 23;
static const unsigned ledPin3 = 24;

int val = 10; // this value is best around "10". works with "multiply"
// and "Threshold" to enable Polyphony!
int Threshold = (0); //Threshold of triggered mp3
int Multiply = (0);  //increases or decreases the overal sensitivity

CapacitiveSensor   cs_2_38 = CapacitiveSensor(2, 38); //Mega sensor pins
CapacitiveSensor   cs_2_39 = CapacitiveSensor(2, 39);
CapacitiveSensor   cs_2_40 = CapacitiveSensor(2, 40);

void setup()
{
  for (int i = 0; i < numberOfSensors; i++) {
    pinMode(sensorPin[i], INPUT);
    Serial.begin(9600); //midi(31250)

    pinMode(ledPin1, OUTPUT);
    pinMode(ledPin2, OUTPUT);
    pinMode(ledPin3, OUTPUT);

  }
}
void loop()
{
  int potVal = map(analogRead(A2), 0, 1024, 0, 3);
  for (int i = 0; i < numberOfSensors; i++) {
    checkSensor(potVal, i);
  }
}
void checkSensor(int scaleIndex, int columnIndex)
{
  static boolean lastSensorHit1 = false;
  static boolean lastSensorHit2 = false;
  static boolean lastSensorHit3 = false;

  bool sensorHit3 = cs_2_40.capacitiveSensor(Multiply) / val > (Threshold);
  bool sensorHit2 = cs_2_39.capacitiveSensor(Multiply) / val > (Threshold);
  bool sensorHit1 = cs_2_38.capacitiveSensor(Multiply) / val > (Threshold);


  Multiply = map(analogRead(A0), 0, 1023, 150, 5);
  Threshold = map(analogRead(A1), 0, 1023, 150, 5);

  long total1 =  cs_2_38.capacitiveSensor(Multiply);
  long total2 =  cs_2_39.capacitiveSensor(Multiply);
  long total3 =  cs_2_40.capacitiveSensor(Multiply);

  int Art1 = total1 / val;
  int Art2 = total2 / val;
  int Art3 = total3 / val;


  if (sensorHit1 != lastSensorHit1)

    if (sensorHit1 && !lastSensorHit1)
    {
      digitalWrite(ledPin1, HIGH);
      MIDI.sendNoteOn(notes[scaleIndex][columnIndex], 127, 1);    // Send a Note (pitch 80, velo 127 on channel 1)
      MIDI.sendControlChange(64, 127, 1);
    }

    else {
      digitalWrite(ledPin1, LOW);
      MIDI.sendNoteOff(notes[scaleIndex][columnIndex], 0, 1);     // Stop the note
      MIDI.sendControlChange(64, 0, 1);
    }

  if (sensorHit2 != lastSensorHit2)

    if (sensorHit2 && !lastSensorHit2)
    {
      digitalWrite(ledPin2, HIGH);
      MIDI.sendNoteOn(notes[scaleIndex][columnIndex], 127, 1);    // Send a Note (pitch 79, velo 127 on channel 1)
      MIDI.sendControlChange(64, 127, 1);
    }

    else {
      digitalWrite(ledPin2, LOW);
      MIDI.sendNoteOff(notes[scaleIndex][columnIndex], 0, 1);     // Stop the note
      MIDI.sendControlChange(64, 0, 1);
    }

  if (sensorHit3 != lastSensorHit3)

    if (sensorHit3 && !lastSensorHit3)
    {
      digitalWrite(ledPin3, HIGH);
      MIDI.sendNoteOn(notes[scaleIndex][columnIndex], 127, 1);    // Send a Note (pitch 78, velo 127 on channel 1)
      MIDI.sendControlChange(64, 127, 1);
    }

    else {
      digitalWrite(ledPin3, LOW);
      MIDI.sendNoteOff(notes[scaleIndex][columnIndex], 0, 1);     // Stop the note
      MIDI.sendControlChange(64, 0, 1);
    }

  lastSensorHit1 = sensorHit1;
  lastSensorHit2 = sensorHit2;
  lastSensorHit3 = sensorHit3;

}
  • You should have another function to do that sensor checking so there isn't all that cut'n'paste code (which some folks consider bad programming). In your checkSensor() function check which sensor is active and call the new function to process it. I'd probably use a switch/case construct for that beginnersbook.com/2017/08/cpp-switch-case – Dougie Dec 23 '19 at 23:32
  • what does this mean? ... it does not make any sense to me ... each sensor will play each of the scale's notes by itself with each finger press – jsotola Dec 24 '19 at 0:35
  • Thanks for your help. @jsotola...it means that if I keep tapping the first sensor only, i will hear each of the scale's notes, one after the other so I know the problem is to do with the for loop as it keeps cycling around. In fact, all the sensors will do this. I guess I'm not sure how to do that with a seperate function but I will look into it Dougie, thanks – Robbie Perry Dec 24 '19 at 1:24
  • you say keep tapping ... does that mean that you tap the sensor and you hear one note, then you tap again and hear the next note, and so on? – jsotola Dec 24 '19 at 2:01
  • Yes, that is correct. Of course, if I keep my finger on the sensor then I hear the sustain of that note until I take my finger off again – Robbie Perry Dec 24 '19 at 2:07
1

Well after more tinkering I found that the one change that fixed everything was simply this (in the if/else statements).....changing MIDI.sendNoteOn(notes[scaleIndex][columnIndex], 127, 1); to MIDI.sendNoteOn(notes[scaleIndex][0], 127, 1); [columnIndex] needs to be a [0], [1] or [2] representing one of three scales in the assigned array. This is fine as I'm writing out the code for a few sensors. However, for 16 sensors I'm going to have to use a for loop ....Thanks for all your help! Here's the full code for anyone who needs it...including some alterations to the leds...

#include <CapacitiveSensor.h>
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();

 int c3 = 36;
 int d3 = 38;
 int e3 = 40;
 int g3 = 43;
 int a3 = 45;
 int c4 = 48;
 int d4 = 50;
 int e4 = 52;
 int g4 = 55;
 int a4 = 57;
 int c5 = 60;
 int d5 = 62;
 int e5 = 64;
 int g5 = 67;
 int a5 = 69;
 int c6 = 72;

const int columns = 3;
const int scales = 3;
int potVal = 0;
const int  notes[scales][columns] = {
  {c3, d3, e3},
  {c4, d4, e4},
  {c5, d5, e5}
};
const int numberOfSensors = 3;
const int sensorPin[numberOfSensors] = {38, 39, 40};

const int ledPin[numberOfSensors] = {22, 23, 24};

const int val = 10; // this value is best around "10". works with "multiply"
// and "Threshold" to enable Polyphony!
int Threshold = (0); //Threshold of triggered mp3
int Multiply = (0);  //increases or decreases the overal sensitivity

CapacitiveSensor   cs_2_38 = CapacitiveSensor(2, 38);
CapacitiveSensor   cs_2_39 = CapacitiveSensor(2, 39);
CapacitiveSensor   cs_2_40 = CapacitiveSensor(2, 40);

void setup()
{
  Serial.begin(9600);//midi(31250)
  for (int i = 0; i < numberOfSensors; i++) {
    pinMode(ledPin[i], OUTPUT);
}
}
void loop()
{
    int potVal = map(analogRead(A2), 0, 1024, 0, 3);
for (int i = 0; i < numberOfSensors; i++) {
    checkSensor(potVal,i);
  }
}
void checkSensor(int scaleIndex, int columnIndex)
{
  static boolean lastSensorHit1 = false;
  static boolean lastSensorHit2 = false;
  static boolean lastSensorHit3 = false;

  bool sensorHit1 = cs_2_38.capacitiveSensor(Multiply) / val > (Threshold);
  bool sensorHit2 = cs_2_39.capacitiveSensor(Multiply) / val > (Threshold);
  bool sensorHit3 = cs_2_40.capacitiveSensor(Multiply) / val > (Threshold);

  Multiply = map(analogRead(A0), 0, 1023, 150, 5);
  Threshold = map(analogRead(A1), 0, 1023, 150, 5);

  if (sensorHit1 != lastSensorHit1)

    if (sensorHit1 && !lastSensorHit1)
    {
      digitalWrite(ledPin[0], HIGH);
      MIDI.sendNoteOn(notes[scaleIndex][0], 127, 1);    
      MIDI.sendControlChange(64, 127, 1);
    }

    else {
      digitalWrite(ledPin[0], LOW);
      MIDI.sendNoteOff(notes[scaleIndex][0], 0, 1);     
      MIDI.sendControlChange(64, 0, 1);
    }
    if (sensorHit2 != lastSensorHit2)

    if (sensorHit2 && !lastSensorHit2)
    {
      digitalWrite(ledPin[1], HIGH);
      MIDI.sendNoteOn(notes[scaleIndex][1], 127, 1);    
      MIDI.sendControlChange(64, 127, 1);
    }

    else {
      digitalWrite(ledPin[1], LOW);
      MIDI.sendNoteOff(notes[scaleIndex][1], 0, 1);     
      MIDI.sendControlChange(64, 0, 1);
    }
    if (sensorHit3 != lastSensorHit3)

    if (sensorHit3 && !lastSensorHit3)
    {
      digitalWrite(ledPin[2], HIGH);
      MIDI.sendNoteOn(notes[scaleIndex][2], 127, 1);    
      MIDI.sendControlChange(64, 127, 1);
    }

    else {
      digitalWrite(ledPin[2], LOW);
      MIDI.sendNoteOff(notes[scaleIndex][2], 0, 1);     
      MIDI.sendControlChange(64, 0, 1);
    }

  lastSensorHit1 = sensorHit1;
  lastSensorHit2 = sensorHit2;
  lastSensorHit3 = sensorHit3;

}````````
1

I am just learning this program so I could be way off on this and I apologize if I am.

Instead of the loop inside of void setup() initialize each pin individually. Also you are telling the system to start the MIDI and set the pinMode 3 times.

Inside the Void checkSensor function you set all the sensorHits every time the function runs, you might save a little bit you do lastSensorHit(i).

I just noticed you have the if command running this function as (int i = 0; i < numberOfSensors; i++). You don't have a sensor 0, so you might want to change that to (int i = 1; i < numberOfSensors+1; i++)// or just change it to 4.

Inside the function checkSensor, it doesn't look your variable val has a value.

if (sensorHit1 != lastSensorHit1) this is still under the same function as before and it is going to run once per channel that you specified in the controlling if function. Maybe move this into the void loop() or create its own function?

  • Thanks Jeff A...you've made some interesting points. I'll have a chance to work again with this later tonight and will report back with my progress! – Robbie Perry Dec 24 '19 at 16:24
  • Thanks for your help everyone but this is way above my head I'm sorry to say. I need to go and learn about all the processes taking place within this code so that I can approach it better . – Robbie Perry Dec 25 '19 at 18:43
  • I hope you can get it figured out. Good luck and Merry Christmas – Jeff A Dec 25 '19 at 21:57
  • Absolutely!! Merry Xmas to you too Jeff A – Robbie Perry Dec 25 '19 at 23:08
  • AWESOME, good job. To make it easier to read can you put ```` at the beginning and end of your code, it will make it easier to read. Its the key to the left of 1 – Jeff A Dec 27 '19 at 1:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.