Trigger MIDI note with a sensor, QUESTION

Hello, i am trying to figure out how the trigger one
midiNote with a sensorReading, i would like to have one
note and not a lot of notes.
I modified two scetches but none is working the way i would like.
Scetch 2 changes the MIDInote according to the sensorvalue, but when i remove the delay it sends out
a midinote on every voidloop, so that's too much
I want one note with every change of the sensorReading
within the given parameters
Arpeggio

Scetch 1

const int sensorMin = 100; // sensor minimum, discovered through experiment
const int sensorMax = 500; // sensor maximum, discovered through experiment

void setup() {
// initialize serial communication:
Serial.begin(31200);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
digitalWrite(3, LOW); // GND 0 Volt supply to opto-coupler
digitalWrite(2, HIGH);
}

void loop() {
// read the sensor:
int sensorReading = analogRead(0);
// map the sensor range to a range of four options:
int range = map(sensorReading, sensorMin, sensorMax, 0, 3);
byte note = 0x1E;
// do something different depending on the
// range value:
switch (range) {
case 0: // your hand is on the sensor
noteOn(0x90, 0x2D, 0x45);
break;
case 1: // your hand is close to the sensor
noteOn(0x90, 0x30, 0x45);
break;
case 2: // your hand is a few inches from the sensor
noteOn(0x90, 0x34, 0x45);
break;
case 3: // your hand is nowhere near the sensor
noteOn(0x90, 0x39, 0x45);
break;
}
}

void noteOn(int cmd, int pitch, int velocity) {
Serial.print(cmd, BYTE);
Serial.print(pitch, BYTE);
Serial.print(velocity, BYTE);
}

Scetch 2

const int sensorMin = 000; // sensor minimum, discovered through experiment
const int sensorMax = 1000; // sensor maximum, discovered through experiment

void setup() {
// initialize serial communication:
Serial.begin(31200);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
digitalWrite(3, LOW); // GND 0 Volt supply to opto-coupler
digitalWrite(2, HIGH);

}

void loop() {
int sensorReading = analogRead(0);
if (sensorReading <= 400)
{noteOn(0x90, 0x3F, 0x45);
delay (400);
noteOn(0x90, 0x3F, 0x00);}
else if (sensorReading >= 100)
{noteOn(0x90, 0x2A, 0x45);
delay (400);
noteOn(0x90, 0x2A, 0x00);
}
}

void noteOn(int cmd, int pitch, int velocity) {
Serial.print(cmd, BYTE);
Serial.print(pitch, BYTE);
Serial.print(velocity, BYTE);
}

First off all include the code i the # box when posting so as to make it more readable : )
and you can be having two setup's and loop's ! include both in only a single sketch and boththe ssketches have different applications

Hello, i am trying to figure out how the trigger one
midiNote with a sensorReading, i would like to have one
note and not a lot of notes

the just have the code set like ......

if (sensor reading >100)&&(sensorreading<200)
{
 noteOn(0x90, 0x2D, 0x45); 

}

else if sensor reading >00)&&(sensorreading<300)

{

noteOn(0x90, 0x30, 0x45); 

}
and so on !

Hope this helps ..... :slight_smile:

Thanks for the tip about the #box, i wil do that the next time when i post a scetch.
About your code; it still is triggering a lot of notes and
not just one, what i would like.
One note for every change of above some value
and under some value and vice versa.
Arpeggio

OOPs i didnt get you! i thought u wanted to triggeg many notes
if then the sketch two will do !

One note for every change of above some value
and under some value and vice versa.

You'll need to keep track of the previous readings.

int noteSentFor = 0;
int deltaToTriggerSend = 10; // Or whatever you consider significant

When the new reading is significantly different, send a note, record that you sent the note, and the reading that caused the note to be sent.

int currVal = analogRead(0);
if(currVal > noteSentFor + deltaToTriggerSend)
{
   // Send the note
   noteSentFor = currVal;
}
else if(currVal < noteSentFor - deltaToTriggerSend)
{
   // Send the note
   noteSentFor = currVal;
}

Hello agian,
Still trying to trigger notes by the change of a
value range.
Here is the scetch i use now, it gives a sequence of
3 notes by the change of a sensorvalue.
But not instantly.
I will try to keep track of sensorReading by the use of
sensorReading_old and comparing these two, if there is a transition from one to the other, bang to note, the note is send.

Here is the sketch with the sequence,
To be continued


/*
Switch statement

Demonstrates the use of a switch statement. The switch
statement allows you to choose from among a set of discrete values
of a variable. It's like a series of if statements.

To see this sketch in action, but the board and sensor in a well-lit
room, open the serial monitor, and and move your hand gradually
down over the sensor.

The circuit:

  • photoresistor from analog in 0 to +5V
  • 10K resistor from analog in 0 to ground

created 1 Jul 2009
modified 4 Sep 2010
by Tom Igoe

This example code is in the public domain.

*/

void setup() {
// initialize serial communication:
Serial.begin(31200);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
digitalWrite(3, LOW); // GND 0 Volt supply to opto-coupler
digitalWrite(2, HIGH);

}

void loop() {
int sensorReading = analogRead(0);
if ((sensorReading >= 400)&&(sensorReading <=999))
{noteOn(0x90, 0x3F, 0x45);
delay (430);
noteOn(0x90, 0x3F, 0x00);}
else if ((sensorReading >= 0)&&(sensorReading <=399))
{noteOn(0x90, 0x29, 0x45);
delay (430);
noteOn(0x90, 0x29, 0x00);}
else
{ noteOn(0x90, 0x30, 0x45);
delay (860);
noteOn(0x90, 0x30, 0x00);

}
}

void noteOn(int cmd, int pitch, int velocity) {
Serial.print(cmd, BYTE);
Serial.print(pitch, BYTE);
Serial.print(velocity, BYTE);
}
// Arpeggio

How can i edit a message that is allready online??
And....the Modify button is gone
de Rocker

Here is another Scetch for the Midi-note triggering.
It will compile, but it does nothing.
I used a photoresistor to detect sensorReading
and map this to a state and store the old state.
Compare state and old_state and if these two
are NOT equal; sent a note (or a note off).
Here is the scetch, Help me out please, trying the build a
LaserHarp.
Arpeggio

/*
  Switch statement
 
 Demonstrates the use of a switch statement.  The switch
 statement allows you to choose from among a set of discrete values
 of a variable.  It's like a series of if statements.
 
 To see this sketch in action, but the board and sensor in a well-lit
 room, open the serial monitor, and and move your hand gradually
 down over the sensor.
 
 The circuit:
 * photoresistor from analog in 0 to +5V
 * 10K resistor from analog in 0 to ground
 
 created 1 Jul 2009
 modified 4 Sep 2010
 by Tom Igoe 
 
 This example code is in the public domain.
 
 http://www.arduino.cc/en/Tutorial/SwitchCase
 */

// these constants won't change:


const int sensorMin = 600;      // sensor minimum, discovered through experiment
const int sensorMax = 1048;    // sensor maximum, discovered through experiment

void setup() {
  // initialize serial communication:
  Serial.begin(31200);
    pinMode(2, OUTPUT);     
  pinMode(3, OUTPUT);  
  digitalWrite(3, LOW); // GND 0 Volt supply to opto-coupler
  digitalWrite(2, HIGH);
}

void loop() {
  // read the sensor:
  int sensorReading = analogRead(0);
  // map the sensor range to a range of four options:
  int state = map(sensorReading, sensorMin, sensorMax, 0, 1);
int state_old = 0;
if (state != state_old) {
if (state = 1);
{noteOn(0x90, 0x3F, 0x45);}
}
   if (state != state_old) {
  if (state = 0)
   {noteOn(0x90, 0x3F, 0x00);
   }
 }
state = state_old;

}

void noteOn(int cmd, int pitch, int velocity) {
  Serial.print(cmd, BYTE);
  Serial.print(pitch, BYTE);
  Serial.print(velocity, BYTE);
}
  int sensorReading = analogRead(0);
  // map the sensor range to a range of four options:
  int state = map(sensorReading, sensorMin, sensorMax, 0, 1);
int state_old = 0;
if (state != state_old) {
if (state = 1);

Starting at the bottom, = is an assignment operator. == is the equality operator. I suspect that you want == in the if test, not =.

The comment is wrong. The map function, as used, will return one of 2 values, 0 or 1. When sensorReading is 0 to 1022, the map function will return 0. When sensorReading is 1023, map will return 1.

[edit]I re-read the code after posting, and see that sensorMin and sensorMax are not 0 and 1023 as I assumed. sensorMin is 640, and sensorMax is 1048. sensorReading can never get to sensorMax. I wrote a sketch that looped from 0 to 1050, and printed the loop index and map output with map defined as shown in the code:
i = 0; val = -1
i = 1; val = -1
i = 2; val = -1
i = 3; val = -1
.
.
.
i = 230; val = -1
i = 231; val = -1
i = 232; val = -1
i = 233; val = 0
i = 234; val = 0
i = 235; val = 0
.
.
.
i = 1021; val = 0
i = 1022; val = 0
i = 1023; val = 0
.
.
.
i = 1044; val = 0
i = 1045; val = 0
i = 1046; val = 0
i = 1047; val = 0
i = 1048; val = 1
i = 1049; val = 1
i = 1050; val = 1

Not exactly the output I expected, and certainly not what you were expecting. Your value for sensorReading will be in the 0 to 1023 range, so the only values map will ever return are -1 and 0.[/edit]

Having state_old as a local variable is an exercise in futility. Every pass through loop(), a new variable is created, and destroyed at the end of loop(). How you can expect that to persist a value escapes me.

The state != state_old comparison will be false for any sensor reading other than 1023, which may not actually be achievable, depending on the unspecified sensor.

Since state_old can only every be 0, and the only value for state that is not state_old is 1, the if state == 1 test hardly seems necessary.

Thanks for the reply,
it make a lot of sence, i will rewrite the map-function
I was indeed wrong with the analogRead, it is from
0-1024
And the equality operator is good, this might work afterall.
The reason i go for this is because i am trying to build a realy nice LaserHarp, nice to play with, so
by the transition of a range value, that is from 0 to 1
( i block the laserlight)(note-on is sent out) and from
1 to 0 (when i release the laser and let it shine on the
photoresistor)(note-off is sent out), one is able to play
for example piano with the laserharp.
Arpeggio

I was indeed wrong with the analogRead, it is from 0-1024

0 to 1023

You should get rid of the map call. If the value read from the sensor is above a threshold, do something. If not, do something else or do nothing.

Yeh, you'r right PaulS, do something when the sensor is
above or below a certain value. But do these two things each one time, and that one time seems to be the problem.
How do i implement the in my scetch.
Thanks in advance, Arpeggio.

do something when the sensor is above or below a certain value. But do these two things each one time, and that one time seems to be the problem.

You need to use a flag to indicate whether "something" has been done.

boolean overDone = false;
boolean underDone = false;

int threshold = 500;

void loop()
{
   int sensorVal = analogRead(sensorPin);
   if(sensorVal > threshold)
   {
      if(!overDone)
      {
        // Do the over something

        overDone = true;
        underDone = false;
      }
   }
   else
   {
      if(!underDone)
      {
         // Do the under something

         underDone = true;
         overDone = false;
      }
   }
}

Depending on sensor drift (how repeatable the sensor output is), you may also need to record the value(s) the over and under things are done at, and not do them unless the change is significant.