if statement problem

Hello to all :slight_smile:

I have been working on this code which triggers midi notes through capacitive touch. There are things I would like to tweak eventually but for the most part it works. However, it continues to send midi cc messages such as note off and sustain off unnecessarily. I realize this is probably not the best way to program for this example and i would love any suggestions as to another approach. However, could anyone suggest a solution for the one I have provided?

Thanking all

#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) > 20;
  bool sensorHit2 = cs_5_34.capacitiveSensor(30) > 20;

  long total1 =  cs_5_33.capacitiveSensor(30);
  long total2 =  cs_5_34.capacitiveSensor(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)
  }

  else if (total1 > 20)
  {
    MIDI.sendControlChange(64, 127, 1);
  }

  else if (total1 < 20)
  {
    digitalWrite(ledPin1, LOW);
    MIDI.sendNoteOff(80, 0, 1);     // Stop the note
    MIDI.sendControlChange(64, 0, 1);
  }


  if (sensorHit2 && !lastSensorHit2)  // Now true, was false
  {
    digitalWrite(ledPin2, HIGH);
    MIDI.sendNoteOn(78, 127, 1);    // Send a Note (pitch 78, velo 127 on channel 1)
  }

  else if (total2 > 20)
  {
    MIDI.sendControlChange(64, 127, 1);
  }

  else if (total2 < 20)
  {
    digitalWrite(ledPin2, LOW);
    MIDI.sendNoteOff(78, 0, 1);     // Stop the note
    MIDI.sendControlChange(64, 0, 1);
  }

  lastSensorHit1 = sensorHit1;
  lastSensorHit2 = sensorHit2;

  delay(10);
}

What is this line

bool sensorHit1 = cs_5_33.capacitiveSensor(30) > 20;

Trying to do?

It doesn't look like it assigned the value you think to sensorHit1. I'm not familiar with the function 'cs_5_33.capacitiveSensor(30)' after which you have a conditional greater than symbol as part of an assignment statement.

I think you are trying to say

if (cs_5_33.capacitiveSensor(30) > 20)
{ sensorHit1 = true; }
else
{ sensorHit1 = false; }

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

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

Why do you need to read each sensor twice?

What is the point of setting sensorHit1 when you later use total1 > 20?

Thanks PaulS. I don't need to read the same sensor twice but due to my lack of understanding it worked for this

else if (total1 > 20)
  {
    MIDI.sendControlChange(64, 127, 1);
  }

I tried "sensorHit1" instead of "total1" and it didn't work. Through experimentation with an earlier version of this code I tried "total1" and it worked, though I know it's flawed.

My main objective was to use a touch sensor that would send a midi note only once, while it was pressed, and to maintain sustain while still pressed. Earlier problems were a continual send of the same midi note repetitively which I have solved to some degree. However, I know there is a better way to write this so that midi note off etc isn't continually sent but I don't yet know how to approach it.

@adwsystems "bool sensorHit1 = cs_5_33.capacitiveSensor(30) > 20;" this is measuring my capacitance and then registering a value? Then used in my true false statement. I've got a lot of reading to do!!!!

I will take your suggestion and work with it though!

Why have you started a new thread when the same subject was being covered in http://forum.arduino.cc/index.php?topic=536415

Thanks UKHeliBob. You answered a question I asked so I can work with the line I questioned earlier.

From the other thread :frowning:
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.

Based on this information, the line 'sensorHit2 = cs_5_34.capacitiveSensor(30) > 20' doesn't work (as you think) and you need to use the if statement I posted earlier. (I'm not even sure what the program would do with that if it does compile)

Sorry UKHeliBob. For some reason I thought it mightn't be noticed and that it was a slightly different question than my original post. Damn, I hope i haven't disrespected the forum rules?

thanks adwsystems. just going to try that now!

I've tried the new if statement and it doesn't work for me I'm afraid to say :frowning:

All I need to do with the old code is to stop generating note off messages constantly...

goatboyrobbie:
I've tried the new if statement and it doesn't work for me I'm afraid to say :frowning:

All I need to do with the old code is to stop generating note off messages constantly...

So send the note off command once the total becomes less than 20 instead of when it is less than 20. See the StateChangeDetection example in the IDE or use the technique that I suggested in reply #1 of the other thread on the subject.

goatboyrobbie:
I've tried the new if statement and it doesn't work for me I'm afraid to say :frowning:

All I need to do with the old code is to stop generating note off messages constantly...

It may not solve all of your problems but it does solve one. That statement doesn't do what you think it does. Next up, follow UKHeliBob to solve your other problem(s).

Indeed I will go back over UkHeliBob’s suggestions and continue understanding yours, adwsystems :slight_smile:

My big problem is understanding the concepts apart from knowledge of approach and I’ve done too much winging it for comfort. Lovin it though!

After my last post I searched with some luck and found others having similar issues.

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state:
  if (buttonState != lastButtonState) {
 
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
    MIDI.sendNoteOn(36, 127, 1);
   
    }
    else {
      // if the current state is LOW then the button went from on to off:
    MIDI.sendNoteOff(36, 0, 1); 
  }
  }

After the help both of ye gave me and staring at this I solved my problem! I cut it down to one input while testing it and she functions as I had hoped.

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

MIDI_CREATE_DEFAULT_INSTANCE();

static const unsigned ledPin1 = 22;      // 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


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

}
void loop()
{

  static boolean lastSensorHit1 = false;

  bool sensorHit1 = cs_5_33.capacitiveSensor(30) > 20;

  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);

    }

    else {
      digitalWrite(ledPin1, LOW);
      MIDI.sendNoteOff(80, 0, 1);     // Stop the note
      MIDI.sendControlChange(64, 0, 1);
    }

    lastSensorHit1 = sensorHit1;

    delay(10);
  }
}

Is there an C programming expert here that know how the line

bool sensorHit1 = cs_5_33.capacitiveSensor(30) > 20;

is evaluated or how the value of sensorHit1 is determined?

The latter the OP believes to mean that a is set true if b > c.

I have seen the notation a = x ? b : c; for if statements (which I prefer not to use, personal preference). But I have never seen (nor can I find) a = b > c; as a proper C statement.

I have just never seen this in 30 years of C programming? What does it do?

adwsystems:
Is there an C programming expert here that know how the line

bool sensorHit1 = cs_5_33.capacitiveSensor(30) > 20;

is evaluated or how the value of sensorHit1 is determined?

The latter the OP believes to mean that a is set true if b > c.

I have seen the notation a = x ? b : c; for if statements (which I prefer not to use, personal preference). But I have never seen (nor can I find) a = b > c; as a proper C statement.

I have just never seen this in 30 years of C programming? What does it do?

That statement (actually, a variable declaration and initialization) sets sensorHit1 to true if cs_5_33.capacitiveSensor(30) is greater than 20.

christop:
That statement (actually, a variable declaration and initialization) sets sensorHit1 to true if cs_5_33.capacitiveSensor(30) is greater than 20.

Dang! Never seen that before. Couldn't even find it online.

adwsystems:
Dang! Never seen that before. Couldn't even find it online.

It's just a simple expression in the initializer:

cs_5_33.capacitiveSensor(30) > 20

That expression yields either 1 or 0 (true or false), which is then assigned to sensorHit1.

:o And just when I thought I was home and dry for a while I hit a snag!

I decided to add a second sensor and test it as I had done with some earlier code. However, sensor 1’s led stays on and the midi note stays on. Sensor 2 fails to trigger. Where have I gone wrong?

#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);       // 10M resistor between pins 4 & 2, pin 2 is sensor pin, add a wire and or foil if desired


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) > 20;
  bool sensorHit2 = cs_5_34.capacitiveSensor(30) > 20;

  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);

    }

    else {
      digitalWrite(ledPin1, LOW);
      MIDI.sendNoteOff(80, 0, 1);     // Stop the note
      MIDI.sendControlChange(64, 0, 1);
    }

    if (sensorHit2 != lastSensorHit2) {

    if (sensorHit2 && !lastSensorHit2) {

      digitalWrite(ledPin2, HIGH);
      MIDI.sendNoteOn(75, 127, 1);    // Send a Note (pitch 80, velo 127 on channel 1)
      MIDI.sendControlChange(64, 127, 1);

    }

    else {
      digitalWrite(ledPin2, LOW);
      MIDI.sendNoteOff(75, 0, 1);     // Stop the note
      MIDI.sendControlChange(64, 0, 1);
    }
    
    
    
    lastSensorHit1 = sensorHit1;
    lastSensorHit2 = sensorHit2;

    delay(10);
  }
  }
}
  if (sensorHit1 != lastSensorHit1)
  {
    if (sensorHit1 && !lastSensorHit1)
    {

All of your sensor 2 code is inside this sensor 1 if. Is that what you meant to do and what is the second test above for ?

  if (sensorHit1 != lastSensorHit1) {

    if (sensorHit1 && !lastSensorHit1) {

That's pretty neat.

If (sensorHi1 not equal to lastSensorHit1) and (if sensorHit1 and the opposite of lastSensorHit1 are the same) then...

It definitely makes sure that sensorHi1 and lastSensorHit1 are not the same value.

All I know is it works. I have yet to reach a level of appreciation! I found it in this thread.... Someone was having a similar issue to mine.

This is something of a solution they were working on.

// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 13;       // the pin that the LED is attached to

// Variables will change:
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
}


void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state:
  if (buttonState != lastButtonState) {
 
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
    MIDI.sendNoteOn(36, 127, 1);
   
    }
    else {
      // if the current state is LOW then the button went from on to off:
    MIDI.sendNoteOff(36, 0, 1); 
  }
  }
  // save the current state as the last state,
  //for next time through the loop
  lastButtonState = buttonState;
 
}

//  plays a MIDI note.  Doesn't check to see that

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

I was getting a little grasp of what was happening and substituted this

if (buttonState != lastButtonState) {
 
    if (buttonState == HIGH) {

with this

if (sensorHit1 != lastSensorHit1) {

    if (sensorHit1 && !lastSensorHit1) {

and it worked though I've misunderstood something in my if loop as it's not working for two sensors, only one! I was away all day so I'm going to give it a lash now :slight_smile:

@ UkHeliBob ..... No, I didn't mean for the sensor 2 code to be inside sensor 1's code. The if flow has confused me!