6 flow meters but only one can be read

Hello dear team ,

I have another problem .

I am using Arduino mega 2560 and 2 flow meter at the moment but my target is to using 6 off them and I am new with C#

for some reason he can read only the first flow meters on pin 2 and the other one he doesn't read it all .

Any ideas why ?


#include <Servo.h>
//https://forum.arduino.cc/t/programming-hobbywing-xrotor-micro-60a/1012457/3


Servo ESC0;
Servo ESC1;
Servo ESC2;
Servo ESC3;
Servo ESC4;
Servo ESC5;

int sensorInterrupt = 0;  // interrupt 0
int Flow0_sensorPin       = 2;
int Flow1_sensorPin       = 3;
int Flow2_sensorPin       = 4;
int Flow3_sensorPin       = 5;
int Flow4_sensorPin       = 6;
int Flow5_sensorPin       = 7; //Digital Pin 2
//int solenoidValve = 5; // Digital pin 5

unsigned int SetPoint = 400; //400 milileter
unsigned int Pump0_quantity=50;
unsigned int Pump1_quantity;
unsigned int Pump2_quantity;
unsigned int Pump3_quantity;
unsigned int Pump4_quantity;
unsigned int Pump5_quantity;

unsigned int Pump0_flowMilliLitres=0;
unsigned int Pump1_flowMilliLitres=0;
unsigned int Pump2_flowMilliLitres=0;
unsigned int Pump3_flowMilliLitres=0;
unsigned int Pump4_flowMilliLitres=0;
unsigned int Pump5_flowMilliLitres=0;


unsigned int Pump0_totalMilliLitres=0;
unsigned int Pump1_totalMilliLitres=0;
unsigned int Pump2_totalMilliLitres=0;
unsigned int Pump3_totalMilliLitres=0;
unsigned int Pump4_totalMilliLitres=0;
unsigned int Pump5_totalMilliLitres=0;




/*The hall-effect flow sensor outputs pulses per second per litre/minute of flow.*/
float Pump0_calibrationFactor = 200; //You can change according to your datasheet
float Pump1_calibrationFactor = 250; //You can change according to your datasheet
float Pump2_calibrationFactor = 200; //You can change according to your datasheet
float Pump3_calibrationFactor = 200; //You can change according to your datasheet
float Pump4_calibrationFactor = 200; //You can change according to your datasheet
float Pump5_calibrationFactor = 200; //You can change according to your datasheet

volatile byte Pump0_pulseCount =0;  
volatile byte Pump1_pulseCount =0;
volatile byte Pump2_pulseCount =0;
volatile byte Pump3_pulseCount =0;
volatile byte Pump4_pulseCount =0;
volatile byte Pump5_pulseCount =0;

float Pump0_flowRate = 0.0;
float Pump1_flowRate = 0.0;
float Pump2_flowRate = 0.0;
float Pump3_flowRate = 0.0;
float Pump4_flowRate = 0.0;
float Pump5_flowRate = 0.0;

//unsigned int flowMilliLitres =0;
//unsigned long Pump0_totalMilliLitres = 0;

unsigned long Pump0_oldTime = 0;
unsigned long Pump1_oldTime = 0;
unsigned long Pump2_oldTime = 0;
unsigned long Pump3_oldTime = 0;
unsigned long Pump4_oldTime = 0;
unsigned long Pump5_oldTime = 0;

void setup()
{
// ESC pump
//Pump1_quantity =50;
ESC0.attach(30);
ESC1.attach(31);
ESC2.attach(32);
ESC3.attach(33);
ESC4.attach(34);
ESC5.attach(35);

//ESC1.writeMicroseconds(1000);turn off the pump
  // Initialize a serial connection for reporting values to the host
  Serial.begin(9600);
  //pinMode(solenoidValve , OUTPUT);
//  digitalWrite(solenoidValve, HIGH);
  pinMode(Flow0_sensorPin, INPUT);
  digitalWrite(Flow0_sensorPin, HIGH);
pinMode(Flow1_sensorPin, INPUT);
  digitalWrite(Flow1_sensorPin, HIGH);
pinMode(Flow2_sensorPin, INPUT);
  digitalWrite(Flow2_sensorPin, HIGH);
pinMode(Flow3_sensorPin, INPUT);
  digitalWrite(Flow3_sensorPin, HIGH);
pinMode(Flow4_sensorPin, INPUT);
  digitalWrite(Flow4_sensorPin, HIGH);
pinMode(Flow5_sensorPin, INPUT);
  digitalWrite(Flow5_sensorPin, HIGH);

  /*The Hall-effect sensor is connected to pin 2 which uses interrupt 0. Configured to trigger on a FALLING state change (transition from HIGH
  (state to LOW state)*/
attachInterrupt(0, Pump0_pulseCounter, FALLING); //you can use Rising or Falling
attachInterrupt(1, Pump1_pulseCounter, FALLING); //you can use Rising or Falling
//attachInterrupt(sensorInterrupt, Pump2_pulseCounter, FALLING); //you can use Rising or Falling
//attachInterrupt(sensorInterrupt, Pump3_pulseCounter, FALLING); //you can use Rising or Falling
//attachInterrupt(sensorInterrupt, Pump4_pulseCounter, FALLING); //you can use Rising or Falling
//attachInterrupt(sensorInterrupt, Pump5_pulseCounter, FALLING); //you can use Rising or Falling
}

void loop()
{

   if((millis() - Pump0_oldTime) > 1000)    // Only process counters once per second
  { 
    // Disable the interrupt while calculating flow rate and sending the value to the host
    detachInterrupt(0);
detachInterrupt(1);
    // Because this loop may not complete in exactly 1 second intervals we calculate the number of milliseconds that have passed since the last execution and use that to scale the output. We also apply the calibrationFactor to scale the output based on the number of pulses per second per units of measure (litres/minute in this case) coming from the sensor.
Pump0_flowRate = ((1000.0 / (millis() - Pump0_oldTime)) * Pump0_pulseCount) / Pump0_calibrationFactor;
Pump1_flowRate = ((1000.0 / (millis() - Pump1_oldTime)) * Pump1_pulseCount) / Pump1_calibrationFactor;
Pump2_flowRate = ((1000.0 / (millis() - Pump2_oldTime)) * Pump2_pulseCount) / Pump2_calibrationFactor;
Pump3_flowRate = ((1000.0 / (millis() - Pump3_oldTime)) * Pump3_pulseCount) / Pump3_calibrationFactor;
Pump4_flowRate = ((1000.0 / (millis() - Pump4_oldTime)) * Pump4_pulseCount) / Pump4_calibrationFactor;
Pump5_flowRate = ((1000.0 / (millis() - Pump5_oldTime)) * Pump5_pulseCount) / Pump5_calibrationFactor;

    // Note the time this processing pass was executed. Note that because we've
    // disabled interrupts the millis() function won't actually be incrementing right
    // at this point, but it will still return the value it was set to just before
    // interrupts went away.
    Pump0_oldTime = millis();
Pump1_oldTime = millis();
Pump2_oldTime = millis();
Pump3_oldTime = millis();
Pump4_oldTime = millis();
Pump5_oldTime = millis();

    // Divide the flow rate in litres/minute by 60 to determine how many litres have
    // passed through the sensor in this 1 second interval, then multiply by 1000 to
    // convert to millilitres.
    Pump0_flowMilliLitres = (Pump0_flowRate / 60) * 1000;
Pump1_flowMilliLitres = (Pump1_flowRate / 60) * 1000;
Pump2_flowMilliLitres = (Pump2_flowRate / 60) * 1000;
Pump3_flowMilliLitres = (Pump3_flowRate / 60) * 1000;
Pump4_flowMilliLitres = (Pump4_flowRate / 60) * 1000;
Pump5_flowMilliLitres = (Pump5_flowRate / 60) * 1000;


    // Add the millilitres passed in this second to the cumulative total
    Pump0_totalMilliLitres += Pump0_flowMilliLitres;
Pump1_totalMilliLitres += Pump1_flowMilliLitres;
Pump2_totalMilliLitres += Pump2_flowMilliLitres;
Pump3_totalMilliLitres += Pump3_flowMilliLitres;
Pump4_totalMilliLitres += Pump4_flowMilliLitres;
Pump5_totalMilliLitres += Pump5_flowMilliLitres;

    unsigned int frac;

    // Print the flow rate for this second in litres / minute
    Serial.print("Flow rate0: ");
    Serial.print(Pump0_flowMilliLitres, DEC);  // Print the integer part of the variable
    Serial.print("mL/Second");
    Serial.print("\t");           

    // Print the cumulative total of litres flowed since starting
    Serial.print("Output Liquid Quantity0: ");        
    Serial.print(Pump0_totalMilliLitres,DEC);
    Serial.println("mL"); 
    Serial.print("\t");     

    Serial.print("Flow rate1: ");
    Serial.print(Pump1_flowMilliLitres, DEC);  // Print the integer part of the variable
    Serial.print("mL/Second");
    Serial.print("\t");           

    // Print the cumulative total of litres flowed since starting
    Serial.print("Output Liquid Quantity1: ");        
    Serial.print(Pump1_totalMilliLitres,DEC);
    Serial.println("mL"); 
    Serial.print("\t");     
    

    if (Pump0_totalMilliLitres > Pump0_quantity)
    {

    //  Serial.println("done");
      //SetSolinoidValve();

ESC1.writeMicroseconds(2000);
 // ESC.write(70);  // Full speed
  //delay(1000);
    }




    if (Pump0_totalMilliLitres > 100)
    {

     // Serial.printIn("done");
      //SetSolinoidValve();
Pump0_totalMilliLitres = 0;
ESC1.writeMicroseconds(1000);
 // ESC.write(70);  // Full speed
  //delay(1000);
    }
    
// Reset the pulse counter so we can start incrementing again
    Pump0_pulseCount = 0;
Pump1_pulseCount = 0;
Pump2_pulseCount = 0;
Pump3_pulseCount = 0;
Pump4_pulseCount = 0;
Pump5_pulseCount = 0;

    // Enable the interrupt again now that we've finished sending output
    attachInterrupt(0, Pump0_pulseCounter, FALLING);
    attachInterrupt(1, Pump1_pulseCounter, FALLING);
    //attachInterrupt(sensorInterrupt, Pump2_pulseCounter, FALLING);
   // attachInterrupt(sensorInterrupt, Pump3_pulseCounter, FALLING);
   // attachInterrupt(sensorInterrupt, Pump4_pulseCounter, FALLING);
   // attachInterrupt(sensorInterrupt, Pump5_pulseCounter, FALLING);
  }
}

//Insterrupt Service Routine

void Pump0_pulseCounter()
{
  // Increment the pulse counter
  Pump0_pulseCount++;
}
void Pump1_pulseCounter()
{
  // Increment the pulse counter
  Pump1_pulseCount++;
}
void Pump2_pulseCounter()
{
  // Increment the pulse counter
  Pump2_pulseCount++;
}
void Pump3_pulseCounter()
{
  // Increment the pulse counter
  Pump3_pulseCount++;
}
void Pump4_pulseCounter()
{
  // Increment the pulse counter
  Pump4_pulseCount++;
}
void Pump5_pulseCounter()
{
  // Increment the pulse counter
  Pump5_pulseCount++;
}

You set your flow pins as input and then you use digitalWrite.

Read about arrays...
It will save you a lot of copy paste work.

Only 2 interrupts are attached... that wiuld explain why the others are not working...

2 Likes

@Jcf53100
Your code is very repetitive, it's hard to read. You took the code for one sensor and just copied all the operators 6 times. That's not how programs are written, it's a surefire chance to make a mistake.
Learn arrays and loops, create an array of sensors and work with it in a loop.

2 Likes

thanks for your help .
I prefer doing copy and paste for now to so I can keep testing .

Where I set input and digitalwrite ?

how to change that ,please .
I had one parts of the script from this forum

for now I am using only 2 flow meters and it doesn't work ,I would like to see both working before to move with 6 off them .

You need to use external interrupt pins.

Take a look at this page to find out which pins those are:

It's wrong way

You use a two sensors, but process only the first in the loop()

yes I took the code from one sensor and duplicate .

I am trying only with 2 flow meter for now .

if I understood correctly I should to create 1 loops for each sensor ?

First read about structs , then make an array of structs to work with multiple devices or sensors.

You’ll be surprised how much easier and readable it makes things.

1 Like

Use find to find...

And read post of @PaulRB .
I think his mention of interrupt pins is what you need to fix.

The digitalWrite to an input pin may or may not do anything. It just does not make sense to me...

Nothing about using arrays and loops will stop being able to test.
What you don't know leads you such an assumption.
What you do now wastes more time that you assume to save.
What you do now leads to easy errors and long debugging.
Every change will take longer.
Arrays are simple.
I won't check your code with multiplied details to be 1 character wrong anywhere. I quit making that mistake in 1980.

1 Like

On the MEGA, interrupt0 is pin 21.
mega.pdf (1.9 MB)

thanks you for your message .

I found something
digitalPinToInterrupt(2)
making our life easier and also a clean code to use 2 flow meters on same arduino .

I am gonna to test it on tomorrow .

#include <FlowMeter.h>  // https://github.com/sekdiy/FlowMeter

// connect a flow meter to an interrupt pin (see notes on your Arduino model for pin numbers)
FlowMeter *Meter1;
FlowMeter *Meter2;

// set the measurement update period to 1s (1000 ms)
const unsigned long period = 1000;

// define an 'interrupt service handler' (ISR) for every interrupt pin you use
void Meter1ISR() {
    // let our flow meter count the pulses
    Meter1->count();
}

// define an 'interrupt service handler' (ISR) for every interrupt pin you use
void Meter2ISR() {
    // let our flow meter count the pulses
    Meter2->count();
}

void setup() {
    // prepare serial communication
    Serial.begin(115200);

    // get a new FlowMeter instance for an uncalibrated flow sensor and let them attach their 'interrupt service handler' (ISR) on every rising edge
    Meter1 = new FlowMeter(digitalPinToInterrupt(2), UncalibratedSensor, Meter1ISR, RISING);
    
    // do this setup step for every  FlowMeter and ISR you have defined, depending on how many you need
    Meter2 = new FlowMeter(digitalPinToInterrupt(3), UncalibratedSensor, Meter2ISR, RISING);
}

void loop() {
    // wait between output updates
    delay(period);

    // process the (possibly) counted ticks
    Meter1->tick(period);
    Meter2->tick(period);

    // output some measurement result
    Serial.println("Meter 1 currently " + String(Meter1->getCurrentFlowrate()) + " l/min, " + String(Meter1->getTotalVolume())+ " l total.");
    Serial.println("Meter 2 currently " + String(Meter2->getCurrentFlowrate()) + " l/min, " + String(Meter2->getTotalVolume())+ " l total.");

    //
    // any other code can go here
    //
}