Midi Question

Hello to all.

I’m using capacitive sensing to send midi notes over serial. So far it is working but my problem is the note is sent continuously because of the loop function. When the threshold has been passed I only wish to send the note once. How can I achieve this?

Thanking All :slight_smile:

#include <SPI.h>
#include <CapacitiveSensor.h>
#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

static const unsigned ledPin1 = 22;      // LED pin on Arduino Uno
static const unsigned ledPin2 = 23;      // LED pin on Arduino Uno

CapacitiveSensor   cs_5_33 = CapacitiveSensor(5, 33);       // 10M resistor between pins 4 & 2, pin 2 is sensor pin, add a wire and or foil if desired
CapacitiveSensor   cs_5_34 = CapacitiveSensor(5, 34);

void setup()
{
  Serial.begin(9600);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);

}

void loop()
{

  long total1 =  cs_5_33.capacitiveSensor(30);
  long total2 =  cs_5_34.capacitiveSensor(30);

  if (total1 > 70)
  {
    digitalWrite(ledPin1, HIGH);
    MIDI.sendNoteOn(80, 127, 1);    // Send a Note (pitch 80, velo 127 on channel 1)
    MIDI.sendNoteOff(80, 0, 1);     // Stop the note
    digitalWrite(ledPin1, LOW);
  }

  if (total2 > 70)
  {
    digitalWrite(ledPin2, HIGH);
    MIDI.sendNoteOn(60, 127, 1);    // Send a Note (pitch 60, velo 127 on channel 1)
    MIDI.sendNoteOff(60, 0, 1);     // Stop the note
    digitalWrite(ledPin2, LOW);

  }
}

When the threshold has been passed I only wish to send the note once. How can I achieve this?

Make sending the note dependant on on a boolean variable being false. Set the boolean variable to true when you send the note and it will not be sent again until you set the boolean to false

Thanks UkHeliBob

Could you perchance give me a small example to start me?
Having trouble finding where to begin.

A small example of the principle

const byte buttonPin = A2;
boolean notePlaying = false;
unsigned long startTime;
unsigned long currentTime;
unsigned long notePeriod = 10000; //10 seconds between notes

void setup()
{
  Serial.begin(115200);
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.println("Press the button to play the note once\n");
}

void loop()
{
  if (digitalRead(buttonPin) == LOW)  //button is pressed
  {
    if (notePlaying == false)  //if the note has not been played
    {
      Serial.println("Play the note here");
      notePlaying = true;
      startTime = millis();
    }
  }
  //code here that sets the boolean to false to allow the note to play again
  currentTime = millis();
  if (notePlaying == true)  //only test when the note is playing
  {
    if (currentTime - startTime >= notePeriod)  //10 seconds passed ?
    {
      notePlaying = false;  //activate the button again
      Serial.println("Button active again");
    }
  }
}

I have no idea under what circumstances the boolean will be set to false to allow the note to play again in your setup. In the code above the button is made inactive for 10 seconds as an illustration.

Thats fantastic UkHeliBob!

Working through it now! :slight_smile:

Well I’ve managed to get a better idea of whats happening through experimentation and have scraped this together. It works perfectly so far but I’m wondering what to change so that the notes have sustain while the threshold is always greater than 30 and then cut off below that level.

#include <SPI.h>
#include <CapacitiveSensor.h>
#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

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

CapacitiveSensor   cs_5_33 = CapacitiveSensor(5, 33);       // 10M resistor between pins 4 & 2, pin 2 is sensor pin, add a wire and or foil if desired
CapacitiveSensor   cs_5_34 = CapacitiveSensor(5, 34);


void setup()
{
  Serial.begin(9600);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
}

void loop()
{

  static boolean lastSensorHit1 = false;
  static boolean lastSensorHit2 = false;

  bool sensorHit1 = cs_5_33.capacitiveSensor(30) > 30;
  bool sensorHit2 = cs_5_34.capacitiveSensor(30) > 30;


  if (sensorHit1 && !lastSensorHit1)  // Now true, was false
  {
    digitalWrite(ledPin1, HIGH);
    MIDI.sendNoteOn(80, 127, 1);    // Send a Note (pitch 80, velo 127 on channel 1)
    MIDI.sendNoteOff(80, 0, 1);     // Stop the note

  }

  else {
    digitalWrite(ledPin1, LOW);
  }

  if (sensorHit2 && !lastSensorHit2)  // Now true, was false
  {
    digitalWrite(ledPin2, HIGH);
    MIDI.sendNoteOn(40, 127, 1);    // Send a Note (pitch 40, velo 127 on channel 1)
    MIDI.sendNoteOff(40, 0, 1);     // Stop the note

  }
  else {
    digitalWrite(ledPin2, LOW);

  }

  lastSensorHit1 = sensorHit1;
  lastSensorHit2 = sensorHit2;

  delay(10);
}
  bool sensorHit1 = cs_5_33.capacitiveSensor(30) > 30;
  bool sensorHit2 = cs_5_34.capacitiveSensor(30) > 30;

What does the 30 parameter mean in the function call in these 2 lines ?

That's a good question! The 30 in brackets possibly has something to do capacitance sensitivity. I cant be sure as it has come from previous code that I've gleaned.

The 30 to its right however is my threshold for triggering the midi and led.

  bool sensorHit1 = cs_5_33.capacitiveSensor(30) > 30;
  bool sensorHit2 = cs_5_34.capacitiveSensor(30) > 30;

I've been experimenting with that 30 parameter by changing it. Increasing it produces far higher readings from the capacitive sensor. I have been varying the resistors needed for the circuit rather than changing this parameter in order to change its sensitivity so far.

http://playground.arduino.cc/Main/CapacitiveSensor

long capacitiveSensor(byte samples)

capacitiveSensor requires one parameter, samples, and returns a long containing the added (sensed) capacitance, in arbitrary units. capacitiveSensor keeps track of the lowest baseline (unsensed) capacitance, and subtracts that from the sensed capacitance, so it should report a low value in the unsensed condition.

Well that explains that! :slight_smile:

Thanks Oqibidipo!