Using 4x water flow sensors (yf s401) with arduino mega

How are you all doing, I have a project that use 4 water flow sensors. The problem is I only can use pin 2 to read pulse from sensor, other pins can't, they give back wrong pulse.

Thank you if you choose to help.

have a read of how-to-get-the-best-out-of-this-forum
in particular

  1. give details of the flow sensor, e.g. link to where you got it
  2. upload a schematic of how you wired and powered the sensor
  3. upload a copy of the program (using codes tags </>)

are you using polling or interrupts to detect pulses from the flow sensors

Google your way to glory....

1.The sensor i'm using
YF-S401.pdf (57.2 KB)
2. Schematic

3.Code i'm using to test:

volatile int flow_frequency; // Measures flow sensor pulses
unsigned int l_hour; // Calculated litres/hour
unsigned char flowsensor = 2; // Sensor Input
unsigned long currentTime;
unsigned long cloopTime;
void flow () // Interrupt function
{
   flow_frequency++;
}
void setup()
{
   pinMode(flowsensor, INPUT);
   digitalWrite(flowsensor, HIGH); // Optional Internal Pull-Up
   Serial.begin(9600);
   attachInterrupt(0, flow, RISING); // Setup Interrupt
   sei(); // Enable interrupts
   currentTime = millis();
   cloopTime = currentTime;
}
void loop ()
{
   currentTime = millis();
   // Every second, calculate and print litres/hour
   if(currentTime >= (cloopTime + 1000))
   {
      cloopTime = currentTime; // Updates cloopTime
      //Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
      l_hour = (flow_frequency * 60 / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
      flow_frequency = 0; // Reset Counter
      Serial.print(l_hour, DEC); // Print litres/hour
      Serial.println(" L/hour");
   }
}

maybe try using InterruptOnChange for this...

Mega and Mega 2560 support change interrupts on the following pins: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69).

Something like this maybe:
(Compiles, NOT tested!)

/*
   PORTB InterruptOnChange Connections:
   PCINT0 (PB0 / 53)
   PCINT1 (PB1 / 52)
   PCINT2 (PB2 / 51)
   PCINT3 (PB3 / 50)
   PCINT6 (PB6 / 12)
   PCINT7 (PB7 / 13)
*/

const uint8_t flowsensor1 = 53, flowsensor2 = 52, flowsensor3 = 51; //assigned pin numbers to named variables
volatile uint16_t flow1_counter = 0, flow2_counter = 0, flow3_counter = 0; // Measures flow sensor pulsesz
uint8_t flowsensor1_state, flowsensor2_state, flowsensor3_state; //to hold last read pin value (for ISR ONLY)
uint32_t oldtime;
float L_Hour_Sensor1, L_Hour_Sensor2, L_Hour_Sensor3;

void setup() {
  Serial.begin(9600);

  //initialise flow sensor counters
  flow1_counter = flow2_counter = flow2_counter = 0;

  flowsensor1_state = digitalRead(flowsensor1);
  flowsensor2_state = digitalRead(flowsensor2);
  flowsensor3_state = digitalRead(flowsensor3);

  //Enable InterruptOnChange on pin 51,52,53
  PCICR  = _BV(PCIE0);
  PCMSK0 = _BV(PCINT0) | _BV(PCINT1) | _BV(PCINT2);

  oldtime = millis();
}

void loop() {
  // Every second, calculate and print litres/hour
  if (millis() - oldtime >= 1000) {
    oldtime = millis();

    //momentarily disable interrupts to avoid data corruption
    noInterrupts();
    uint16_t local_cnt1 = flow1_counter;
    uint16_t local_cnt2 = flow2_counter;
    uint16_t local_cnt3 = flow3_counter;
    flow1_counter = flow2_counter = flow2_counter = 0; // Reset Counters
    interrupts();

    //Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
    L_Hour_Sensor1 = ((local_cnt1 * 60) / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
    L_Hour_Sensor2 = ((local_cnt2 * 60) / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
    L_Hour_Sensor3 = ((local_cnt3 * 60) / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour

    // Print litres/hour from each sensor read
    Serial.print(L_Hour_Sensor1, 2);
    Serial.print(" L/hour, ");
    Serial.print(L_Hour_Sensor2, 2);
    Serial.print(" L/hour, ");
    Serial.print(L_Hour_Sensor3, 2);
    Serial.println(" L/hour");
  }
}

ISR(PCINT0_vect) {

  uint8_t data = PINB & PCMSK0; // read data and clear unused pins

  if (digitalRead(flowsensor1) != flowsensor1_state) {
    flowsensor1_state = digitalRead(flowsensor1);
     //update counter only if rising edge (ie HIGH) whenever ISR is triggered
    if (flowsensor1_state) ++flow1_counter;
  }

  if (digitalRead(flowsensor2) != flowsensor2_state) {
    flowsensor2_state = digitalRead(flowsensor2);
    //update counter only if rising edge (ie HIGH) whenever ISR is triggered
    if (flowsensor2_state) ++flow2_counter;
  }

  if (digitalRead(flowsensor3) != flowsensor3_state) {
    flowsensor3_state = digitalRead(flowsensor3);
    //update counter only if rising edge (ie HIGH) whenever ISR is triggered
    if (flowsensor3_state) ++flow3_counter;
  }
}

hope that helps....

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.