Flowmeter Arduino Nano + IFM SM6004

Hi everyone, first time posting here, I have been tinkering with Arduino for a few months, in order to develop some tools that helps me at my job at the brewery. We recently acquired a flowmeter ( IFM 6004) that works with 4-20 ma input. The flowmeter only show on screen the Flowrate - L/M) and I wanted to develop an Arduino Add-on that allows me to 1) Read the flow rate on a bigger screen 2 ) Show the TOTAL amount of liter over time 3) allow me to set a target value that would activate a solenoid valve through a relay.

So far I have tackled successfully 1) , the 4-20 ma signal comes through 250 Ohms resistors and the formula gives me a pretty accurate reading. I balanced the spotiness of the ADC reading, making an average of 50 readings and taking the average reading. I am using an arduino Nano and a st 7789 screen

The readings get stable when there is actual flow going through the sensor. But, when the device is turned on, it takes a bit to stabilize, that the reading I included a line that only start counting total liter if the flow is minimum to 0.5 L/m which is a reasonable threshold in my experience

Atm im stucked at a pretty basic issue : The code I wrote for 2) isn't working. Its not adding the values correctly and the increment is not proportional to the readings. Also, I put a single push button that allows me to reset the counter, but its not working either. That makes me suspect the loop I wrote is not correct and I was hoping someone could direct me or help me to solve this issue before I get to 3)

Thank you in advance,

here is my code

#include <Adafruit_ST7789.h> 
#include <SPI.h>
#include <Adafruit_GFX.h>


#define TFT_MOSI 11  // SDA Pin on ESP32
#define TFT_SCLK 13  // SCL Pin on ESP32
#define TFT_CS 10     // Chip select control pin
#define TFT_DC 9    // Data Command control pin
#define TFT_RST 8   // Reset pin (could connect to RST pin)
#define BUTTON_PIN 6 // reset counter


Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
const int flowPin = A0; // Analog pin for flow sensor
const float conversionFactor = 5.01; // Conversion factor for voltage to flow rate
const float minimumFlow = 0.5; // Minimum flow rate to consider
const int tempPin = A1; //analog pin for temperature
float sensorValue =0;
float sensorValue2 =0;
float voltage =0;
float voltage2 =0;
float Temperature;
float totalFlow = 0.0; // Total accumulated flow in liters
float SetValue = 0.0;
float PotValue =0.0;

void setup() {
  Serial.begin(9600); // Initialize serial communication
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  tft.init(240, 320, SPI_MODE2);  // Init ST7789 display 135x240 pixel
  tft.setRotation(1);
  tft.fillScreen(ST77XX_BLACK);
  TftSetup();

}

void loop() {

  ReadADC();
  ReadADC2();
  float Temperature = ((voltage2/1000)*24.73)-42.38;
  float flowRate = ((voltage/1000)*6.173)-6.285; // Convert voltage to flow rate
  float PotValue = analogRead(A4); 
  float SetValue = map(PotValue,0,1023,0,500);
    Serial.print("Sensor Value : ");
    Serial.print(sensorValue);
    Serial.print(" Voltage: ");
    Serial.print(voltage);
    Serial.print("Flow Rate: ");
    Serial.print(flowRate);
    Serial.print("Temperature : ");
    Serial.print(Temperature);
    Serial.print(" L/min\t");
    Serial.print("Total Flow: ");
    Serial.print(totalFlow);
    Serial.println(" Liters");
  if (flowRate > minimumFlow) {
    float deltaTime = 1.0; // Time interval in seconds (assuming 1 second)
    float flowIncrement = flowRate * deltaTime / 60.0; // Convert flow rate to flow increment in liters

    totalFlow += flowIncrement; // Accumulate the flow
    byte buttonState = digitalRead(BUTTON_PIN);
  
  if (buttonState == LOW) {
      totalFlow = 0;
  }
  else {
     
  }
    // Print the current flow rate and total flow
    Serial.print("Voltage: ");
    Serial.print(voltage);
    Serial.print("Flow Rate: ");
    Serial.print(flowRate);
    Serial.print(" L/min\t");
    Serial.print("Total Flow: ");
    Serial.print(totalFlow);
    Serial.println(" Liters");
  }
   // Delay for 1 second before the next reading
  tft.setCursor(0, 0);
  tft.fillRect(5, 5, 150,90,ST77XX_BLACK);  
  tft.setCursor(25, 25);
  tft.setTextColor(ST77XX_ORANGE);
  tft.setTextSize(5);
  tft.print(flowRate, 1);
  //
  tft.fillRect(165, 5, 150,90,ST77XX_BLACK);  
  tft.setCursor(185, 25);
  tft.setTextColor(ST77XX_BLUE);
  tft.setTextSize(5);
  tft.print(SetValue, 0);
  //temperature
  tft.fillRect(5, 125, 150,90,ST77XX_BLACK);  
  tft.setCursor(25, 145);
  tft.setTextColor(ST77XX_RED);
  tft.setTextSize(5);
  tft.print(Temperature, 0);
  //Total flow
  tft.fillRect(165, 125, 150,90,ST77XX_BLACK);  
  tft.setCursor(185, 145);
  tft.setTextColor(ST77XX_GREEN);
  tft.setTextSize(5);
  tft.print(totalFlow, 1);
  delay(1000);

}

void ReadADC()
{
sensorValue= 0.0;

for (int i = 0; i < 50; i++) //Do 100 readings
  {
 sensorValue += analogRead(flowPin);
 delay(5);
  }

  voltage = (float)(sensorValue/50)* (5010/ 1023.0);
  }

 void ReadADC2()
{
sensorValue2= 0.0;

for (int i = 0; i < 100; i++) //Do 100 readings
  {
 sensorValue2 += analogRead(tempPin);
 delay(5);
  }

  voltage2 = (float)(sensorValue2/100)* (5010 / 1023.0);
  } 

void TftSetup()
{
  tft.setTextWrap(false);
  tft.setCursor(0, 0);
  tft.fillRect(0, 0, 160,120,ST77XX_ORANGE);
  tft.fillRect(3, 3, 154,114,ST77XX_BLACK);
  tft.fillRect(160, 0, 160,120,ST77XX_BLUE);
  tft.fillRect(163, 3, 154,114,ST77XX_BLACK);
  tft.fillRect(0, 120, 160,120,ST77XX_RED);
  tft.fillRect(3, 123, 154,114,ST77XX_BLACK);
  tft.fillRect(160, 120, 160,120,ST77XX_GREEN);
  tft.fillRect(163, 123, 154,114,ST77XX_BLACK);
  tft.setCursor(100, 92);
  tft.setTextColor(ST77XX_ORANGE);
  tft.setTextSize(3);
  tft.println("L/m");
  tft.setCursor(105, 217);
  tft.setTextColor(ST77XX_RED);
  tft.setTextSize(2);
  tft.println("Temp");
  tft.setCursor(214, 98);
  tft.setTextColor(ST77XX_BLUE);
  tft.println("Set Flow");
  tft.setCursor(195, 217);
  tft.setTextColor(ST77XX_GREEN);
  tft.setTextSize(2);
  tft.println("Total Flow");

  } 
#define BUTTON_PIN 6 // reset counter
const int flowPin = A0; // Analog pin for flow sensor
const int tempPin = A1; //analog pin for temperature
const float conversionFactor = 5.01; // Conversion factor for voltage to flow rate
const float minimumFlow = 0.5; // Minimum flow rate to consider
float totalFlow = 0.0; // Total accumulated flow in liters

void setup() {
  Serial.begin(115200); // Initialize serial communication
  pinMode(BUTTON_PIN, INPUT_PULLUP);
}

void loop() {
  static uint32_t TimeStore = millis();
  static uint16_t FR;
  static float Temperature;
  static float flowRate;

  FR = ReadADC();
  Temperature = (float)ReadADC2() * 24.73 - 42.38;                // <-----  need adjustment
  flowRate = (float)FR * 6.173 - 6.285; // Convert voltage to flow rate   <-----  need adjustment
  totalFlow += float(millis() - TimeStore) / 60000.0 * flowRate;
  TimeStore = millis();
  if (millis() % 1000 < 2) {
    Serial.print("Temperature: ");
    Serial.println(Temperature, 1);
    Serial.print("Sensor Value : ");
    Serial.print(FR);
    Serial.print(",  Flow Rate: ");
    Serial.print(flowRate, 2);
    Serial.println(" L/min\t");
    Serial.print("Total Flow: ");
    Serial.print(totalFlow, 2);
    Serial.println(" Liters");
    delay(2);
  }
  if (digitalRead(BUTTON_PIN) == LOW) {
    totalFlow = 0;
    TimeStore = millis();
  }
}

uint16_t ReadADC() {
  const uint8_t Readings = 50;
  uint32_t sensorValue = 0;

  for (int i = 0; i < Readings; i++)   {
    sensorValue += analogRead(flowPin);
    delay(1);
  }
  return uint16_t(sensorValue / Readings);
}

uint16_t ReadADC2() {
  const uint8_t Readings = 50;
  uint32_t sensorValue = 0;

  for (int i = 0; i < Readings; i++) {
    sensorValue += analogRead(tempPin);
    delay(1);
  }
  return uint16_t(sensorValue / Readings);
}

Hi,
Have you looked at this parameter?

Tom.. :smiley: :+1: :coffee: :australia:

Can't help on the code but you should add an RC high frequency filter going into your A/D input.
Near the Nano:

image

This will remove high frequency noise from getting into the Nano A/D ckt. If it helps but feel more filtering would be helpful, change the 0.1µf to a 1µf (ceramic or film, not electrolytic).

Hello, thank you very much for your input I will try it later today to see the result. I guess Millis will be more useful than my formula but I need to learn more about it.

Hello Tom ! Yes, damping is actually fine since im reading the correct L/minutes on the arduino, just not getting the correct total amount. Thanks for taking the time to look into it

Hello John, i don't have the 10k resistor either, I will try it out and add the capacitor to see if it helps have a smoother start up of the software. I will check also more about high frequency filters, thanks !

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