[SOLVED] micro flow sensor SMWF0.5B

Hello, I'm using Arduino UNO R3 (ATMEGA328-PU) and trying to measure with micro flow sensor SMWF0.5B (http://shineui.co.kr/shineui/bbs/download.php?bo_table=eng_s_05_05&wr_id=23&no=0&page=3 ) the quantity of liquid instead of flow rate. My circuit includes: 1 push button (with internal LED) for turning on the system (Normally Open connection), another pressing will turn off the system (EMO). The code include state machine with timer using millis() of 12 seconds: led1 is turn on for 5 seconds and then turn off, now led2 is turn on for 7 seconds and then turn off. If button was pressed within the 12 seconds the system is turn off. During the 12 seconds I want to measure with the FLS two different quantities - 100ml and 175ml, I want to fill 2 tanks with different quantities. I connected the FLS to digital pin 3 (interrupt 1), tried many examples from the web, sometime got false values like when the turbine is idle the data is rising.

In other words, I want to count the number of pulses (according to the datasheet every 58 pulses is 1 L/min) every 0.5 second (sample rate) and then I can calculate the liters, right? According to the datasheet - the equation: Pulse signal(Hz) = 60 * Flow rate (Q -> L/min) => Q(L/min)=(Pulse signal(Hz) + 2) / 60

Any examples of codes that I can draw ideas?

[img alt=Micro Water Flow Sensor (SMWF-0420 H21 / H27 / H29) - Shineui Entec Co., Ltd.]https://image.ec21.com/image/shineui/oimg_GC03681822_CA10054217/Micro_Water_Flow_Sensor_SMWF-0420_H21_%252F_H27_%252F_H29_.jpg[/img]

Thanks in advance

Are you using the analog or digital input? I don’t fully understand the code, but I believe that the frequency measurement has to do with the rotation of the sensor.

The higher the flow, the faster the rotation therefore the frequency changes. Therefore we generate a wave.

My issue here is that an analog input will also have noise. That will also be measured as many different frequencies.

Im on my phone so, doing my best to understand how everything works.

@dyso My FLS is connected to digital pin 3.

More info for the first quote

The final system will includes 5 different loads, some of them are: one water pump and 2 solenoids. I operate each one of them with module of power mosfet n channel logic level - Mosfet RFP30N06LE, load connected to drain, I added 220ohm to Gate. https://www.sparkfun.com/products/12959

I added to each load flyback diode 1N5408.

Pressing the push button (has 10Kohm to GND) within on state of the system will stop also the FLS. I want to count how many pulses occurred in 0.5 second, in other words to know the frequency of the FLS so I can calculate how much liquid passed the turbine and then measure quantities of 100mL and 175ml tanks, when the tanks are full stop the solenoids operations. Each tank has it's own solenoid.

Ah okay. Its kinda hard for me to imagine exactly how your schematic looks like. You could draw the schematic and send us a picture.

Also, the datasheet is a bit confusing. Is there a pull-up resistor on the out pin?

An idea what you could do is to test this on tinkercad.

Maybe also upload a sample code. I would like to understand why you get data on idle.

@dyso thinkercad is for 3d printing...

I understood that the pull up resistor is external that why I connected it.

How do I upload picture from the computer and not from link?

Tinkercad is not only 3D design. It also has circuit design where you can actually simulate an Arduino UNO. You should look it up, you’ll love it!

In attachments and other options.

Did you measure the resistance between the out and vin?

I added the 10K ohm resistor between VCC and OUT according to the datasheet, their recommendation is resistor greater than 4.7kohm.

The picture is demonstrate part of the circuit - push button, one load and the FLS.
I also tried the “Typical Three -Wire Application Circuit” from the data sheet but instead of 4.7nF capacitor I put 10nF.

Thank you! Much clearer now.

I understand that your problem is only the FLS. So I assume that the other parts are running fine.

When I did my apprenticeship in electronics. We would usually measure the output of such sensors on an oscilloscope. However, i suppose you don’t have one. Could you connect the FLS to the analog pin and do an analog read with a high enough sampling rate. Copy then the serial monitor and paste it in a txt file. It is also important to see the idle data.

You can basically plot this afterwards on MATLAB, R, Python or Excell and then see how the measurement looks like. If it is a Sine wave, digital 1 and 0s, etc.

You could upload a picture of the results for us to see.

With this, I would build the exact same setup as you displayed in the Schematic on Tinkercad and see if the same issues occurs. Basically use a signal generator as a FLS.

I tested so many codes. Actually I connect it to oscilloscope and I didn't see any signal on digital pin 3(FLS out).

From the online examples code you can see that they use digital read instead of analog read. Where and how you decide the sample rate? Can you share your code of signal generator (frequency meter) so I try it?

Well if you have an oscilloscope, thats even better than using the Arduino. Put the 5V on vin, gnd to gnd and connect out to the oscilloscope probe. Take some water and let it flow through the FLS. See what happens, how does the wave look like. Once you have an idea what signal will be going in the Arduino, you can simulate this on Tinkercad.

Something like this.

https://www.tinkercad.com/things/czB1AN0DmA0-rpm-meter-encoder

I don’t have a code on me since I am not at home and still on my phone. I could see what I can do this evening.

I already did it but instead of water I blow the pipe of the FLS and nothing changed in the scope.

Thank you for your help, waiting to your update with the code. :)

Try something like this:

int test=A0;
int readValue;
float Voltage;

void setup() {
  pinMode(test, INPUT);
  Serial.begin(9600);
  Serial.println("Time, Voltage");
}

void loop() {
  readValue = analogRead(test);
  Voltage = (5./1023.)*readValue;
  Serial.print(millis());
  Serial.print(", ");
  Serial.println(Voltage);
  delay (5);
}

Connect out to the analog pin A0 and open the serial monitor, let it run for 10 seconds without any pressure. Then blow in for 5 seconds or so. Then pull out the USB cable and copy all of the data (CTRL-A > CTRL-C). Paste it in notepad and name it test.txt or whatever you want. Then upload the txt file.

Your flow meter, looking at the data sheet, likely has an open collector NPN output. I assume you are using a pullup resistor between the output and VCC pins?

WE can measure flow a few different ways. There is Rate such as LPM (Liters Per Min) or Totalizer, quantity. You seem to be after the Totalizer method. Should that be true I suggest you look up K-Factor as it pertains to flow. How many pulses per unit of measure.

Just as an example a flow meter outputs 7.5 Hz. when the flow rate is 1.0 LPM. Therefore 7.5 * 60 (60 seconds per min) = 450 so the actual K-Factor is 450 or every 450 pulses counted = 1 liter.

Your symptoms sound like you are not using an external pullup with an open collector output flowmeter. The data sheet mentions about 4.57K with 5 volts VCC minimum. I would use 10K Output to VCC.

Ron

@dyso Thank you for the code, I upload it with delay of 1 sec instead of 5ms. The result is in the picture.
@Ron_Blain If the FLS was Total method it wasn’t it written in the datasheet?
I’m using the FLS like the datasheet shows, see my last message - I connected 10Kohm resistor between VCC and signal line.

analog.JPG

Thats not what I had in mind. We want to see how the frequency looks like.

If you have a frequency of 60Hz (1l/min), that means that in 1 second you will have 60 pulses. Therefore, 1 pulse would be in 17milliseconds. With a sampling rate of 200Hz (5ms) we should be able to look at the pulses.

You also need to copy all the data and paste it in a text file and upload it here so that I can plot it.

In other words, I want to count the number of pulses (according to the datasheet every 58 pulses is 1 L/min) every 0.5 second (sample rate) and then I can calculate the liters, right? According to the datasheet - the equation: Pulse signal(Hz) = 60 * Flow rate (Q -> L/min) => Q(L/min)=(Pulse signal(Hz) + 2) / 60

Sorry, I thought you wanted to get a pulse count for 1.0 liter and 1.5 liter of volume for a dispensing application.

Ron

UPDATE

The code include my 5 loads + FLS, I’m testing the code with 2 LEDs (load3 and load4) and the FLS.
Link for MOSFET module: SparkFun MOSFET Power Control Kit - COM-12959 - SparkFun Electronics
I got help from that post: https://forum.arduino.cc/index.php?topic=541198.0

The code here is only the meaningful part and those I think I need to fix:
push button is connected to digital pin2
FLS is connected to digital pin3

//all the physical connection of the push button, loads and FLS
int buttonState;                             // the current reading from the switch

unsigned long tank1_max = 500;          // capacity of maximum mL untreated water tank
unsigned long tank2_max = 700;           // capacity of maximum mL water in bottle

//------------ VARIABLES (will change)---------------------

uint8_t state = 0;
uint8_t button_state = 0;
uint8_t fls_state = 0;
long button_timer;
int lastButtonState = 0;                         // previous state of the button
int button_was_pressed = 0;                     // the current reading from the button
volatile unsigned long pulse_counter;          // this integer needs to be set as volatile to ensure it updates correctly during the interrupt process.
unsigned long copy_count = 0;                 // accumulates the interrupt count, after
unsigned long speed = 0;
unsigned long tank1 = 0;
unsigned long tank2 = 0;
int time;

//========================================

void setup() {
  Serial.begin(9600);
  Serial.println("Machine is turn on");       // so we know what sketch is running

  pinMode(button, INPUT);                    
  pinMode(led_button, OUTPUT);              
  //pinMode(all the loads are set to, OUTPUT);                            
  pinMode(flow_pin, INPUT);           
  attachInterrupt(1, isrCount, RISING);     // interrupt programme when signal to pin 3 detected (1 = pin 3)
	          // count when rising, call isrCount function when happens (isr = interupt service routine)
}

//========================================

void loop() {

  check_button();
  check_state_machine();
  pulse_counter = 0;
  measure_pulses();

  button_was_pressed = LOW;

}

//========================================

void check_button() {

  switch (button_state)
  {
    case 0:
      if (digitalRead(button) == HIGH)
      {
        button_was_pressed = HIGH;
        button_state = 1;
        button_timer = millis();
      }
      break;

    case 1:
      if (digitalRead(button) == HIGH)
        button_timer = millis();
      else if ((millis() - button_timer) > 25)      // time after bouncing finished
      {
        button_state = 0;
      }
      break;
  }
}

//========================================

void check_state_machine() {
  Serial.print("check_state_machine :: state = ");
  Serial.println(state);

  switch (state)
  {
    case 0:
      digitalWrite(led_button, LOW);
      digitalWrite(load3, LOW);
      digitalWrite(load2, LOW);
      digitalWrite(load1, LOW);
      digitalWrite(load4, LOW);
      digitalWrite(load5, LOW);

      if (button_was_pressed == HIGH)
      {
        digitalWrite(led_button, HIGH);           
        digitalWrite(load3, HIGH);               
        digitalWrite(load2, HIGH);                
        digitalWrite(load1, HIGH);             
        if (copy_count > 0) {
          tank1++;
          Serial.print("pulses: ");
          Serial.println(copy_count);
          Serial.print("tank1: ");
          Serial.println(tank1);
          if (copy_count >= (tank1_max / (1000 / 3480)))       // (500mL(tank1_max) / (1000mL per min/ 58*60 pulse signal per min)) = tank1
          {
            state = 1;
          }
        }
      }
      else if (button_was_pressed == HIGH)              // turning off machine - emo state
      {
        digitalWrite(load1, LOW);
        digitalWrite(load2, LOW);
        digitalWrite(load3, LOW);
        digitalWrite(led_button, LOW);
      }
      break;

    case 1:
      digitalWrite(load4, HIGH);           
      digitalWrite(load5, HIGH);          
      digitalWrite(load3, LOW);          
      if (copy_count > 0) {
        tank2_max++;
        Serial.print("pulses: ");
        Serial.println(copy_count);
        Serial.print("tank2_max: ");
        Serial.println(tank2_max);
        if (copy_count >= (tank2_max / (1000 / 3480))) {   // (700mL(tank2_max) / (1000mL per min/ 58*60 pulse signal per min)) = tank2
          state = 2;
        }
      }

      if (button_was_pressed == HIGH)        // turning off machine - emo state
      {
        digitalWrite(load1, LOW);                
        digitalWrite(load2, LOW);                 
        digitalWrite(load4, LOW);              
        digitalWrite(load5, LOW);            
        digitalWrite(led_button, LOW);      
        state = 0;
      }
      break;

    case 2:                                     // turning off machine
      digitalWrite(load5, LOW);                 
      digitalWrite(load4, LOW);                
      digitalWrite(load1, LOW);               
      digitalWrite(load2, LOW);                
      digitalWrite(led_button, LOW);       
      state = 0;
  }
}

//========================================

void measure_pulses() {
  Serial.print("fls_state :: pulse counter = ");
  Serial.println(pulse_counter);

  switch (fls_state)
  {
    case 0:
      time = millis();
      fls_state = 1;
      break;

    case 1:                                      // disable interrupts, make copy of pulse_counter, reenable interrupts
      noInterrupts();                           // don't interrrupt to count on pin while copying count
      copy_count = pulse_counter;
      interrupts();                           // switch on interrrupts again

      break;
  }
}

//========================================

void isrCount() {
  pulse_counter++;
}

Now there are 3 situation:

  1. Blowing air in the FLS the serial monitor shows the number of the pulses.
  2. Pushing the button LED1 (load1) is turning on, no expression in the serial monitor, continues pressing doesn’t change the time illumination of the led.
  3. Blowing air in the FLS the serial monitor shows the number of the pulses, pushing the button while I see the pulses running the code stop.

In the loop section, do I need to do measure_pulses function before the check_state_machine function or first the check_state_machine function?

As I mentioned earlier, I want to do when I push the button the FLS will measure the quantity of the water in the background (of the code) for each tank, after tank1 is full I want to fill tank2.
What am I missing?

@ardil thanks for the a2a;

you seem to have D3 connected to +5v? Why not use input_pullup and make the circuit simpler?

and get rid of the 10nF that will damp out your pulses. Y

ou MAY need a small cap for debouncing though - but lets see some pulses counted frst.

I can see no definition for flow_pin?

uint8_t button_state = 0; int buttonState; ?? which variable represents the state of the button?

Can you write a simple piece of code just to count pulses from the flow sensor - without using an interrupt, nor debouncing?

Also why are you using a pull-DOWN on your button? But lets worry about the button when you get the pulse detection working.

"Why not use input_pullup and make the circuit simpler?"

I use the details from the datasheet of the FLS.

"I can see no definition for flow_pin?"

I put that in the begging of the code, I summarize the relevant code for the code I attached :-) see my comment in the top of the code.

"uint8_t button_state = 0; int buttonState; ?? which variable represents the state of the button?

The first one represent the state one, the latter I wrote it accidently. The code for counting the pulses is working, I tried it from the link I attached I'm using a pull-down to my button because for me it's more common sense that when you push the button the voltage is "moving" from point A to B, so HIGH will turn on the system and not LOW (turn off).