Possible need of extra functions?

Status
Not open for further replies.

banjorobbie

New Member
Hello, I'm having difficulty with triggering the correct notes with my capacitive sensors running on an Arduino Mega. Sensors work fine if triggering allocated notes in the double if statements of the loop as such...
Code:
if (sensorHit1 != lastSensorHit1)

    if (sensorHit1 && !lastSensorHit1)
    {
      digitalWrite(ledPin1, HIGH);
      MIDI.sendNoteOn(80, 127, 1);    // Send a Note (pitch 80, velo 127 on channel 1)
      MIDI.sendControlChange(64, 127, 1);
    }
...However, if I want to choose a scale for the sensors to play using a pot and change to...
Code:
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);
    }
... then I run into problems. For example, for each successive tap of sensor 1 I will get a different note of the chosen scale. This happens for all the sensors.
What I want to happen is that each sensor has its own note from any chosen scale. Can anyone provide a small example on how I could solve this matter please? Any help much appreciated....
Code:
#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);
 

  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;

}
 
This sounds familiar.

I don't fully understand your problem but would suggest reading your sensors into a single byte and reacting to new "keydown" events.

Can you explain this line?
bool sensorHit3 = cs_2_40.capacitiveSensor(Multiply) / val > (Threshold);
What is it doing?
How do you simply read an input?

Mike.
 
Hahaha...very familiar! My other issue was part of a bigger picture. I knew starting with buttons would be far easier than capacitive sensing and give me a chance to understand arrays and for loops. Once that was working I thought I would use it to modify my capacitive sensor code so that I could enjoy being able to select scales with it. Unfortunately, the way the capacitive sensing code works is a little more complicated than a simple button click using a single input as cap sensing requires 2 pins.
bool sensorHit3 = cs_2_40.capacitiveSensor(Multiply) / val > (Threshold);
From what I understand, once this value is above the threshold value it is held as a 1 and then compared with
static boolean lastSensorHit3 = false;
to continue with the note or not (I really need to go and check all this properly!!). I forgot to mention that I also noticed that once a note plays (with the present code) it continues with sustain even when the finger is removed from the sensor. This shouldn't happen. I'm thinking that I have to many things going on in this code that I don't fully understand and that I should probably brake it down into arrays, for loops, functions and sensing and get a grip on those with easier examples to begin with and then come back to this again. However, if you have an example of how to achieve
reading your sensors into a single byte and reacting to new "keydown" events.
I'll keep going Mike.
 
Last edited:
Having trouble editing this last post so I'll try again.... I'm afraid I had a mix up there and now I have my solution after all that Mike. This Is what I now have and it works perfectly thanks. However, I do need to reduce the if/else statements to a for loop as I wish to add 16 or more sensors.... this was the solution..changing the midi sends
Code:
(notes[scaleIndex][columnIndex], 127, 1);
to
Code:
(notes[scaleIndex][0], 127, 1);
Code:
#include <SPI.h>
#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);    // Send a Note (pitch 80, velo 127 on channel 1)
      MIDI.sendControlChange(64, 127, 1);
    }

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

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

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

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

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

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

}
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…