Pressure sensor and If function

Hi guys,

I’m running into a difficult situation.

I have some solenoids and servos controlled by MIDI notes. so far it works perfectly.
Here’s the explanation of my current code below.

  1. If it receives a note on, it listen to what note it is
  2. each note call a specific function
  3. Note off, stop the function
#include <VarSpeedServo.h>

byte type = 0;

byte incomingByte;
byte note;
byte velocity;
int chan = 1;  //specify what MIDI channel we're listing to
byte boucle = 0; // for boucle

int action = 2; //0 =note off ; 1=note on ; 2= null
int currentTime;
int previousTime;
const int lowNote = 60; //what's the first note?  36 is C1 in Ableton

VarSpeedServo servoe;   // create servo object to control a servo that open circuit
VarSpeedServo servos;   // create servo object to control a servo that close circuit

const byte solenoidspin[] = {22, 23, 24, 25, 26, 27, 28, 29};
const byte NUMBER_OF_SOLENOIDS = sizeof(solenoidspin);
unsigned long startTimes[NUMBER_OF_SOLENOIDS];
unsigned long periods[] = {80, 60, 100, 80, 60, 40, 110, 90};

// the loop function runs over and over again forever

void setup() {
  Serial.begin(38400);
  for (int p = 0; p < NUMBER_OF_SOLENOIDS; p++)
  {
    pinMode(solenoidspin[p], OUTPUT);
  }

servoe.attach(30);
servos.attach(31);

  //setup our outputs

  pinMode(22, OUTPUT);  // 1
  digitalWrite (22, LOW);
  pinMode(23, OUTPUT);
  digitalWrite (23, LOW);

  pinMode(24, OUTPUT);  // 2
  digitalWrite (24, LOW);
  pinMode(25, OUTPUT);
  digitalWrite (25, LOW);

  pinMode(26, OUTPUT);  // 3
  digitalWrite (26, LOW);
  pinMode(27, OUTPUT);
  digitalWrite (27, LOW);

  pinMode(28, OUTPUT);  // 4
  digitalWrite (28, LOW);
  pinMode(29, OUTPUT);
  digitalWrite (29, LOW);


}

void vibe20 () {
  servoe.write(90, 0, true);
  servos.write(55, 0);
  while ( true )
  {
    static unsigned long previousTime = 0;

    currentTime = millis();
    if (currentTime - previousTime >= 20)
    {
      digitalWrite (22, !digitalRead(22));
      digitalWrite (23, !digitalRead(23));
      digitalWrite (24, !digitalRead(24));
      digitalWrite (25, !digitalRead(25));
      digitalWrite (26, !digitalRead(26));
      digitalWrite (27, !digitalRead(27));
      digitalWrite (28, !digitalRead(28));
      digitalWrite (29, !digitalRead(29));
      if (currentTime < previousTime) // check for rollover
        previousTime = 0;

      previousTime += 20; // increment previous time by delay factor "20"
    }

    if (Serial.available() > 0)
    {
      incomingByte = Serial.read();
      if (incomingByte == lowNote)
        break; // if incomingByte is equal to chan+127
    }
  }
  digitalWrite (22, LOW);
  digitalWrite (23, LOW);
  digitalWrite (24, LOW);
  digitalWrite (25, LOW);
  digitalWrite (26, LOW);
  digitalWrite (27, LOW);
  digitalWrite (28, LOW);
  digitalWrite (29, LOW);
}

void vibe25 () {
  servoe.write(90, 0, true);
  servos.write(55, 0);
  while ( true )
  {
    static unsigned long previousTime = 0;

    currentTime = millis();
    if (currentTime - previousTime >= 25)
    {
      digitalWrite (22, !digitalRead(22));
      digitalWrite (23, !digitalRead(23));
      digitalWrite (24, !digitalRead(24));
      digitalWrite (25, !digitalRead(25));
      digitalWrite (26, !digitalRead(26));
      digitalWrite (27, !digitalRead(27));
      digitalWrite (28, !digitalRead(28));
      digitalWrite (29, !digitalRead(29));
      if (currentTime < previousTime) // check for rollover
        previousTime = 0;

      previousTime += 25; // increment previous time by delay factor "25"
    }

    if (Serial.available() > 0)
    {
      incomingByte = Serial.read();
      if (incomingByte == lowNote + 1)
        break; // if incomingByte is equal to 12
    }
  }
  digitalWrite (22, LOW);
  digitalWrite (23, LOW);
  digitalWrite (24, LOW);
  digitalWrite (25, LOW);
  digitalWrite (26, LOW);
  digitalWrite (27, LOW);
  digitalWrite (28, LOW);
  digitalWrite (29, LOW);

}


void vibe30 () {
  servoe.write(90, 0, true);
  servos.write(85, 0);
  while ( true )
  {
    static unsigned long previousTime = 0;

    currentTime = millis();
    if (currentTime - previousTime >= 30)
    {
      digitalWrite (22, !digitalRead(22));
      digitalWrite (23, !digitalRead(23));
      digitalWrite (24, !digitalRead(24));
      digitalWrite (25, !digitalRead(25));
      digitalWrite (26, !digitalRead(26));
      digitalWrite (27, !digitalRead(27));
      digitalWrite (28, !digitalRead(28));
      digitalWrite (29, !digitalRead(29));
      if (currentTime < previousTime) // check for rollover
        previousTime = 0;

      previousTime += 30; // increment previous time by delay factor "30"
    }

    if (Serial.available() > 0)
    {
      incomingByte = Serial.read();
      if (incomingByte == lowNote + 2)
        break; // if incomingByte is equal to 12
    }
  }
  digitalWrite (22, LOW);
  digitalWrite (23, LOW);
  digitalWrite (24, LOW);
  digitalWrite (25, LOW);
  digitalWrite (26, LOW);
  digitalWrite (27, LOW);
  digitalWrite (28, LOW);
  digitalWrite (29, LOW);
}

void vibe35 () {
  servoe.write(90, 0, true);
  servos.write(55, 0);
  while ( true )
  {
    static unsigned long previousTime = 0;

    currentTime = millis();
    if (currentTime - previousTime >= 35)
    {
      digitalWrite (22, !digitalRead(22));
      digitalWrite (23, !digitalRead(23));
      digitalWrite (24, !digitalRead(24));
      digitalWrite (25, !digitalRead(25));
      digitalWrite (26, !digitalRead(26));
      digitalWrite (27, !digitalRead(27));
      digitalWrite (28, !digitalRead(28));
      digitalWrite (29, !digitalRead(29));
      if (currentTime < previousTime) // check for rollover
        previousTime = 0;

      previousTime += 35; // increment previous time by delay factor "35"
    }

    if (Serial.available() > 0)
    {
      incomingByte = Serial.read();
      if (incomingByte == lowNote + 3)
        break; // if incomingByte is equal to 12
    }
  }
  digitalWrite (22, LOW);
  digitalWrite (23, LOW);
  digitalWrite (24, LOW);
  digitalWrite (25, LOW);
  digitalWrite (26, LOW);
  digitalWrite (27, LOW);
  digitalWrite (28, LOW);
  digitalWrite (29, LOW);
}

void micro100 () { 
servoe.write (40, 0, true);
servos.write (90, 0);
 digitalWrite (22, LOW);
 digitalWrite (23, LOW);
 digitalWrite (24, LOW);
 digitalWrite (25, LOW);
 digitalWrite (26, LOW); 
 digitalWrite (27, LOW);
 digitalWrite (28, LOW);
 digitalWrite (29, LOW);
  while (true)
  {
    for (int p = 0; p < NUMBER_OF_SOLENOIDS; p++)
    {
      unsigned long currentTime = millis();
      if (currentTime - startTimes[p] >= periods[p])
      {
        digitalWrite(solenoidspin[p], !digitalRead(solenoidspin[p]));
        startTimes[p] = currentTime;
      }
    }

    if (Serial.available() > 0)
    {
      incomingByte = Serial.read();
      if (incomingByte == lowNote + 21)
        break; // if incomingByte is equal to 12
    }
  }
  digitalWrite (22, LOW);
  digitalWrite (23, LOW);
  digitalWrite (24, LOW);
  digitalWrite (25, LOW);
  digitalWrite (26, LOW);
  digitalWrite (27, LOW);
  digitalWrite (28, LOW);
  digitalWrite (29, LOW);
}
void loop () {
  
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();

    // wait for as status-byte, channel 1, note on or off
    if (incomingByte == 143 + chan) { // note on message starting starting
      action = 1;
    }

    if (incomingByte == 127 + chan) { // note off message starting
      action = 0;

    }

    if ( (action == 0)/*&&(note==0)*/ ) { // if we received a "note off", we wait for which note (databyte)
      note = incomingByte;
    }

    if ( (action == 1)/*&&(note==0)*/ ) { // if we received a "note on", we wait for the note (databyte)
      note = incomingByte;
      moveServo(note);

    }
  }

}

void moveServo(byte note) {   //  call a function based on the note


  switch (note) {
    case lowNote:
      vibe20 ();
      break;
    case lowNote+1:
      vibe25 ();
      break;
    case lowNote+2:
      vibe30 ();
      break;
    case lowNote+3:
      micro100 ();
      break;

  }
}

I’m trying to add a pressure sensor that will indicate me the pressure flow in my circuit. According to this value that I’ll obtain, I d’like the “servoe” that controls the water flow at the beginning of the circuit to open or close according to the value of the sensor.

I would map it as such (random value for the moment):

sensor value obtained in mbar: over or equal to 973 = “servoe” 70 degrees
sensor value obtained in mbar: over or equal to 1500>= “servoe” 80 degrees
sensor value obtained in mbar: over or equal to 2000>= “servoe” 90 degrees

Therefore what I d’like to achieve is creating a function “void pressuresensor” that is being activated with a midi note lownote+4 exactly like the other functions above. That I know how to do as it is similar as the others functions above.

1- Every time this function would be called, the solenoids would turn HIGH and then LOW in 1 second.
2- The sensor would THEN measure the value.
3- If this value is over or equal to X then “servoe” changes to 70 degrees in ALL the other functions above. If the Value is over or equal to Z then “servoe” changes to 80 degrees and so forth.

I guess I should try to implement a “IF” function but I wonder how I can change the “servoe” angle in all functions (from lownote to lownote+3) according to the sensor value obtained with function pressuresensor?
Another idea I’m having is to remove the “servoe” from all functions and to put it in the void loop, before calling each midi note, it would check the previous sensor state?

BTW, here’s the pressure sensor code I’m using and the sensor Freescale MPX5700AP.

#include <VarSpeedServo.h>
#define ADC_HONEYWELL 0 // Arduino analog pin

const float Null = 0.50; // Null VDC; datasheet Page 32
const float Sensitivity = 266.6;  // Sensitivity mV/psi; MPX5700AP
  VarSpeedServo servoe; 


  Serial.begin(9600);


}

// the loop function runs over and over again forever
void loop() {
    
 
  Serial.print("P: ");
  Serial.print(getPressure());
  Serial.println("mbar g");
}  
  
float getPressure(void) {
  float pressurePSI,pressureMBAR,pressureVDC;
  int pressure;
  
  pressure = analogRead(ADC_HONEYWELL);
  pressureVDC = (float)pressure * 0.0048828125; // (5/1024 = 0.0048828125)
  pressureVDC = pressureVDC - Null;
  pressurePSI = pressureVDC / Sensitivity * 1000; 
  pressureMBAR = pressurePSI * 68.948;
  
  return pressureMBAR;

  
}

Finally, the last issue I’m having is that because I’m using MIDi note to communicate with my arduino. I’m using Hairless software that uses the Arduino Serial to received midi note. Therefore I won’t be able to read sensor value using serial monitor to debug my code.

If you could help me in finding the right way of doing it with pseudo code or advices I would gladly appreciate :slight_smile:

Thanks a lot for your help guys.

I guess I should try to implement a "IF" function but I wonder how I can change the "servoe" angle in all functions (from lownote to lownote+3) according to the sensor value obtained with function pressuresensor?

Function pressure sensor sets a global int XX to 70, 80, whatever.

Your four vibe functions that set the servoe angle will now have an if-else in them. If the global int is a certain level, they will set the servoe at 70, else they will set it at what they normally set it at.

Between the 1st measure and the second one, how can I store the value somewhere so that the other functions can come and read it?

In a global variable perhaps ?

 if (900 >= pressure =< 1000) {

If you want to test whether the value of pressure is in a range then you need to do 2 comparisons.

 if ( (pressure >= 900) && (pressure <= 1000) )

Feel free to change the order of the comparisons but you must do two of them unless you cascade the if/else through from highest to lowest (or vice versa)

if (pressure >= 2000)
{
  //do stuff for pressure greater or equal to 2000
}
else if (pressure >= 1500)
{
  //do stuff for pressure between 1500 and 1999
}
else if (pressure >= 1000)
{
  //do stuff for pressure between 1000 and 1499
}

Personally I would probably use switch/case but that is a matter of personal preference.

sensorValue is declared as a global variable so its value is available throughout the entire program and its value can be changed anywhere in the program.

So its value is available throughout the entire program

Yes but does it remains fixed inbetween 2 measures?

1/ Lets say that I call function pressuresensor once. The value found is 100. Will it remain 100 till the next time that I call the pressuresensor function or will it change overtime (knowing the fact that the pressure will change in the circuit inbetween measures)? As my sensor is still being supplied in volt and still on the arduino A0.

Therefore I just wonder if when I’ll call the micro100 function, if it’s going to read directly from the Analogic A0 value of the sensor (that may have changed and not being 100 anymore) or if it’s gonna get the global variable value that was measured and memorized before (in this case 100)?

Sorry for not being very clear. As you can see, English is not ma native language.

It's value will remain the same unless/until you change it. Do you change its value in the micro100() function ? No, so it will be the same as when it was last read in the pressuresensor() function

Thanks UKheliBob!

I really appreciate your answers.

it seems to be working :) I'll run some more tests tomorrow.

The only issue I'm gonna have to resolve is that I'm using the serial for MIDi note (with hairless software) so I'm not able to serial read the sensor value and working a bit blind here.

I guess I'll have to connect MIDi with I2C or something else in order to let the serial available for debugging

Again, thanks for your answer!

The only issue I'm gonna have to resolve is that I'm using the serial for MIDi note (with hairless software) so I'm not able to serial read the sensor value and working a bit blind here.

Take a look at the SoftwareSerial library. It allows you to use most pins as Tx/Rx and will work in parallel with hardware serial so you can still use the Serial monitor for debugging and/or other output.

Thanks UkHeliBob,

It looks great. I’m trying to get it to work with my system.

Do you think this software serial should be used to transfer MIDI note to the Arduino or to get the sensor value(normally plugged in the analog A0 of the arduino)?

Moreover, will I be able to use the serial monitor to display the sensor value while the hardware serial is used by MIDI?

If yes, then, here’s the code I’ve tried to implement for the software serial and sensor:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

int sensorPin = 10;    // Select input pin for the potentiometer
int sensorValue;   // Variable stores value coming from the sensor

void setup()  
{
  // Open serial communications and wait for port to open:
  Serial.begin(57600);

  }

}

  Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(4800);
  mySerial.println("Hello, world?");
}

void loop() // run over and over

  sensorValue = digitalRead(sensorPin);  // Read sensor
  Serial.println(sensorValue, DEC);     // Display result

}

Does that seems a correct way of doing it?

Thanks

That program does not compile and only uses SoftwareSerial to send “Hello, world?” somewhere once, or it would apart from the problem with the setup() function.

Do you think this software serial should be used to transfer MIDI note to the Arduino or to get the sensor value(normally plugged in the analog A0 of the arduino)?

You can’t use SoftwareSerial to read an analogue pin (or a digital one for that matter). You can use it to send a value that has been read from an analogue pin over a serial link though.

You are almost certainly better off using hardware serial to send/receive data to/from the serial monitor and SoftwareSerial to communicate with the MIDI device. That way you can use the serial monitor for debugging messages.

Thanks UKHeliBob but from what I have read, to transfer MIDI signal from the Laptop to the Arduino, you either need to go trhough the USB serial and use a software such as MIDI hairless OR to build a small hardware circuit (with an octocoupler). I'm not sure I can simply plug MIDi in the digital pin of the arduino using softwareserial.