Search code examples
carduino

Counting pulses using a swiss flow meter with an Arduino, how is it done?


So I'm trying to count the pulses of a swiss flow SF800 flow sensor / meter in my current Arduino project, but I'm currently not getting any data printed out to the console. My Arduino sketch looks like the following,

// global variables should be identified with _

 // flow_A LED
 int led = 4;

 // relay_A
 const int RELAY_A = A0;

 // variables from sketch example
 String inputString = ""; // a string to hold incoming data
 boolean stringComplete = false; // whether the string is complete

// FLOWMETER SHIT
// flowmeter 0 pulse (input) = digital pin 2
// https://github.com/Kegbot/kegboard/blob/master/arduino/kegboard/kegboard_config.h

// which pin to use for reading the sensor? kegboard-mini shield has digital pin 2 allocated
# define FLOWSENSORPIN 2
int rpmcount = 0;
int rpm = 0;
unsigned long lastmillis = 0;

void setup() {
   // initialize serial
   Serial.begin(9600); // open serial port, sets data rate to 115200bps
   inputString.reserve(200);

   pinMode(RELAY_A, OUTPUT);

   // flowmeter shit
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH); // Need to set these HIGH so they won't just tick away
   attachInterrupt(0, rpm_fan, FALLING); // interrupt is attached, is on pin two(2).
}

void open_valve() {

  digitalWrite(RELAY_A, HIGH); // turn RELAY_A on
  // Serial.println("Valve Open");
  Serial.write("{valve_open}");
}

void close_valve() {
  digitalWrite(RELAY_A, LOW); // turn RELAY_A off
  // Serial.println("Vavle Closed");
  Serial.write("{valve_close}");
}

void flow_A_blink() {

  digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for one second
  digitalWrite(led, LOW);   // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}

void flow_A_blink_stop() {

  digitalWrite(led, LOW);
}

// flowmeter shit
void getFlow() {
  Serial.println("reached getFlow function");
  if(millis() - lastmillis == 1000) { // Update every one second, this will be equal to reading frequency (Hz).

  detachInterrupt(0);  // Disable interrupt when calculating

  rpm = rpmcount * 60; // Convert frequency to RPM, note: this works for one interruption per full rotation.

  Serial.print("RPM =\t"); // print the word "RPM and tabl.
  Serial.print(rpm); // print the rpm value
  Serial.print("\t Hz=\t"); // print the word "Hz".
  Serial.println(rpmcount); // print revolutions per second or Hz. And print new line or enter.

  rpmcount = 0; // Restart the RPM counter
  lastmillis = millis(); // Update lastmillis
  attachInterrupt(0, rpm_fan, FALLING); // enable interrupt
  }
}

void rpm_fan() { // this code will be executed every time the interrupt 0 (pin2) gets low.
  rpmcount++;
}

/*
 * Main program loop, runs over and over repeatedly
 */

void loop() {
 if(stringComplete) {
//    Serial.println(inputString);

    if(inputString.equals("{open_valve}\n")) {
//       Serial.println("opening valve.");
       open_valve();
       getFlow();
     }

    if(inputString.equals("{close_valve}\n")) {
//      Serial.println("close vavle.");
      close_valve();
    }

  // clear the string:
  inputString = "";
  stringComplete = false;
  }
}

/*
 SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
*/

void serialEvent() {
  while(Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
    // Serial.println(inputString.length());
  }
}

Solution

  • The following code changes seem to be printing the RPM and Hz values now.

     // flow_A LED
     int led = 4;
    
     // relay_A
     const int RELAY_A = A0;
    
     // variables from sketch example
     String inputString = ""; // a string to hold incoming data
     boolean stringComplete = false; // whether the string is complete
    
    // FLOWMETER SHIT
    // flowmeter 0 pulse (input) = digital pin 2
    // https://github.com/Kegbot/kegboard/blob/master/arduino/kegboard/kegboard_config.h
    
    // which pin to use for reading the sensor? kegboard-mini shield has digital pin 2 allocated
    # define FLOWSENSORPIN 2
    int rpmcount = 0;
    int rpm = 0;
    unsigned long lastmillis = 0;
    
    void setup() {
       // initialize serial
       Serial.begin(9600); // open serial port, sets data rate to 115200bps
       inputString.reserve(200);
    
       pinMode(RELAY_A, OUTPUT);
    
       // flowmeter shit
       pinMode(FLOWSENSORPIN, INPUT);
       digitalWrite(FLOWSENSORPIN, HIGH); // Need to set these HIGH so they won't just tick away
       attachInterrupt(0, rpm_fan, FALLING); // interrupt is attached, is on pin two(2).
    }
    
    void open_valve() {
    
      digitalWrite(RELAY_A, HIGH); // turn RELAY_A on
      // Serial.println("Valve Open");
      Serial.write("{valve_open}");
    }
    
    void close_valve() {
      digitalWrite(RELAY_A, LOW); // turn RELAY_A off
      // Serial.println("Vavle Closed");
      Serial.write("{valve_close}");
    }
    
    void flow_A_blink() {
    
      digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
      delay(1000);              // wait for one second
      digitalWrite(led, LOW);   // turn the LED off by making the voltage LOW
      delay(1000);              // wait for a second
    }
    
    void flow_A_blink_stop() {
    
      digitalWrite(led, LOW);
    }
    
    // flowmeter shit
    void getFlow() {
    //  Serial.println("reached getFlow function");
      if(millis() - lastmillis >= 1000) { // Update every one second, this will be equal to reading frequency (Hz).  Using >= should be safter
    
    //    Serial.println("reached inside if statement");  
        detachInterrupt(0);  // Disable interrupt when calculating
    
        rpm = rpmcount * 60; // Convert frequency to RPM, note: this works for one interruption per full rotation.
    
        Serial.print("RPM =\t"); // print the word "RPM and tabl.
        Serial.print(rpm); // print the rpm value
        Serial.print("\t Hz=\t"); // print the word "Hz".
        Serial.println(rpmcount); // print revolutions per second or Hz. And print new line or enter.
    
        rpmcount = 0; // Restart the RPM counter
        lastmillis = millis(); // Update lastmillis
        attachInterrupt(0, rpm_fan, FALLING); // enable interrupt
        }
    }
    
    void rpm_fan() { // this code will be executed every time the interrupt 0 (pin2) gets low.
      rpmcount++;
    }
    
    /*
     * Main program loop, runs over and over repeatedly
     */
    
    void loop() {
     if(stringComplete) {
    //    Serial.println(inputString);
    
        if(inputString.equals("{open_valve}\n")) {
    //       Serial.println("opening valve.");
           open_valve();
    
         }
    
        if(inputString.equals("{close_valve}\n")) {
    //      Serial.println("close vavle.");
          close_valve();
        }
    
      // clear the string:
      inputString = "";
      stringComplete = false;
      }
      getFlow();
    }
    
    /*
     SerialEvent occurs whenever a new data comes in the
     hardware serial RX.  This routine is run between each
     time loop() runs, so using delay inside loop can delay
     response.  Multiple bytes of data may be available.
    */
    
    void serialEvent() {
      while(Serial.available()) {
        // get the new byte:
        char inChar = (char)Serial.read();
        // add it to the inputString:
        inputString += inChar;
        // if the incoming character is a newline, set a flag
        // so the main loop can do something about it:
        if (inChar == '\n') {
          stringComplete = true;
        }
        // Serial.println(inputString.length());
      }
    }