Fuelab Prodigy Series Pump and Driver via Arduino

Thread Starter

rennie1080

Joined Apr 10, 2017
52
Ron, by the way the flowmeter I will add ( macnaught mx12s-2b ) series. Its sensor type is open collector npn hall effect sensor. Macnaught Mx12s-2sb . open collector npn term is confused me. Can I write code for this flowmeter as like normal hall effect sensor ? After it count the flow, I want to reset the counts info on lcd by using a button. How should I wire button ? ( analog input for button is suitable ? )
upload_2018-8-3_11-11-24.png
 

Reloadron

Joined Jan 15, 2015
7,523
If you look at your data sheet you will see pin 1 is your + supply voltage, pin 2 is unused, pin 3 is your common and pin 4 is your Vout pulses. Note how pin 4 has a 3.3 K Ohm resistor tied to it. Open collector simply put means you get your out pulses off pin 4 and pin 4 is tied to power through a 3.3 K resistor. Just means the internal output circuit is a NPN transistor with the collector open so we place a resistor on that collector to generate our signal out pulses. You want to try powering it with 5 Volts so we get usable pulses for your Arduino.

You also want to take note of the K-Factor which is 423.97 Pulses/Gallon, so each gallon passing through the sensor will produce 423.94 pulses or about 424 pulses. This is a pretty good tutorial using an Arduino to measure flow rate. In the example their K-Factor is 450 pulses per liter where yours will be 424 pulses per gallon. Take note of how the math functions work. Also, they went with a 10 K collector resistor which is more typical of what I would use but the 3.3 K suggested by the flow meter manufacturer should work fine.

I have a few things going today but I'll try and run the code later and see what I get. I'll just simulate a flow meter into an Arduino Uno.

Ron
 

Thread Starter

rennie1080

Joined Apr 10, 2017
52
What do you think about this code ? There is flow and total flow. But I want to reset total flow by using push button . How I should do that ?


C:
// initialize LCD lib with I2C serial communication protocol
#include <Wire.h> //I2C lib
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
// LCD lib
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

int pot_pin = A0;
int pump_pwm= 3;

int press_pin =A1;

int flowPin = 2;  //This is the input pin on the Arduino

double flowRate;    //This is the value we intend to calculate.
double totalFlowRate;
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.


int pot_init= 0;
int pump_init= 0;
int percentValue =0;



void setup() {


  lcd.begin(20,4);  // A4 - A5 connection SDA - SCL
  lcd.backlight();
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Nano) to run the function "Flow"
  
  Serial.begin(9600);
}

void loop() {
pressure_cal();
pump_control();
flow_control();


}

void pressure_cal(void) {

float sensorVoltage = analogRead(press_pin);   // sensor voltage A0
float psi = ((sensorVoltage-102)/204)*25;  // Offset    0 PSI= 0.5V=102 unit, 50 PSI= 2.5, 100 PSI= 4.5V, 1 PSI= 0.04V , +-0.4PSI approax. sensitivity
// calibration
float bar = psi*(0.0689475729);           // Conversion PSI to BAR

if(psi < 0)
    psi = 0;

    if(bar<0);
    bar=0;
lcd.setCursor (0,2);
lcd.print (psi);
lcd.print (" PSI");

lcd.setCursor ( 0,3);
lcd.print(bar);
lcd.print( " BAR");

lcd.setCursor(0,1);
lcd.print(sensorVoltage);

Serial.println (sensorVoltage);
Serial.println(bar);
Serial.println (psi);

delay (100);
}

void pump_control(void)

{
// read the analog in value:
  pot_init = analogRead(pot_pin);
  // map it to the range of the analog out:
  pump_init = map(pot_init, 0, 1023, 0, 255);  //  Duty cycle between %20 - %90: speed control , duty cycle between %0 - %20: turned off  , duty cycle between %90 - %100: full speed
  // map pump speed percent of full scale
  percentValue = map (pump_init, 0, 255,0,100);
  // change the analog out value:
  analogWrite(pump_pwm, pump_init);

  // print the results to the Serial Monitor:
  Serial.print("\t Speed Input = ");
  Serial.print(pot_init);
  Serial.print("\t Speed Output = ");
  Serial.print(pump_init);
  Serial.print("\t Pump Speed Percentage = ");
  Serial.println(percentValue);
  lcd.setCursor(0,0);        
  lcd.print("Speed: ");
  lcd.setCursor(8,0);        
  lcd.print("%");        
lcd.setCursor(9,0);        
lcd.print(percentValue);        

//  delay after the last reading:
  delay(2);

}

  void flow_control(void)  {

  count = 0;      // Reset the counter so we start counting from 0 again
  interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second
  noInterrupts(); //Disable the interrupts on the Arduino
  //Start the math
  flowRate = (count * 2.36);        //Take counted pulses in the last second and multiply by 2.25mL
  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
  totalFlowRate += flowRate;   // Add the liters passed in  second to the cumulative total

  Serial.println(flowRate);         //Print the variable flowRate to Serial
lcd.setCursor(0,4);        
  lcd.print("F: ");  
   lcd.setCursor(3,4);      
lcd.print(flowRate);
   lcd.setCursor(8,4);      
  lcd.print("lt/m");

lcd.setCursor(13,4);
lcd.print("TF:");
lcd.setCursor(16,4);
lcd.print(totalFlowRate);

}

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}
Moderators note : used code tags
 

Thread Starter

rennie1080

Joined Apr 10, 2017
52
By the way, I will change the calculation for flow I have made a mistake because of 1/liter.

flowRate = ( count * 8.93 ) ;
 
Last edited:

Reloadron

Joined Jan 15, 2015
7,523
Before I forget when looking at flow you have a rate and the other is totalizer, so you have a rate mode and a totalizer mode.

I am not an Arduino type but am a little familiar with them. I am not sure about how many functions you can get in that when measuring flow we use an interrupt which my understanding will slow things down. I am just not sure how well it will go.

As to the code I can't get it to compile, have you gotten this code to compile? I am trying on an Arduino Uno board.

Ron
 

Thread Starter

rennie1080

Joined Apr 10, 2017
52
I sent wrong worng ( uncompleted alternative code ). I am adding the code you can try these. I can compile them with nano.

C:
// initialize LCD lib with I2C serial communication protocol
#include <Wire.h> //I2C lib
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
// LCD lib
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

int pot_pin = A0;
int pump_pwm= 3;

int press_pin =A1;

int flowPin = 2;  //This is the input pin on the Arduino

double flowRate;    //This is the value we intend to calculate.
double totalFlowRate;
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.


int pot_init= 0;
int pump_init= 0;
int percentValue =0;



void setup() {


  lcd.begin(20,4);  // A4 - A5 connection SDA - SCL
  lcd.backlight();
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Nano) to run the function "Flow"

  Serial.begin(9600);
}

void loop() {
pressure_cal();
pump_control();
flow_control();


}

void pressure_cal(void) {

float sensorVoltage = analogRead(press_pin);   // sensor voltage A0
float psi = ((sensorVoltage-102)/204)*25;  // Offset    0 PSI= 0.5V=102 unit, 50 PSI= 2.5, 100 PSI= 4.5V, 1 PSI= 0.04V , +-0.4PSI approax. sensitivity
// calibration
float bar = psi*(0.0689475729);           // Conversion PSI to BAR

if(psi < 0)
    psi = 0;

    if(bar<0);
    bar=0;
lcd.setCursor (0,2);
lcd.print (psi);
lcd.print (" PSI");

lcd.setCursor ( 0,3);
lcd.print(bar);
lcd.print( " BAR");

lcd.setCursor(0,1);
lcd.print(sensorVoltage);

Serial.println (sensorVoltage);
Serial.println(bar);
Serial.println (psi);

delay (100);
}

void pump_control(void)

{
// read the analog in value:
  pot_init = analogRead(pot_pin);
  // map it to the range of the analog out:
  pump_init = map(pot_init, 0, 1023, 0, 255);  //  Duty cycle between %20 - %90: speed control , duty cycle between %0 - %20: turned off  , duty cycle between %90 - %100: full speed
  // map pump speed percent of full scale
  percentValue = map (pump_init, 0, 255,0,100);
  // change the analog out value:
  analogWrite(pump_pwm, pump_init);

  // print the results to the Serial Monitor:
  Serial.print("\t Speed Input = ");
  Serial.print(pot_init);
  Serial.print("\t Speed Output = ");
  Serial.print(pump_init);
  Serial.print("\t Pump Speed Percentage = ");
  Serial.println(percentValue);
  lcd.setCursor(0,0);     
  lcd.print("Speed: ");
  lcd.setCursor(8,0);     
  lcd.print("%");     
lcd.setCursor(9,0);     
lcd.print(percentValue);     

//  delay after the last reading:
  delay(2);

}

  void flow_control(void)  {

  count = 0;      // Reset the counter so we start counting from 0 again
  interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second
  noInterrupts(); //Disable the interrupts on the Arduino
  //Start the math
  flowRate = (count * 2.36);        //Take counted pulses in the last second and multiply by 2.25mL
  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
  totalFlowRate += flowRate;   // Add the liters passed in  second to the cumulative total

  Serial.println(flowRate);         //Print the variable flowRate to Serial
lcd.setCursor(0,4);     
  lcd.print("F: ");
   lcd.setCursor(3,4);   
lcd.print(flowRate);
   lcd.setCursor(8,4);   
  lcd.print("lt/m");

lcd.setCursor(13,4);
lcd.print("TF:");
lcd.setCursor(16,4);
lcd.print(totalFlowRate);

}

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}
I omit the LCD commands for second code. Maybe the reason why it couldnt compile is because of missing library.

C:
// initialize LCD lib with I2C serial communication protocol
#include <Wire.h> //I2C lib


int pot_pin = A0;
int pump_pwm= 3;

int press_pin =A1;

int flowPin = 2;  //This is the input pin on the Arduino

double flowRate;    //This is the value we intend to calculate.
double totalFlowRate;
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.


int pot_init= 0;
int pump_init= 0;
int percentValue =0;



void setup() {


  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Nano) to run the function "Flow"

  Serial.begin(9600);
}

void loop() {
pressure_cal();
pump_control();
flow_control();


}

void pressure_cal(void) {

float sensorVoltage = analogRead(press_pin);   // sensor voltage A0
float psi = ((sensorVoltage-102)/204)*25;  // Offset    0 PSI= 0.5V=102 unit, 50 PSI= 2.5, 100 PSI= 4.5V, 1 PSI= 0.04V , +-0.4PSI approax. sensitivity
// calibration
float bar = psi*(0.0689475729);           // Conversion PSI to BAR

if(psi < 0)
    psi = 0;

    if(bar<0);
    bar=0;

Serial.println (sensorVoltage);
Serial.println(bar);
Serial.println (psi);

delay (100);
}

void pump_control(void)

{
// read the analog in value:
  pot_init = analogRead(pot_pin);
  // map it to the range of the analog out:
  pump_init = map(pot_init, 0, 1023, 0, 255);  //  Duty cycle between %20 - %90: speed control , duty cycle between %0 - %20: turned off  , duty cycle between %90 - %100: full speed
  // map pump speed percent of full scale
  percentValue = map (pump_init, 0, 255,0,100);
  // change the analog out value:
  analogWrite(pump_pwm, pump_init);

  // print the results to the Serial Monitor:
  Serial.print("\t Speed Input = ");
  Serial.print(pot_init);
  Serial.print("\t Speed Output = ");
  Serial.print(pump_init);
  Serial.print("\t Pump Speed Percentage = ");
  Serial.println(percentValue);
//  delay after the last reading:
  delay(2);

}

  void flow_control(void)  {

  count = 0;      // Reset the counter so we start counting from 0 again
  interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second
  noInterrupts(); //Disable the interrupts on the Arduino
  //Start the math
  flowRate = (count * 2.36);        //Take counted pulses in the last second and multiply by 2.25mL
  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
  totalFlowRate += flowRate;   // Add the liters passed in  second to the cumulative total

  Serial.println(flowRate);         //Print the variable flowRate to Serial

}

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}
 

Thread Starter

rennie1080

Joined Apr 10, 2017
52
When I use this code, lcd show other variables but no flowmeter variables. In serial port, it write pump and pressure sensor variables but then write 0. ( By the way if does not work, you add your lcd lib. I use LCD with I2C module )

C:
// initialize LCD lib with I2C serial communication protocol
#include <Wire.h> //I2C lib
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
 // LCD lib
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

int pot_pin = A0;
int pump_pwm= 3;

int press_pin =A1;

int flowPin = 2;  //This is the input pin on the Arduino
byte resetButtonA = 11;

double flowRate;    //This is the value we intend to calculate. 

volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process. 


int pot_init= 0;
int pump_init= 0;
int percentValue =0;
int totalFlowRate = 0;


void setup() {


  lcd.begin(20,4);  // A4 - A5 connection SDA - SCL
  lcd.backlight();
  pinMode(resetButtonA, INPUT);
  digitalWrite(resetButtonA, HIGH);
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Nano) to run the function "Flow" 
   
  Serial.begin(9600); 
}

void loop() {
pressure_cal(); 
pump_control();
flow_control();


}

void pressure_cal(void) {

float sensorVoltage = analogRead(press_pin);   // sensor voltage A0
float psi = ((sensorVoltage-102)/204)*25;  // Offset    0 PSI= 0.5V=102 unit, 50 PSI= 2.5, 100 PSI= 4.5V, 1 PSI= 0.04V , +-0.4PSI approax. sensitivity
// calibration 
float bar = psi*(0.0689475729);           // Conversion PSI to BAR

if(psi < 0)
    psi = 0;

    if(bar<0);
    bar=0;
lcd.setCursor (0,1);
lcd.print (psi);
lcd.print (" PSI");

lcd.setCursor ( 0,2);
lcd.print(bar);
lcd.print( " BAR");

//lcd.setCursor(0,1);
//lcd.print(sensorVoltage);

Serial.println (sensorVoltage);
Serial.println(bar);
Serial.println (psi);

delay (100);
}

void pump_control(void)

{
 // read the analog in value:
  pot_init = analogRead(pot_pin);
  // map it to the range of the analog out:
  pump_init = map(pot_init, 0, 1023, 0, 255);  //  Duty cycle between %20 - %90: speed control , duty cycle between %0 - %20: turned off  , duty cycle between %90 - %100: full speed
  // map pump speed percent of full scale
  percentValue = map (pump_init, 0, 255,0,100);
  // change the analog out value:
  analogWrite(pump_pwm, pump_init);

  // print the results to the Serial Monitor:
  Serial.print("\t Speed Input = ");
  Serial.print(pot_init);
  Serial.print("\t Speed Output = ");
  Serial.print(pump_init);
  Serial.print("\t Pump Speed Percentage = ");
  Serial.println(percentValue);
  lcd.setCursor(0,0);         
  lcd.print("Speed: ");
  lcd.setCursor(8,0);         
  lcd.print("%");         
lcd.setCursor(9,0);         
lcd.print(percentValue);         

 //  delay after the last reading:
  delay(2);

}

  void flow_control(void)  {

  count = 0;      // Reset the counter so we start counting from 0 again
  interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second 
  noInterrupts(); //Disable the interrupts on the Arduino

  /*  if(digitalRead(resetButtonA) == LOW)
  {
    totalFlowRate = 0;
    lcd.setCursor(16, 3);
    lcd.print("0");
  }
    else {
    totalFlowRate += flowRate; 
    lcd.setCursor(16, 3);
    lcd.print(totalFlowRate);
   
     
    }   */
   
  //Start the math
  flowRate = (count * 8.93);        //Take counted pulses in the last second and multiply by 8.93mL 
  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
  totalFlowRate += flowRate;   // Add the liters passed in  second to the cumulative total

  Serial.println(flowRate);         //Print the variable flowRate to Serial
 lcd.setCursor(0,3);         
  lcd.print("F: ");   
   lcd.setCursor(3,3);       
lcd.print(flowRate); 
   lcd.setCursor(8,3);       
  lcd.print("lt/m");

lcd.setCursor(13,3);
lcd.print("T:");
lcd.setCursor(15,3);
lcd.print(totalFlowRate);

 }

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}
 

Reloadron

Joined Jan 15, 2015
7,523
It won't compile on an Uno which is all I have to play around with. I would guess and it is purely a guess that some of the problems you have are a result of the interrupt. Again while not my forte the code should have a nice flow to it, stepping through what you want to do in a nice orderly fashion. You also may want to toss this out on the Arduino Boards for some input from those guys. What would also help is a good C++ programming type which I am not.

Ron
 

Thread Starter

rennie1080

Joined Apr 10, 2017
52
Ron,you are right. Because of interrupt, other function cannot go out from loop. I can not find how to solve this problem yet. I am trying to figure it out.
 

Reloadron

Joined Jan 15, 2015
7,523
I had a feeling about that. I'll also look for a work around. I managed to find an old LCD display I was given a few years ago and after about 8 hours managed to get it to do something. Hopefully I can get it to actual;ly do more than tell me "Hello World". :) Anyway, there should be a work around for the interrupt issues, just need to figure it out.

Ron
 

Thread Starter

rennie1080

Joined Apr 10, 2017
52
with this code I can read variables from serial port but There some variables on LCD ( speed, psi and bar variables are on LCD but there are no changes for them. and I cannot see flowmeter variables on it ) I add also lcd library for arduino.

C:
#include <Wire.h> //I2C lib
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
 // LCD lib
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

const int pot_pin = A0;
const int pump_pwm= 3;

int press_pin =A1;

//flowmeter parameters
int flowPin = 2;  // input pin on arduino D2

double flowRate;   // value intented to calculate
double flowR; // flow value in lt
double totalFlow; // total output of flow from system

byte sensorInterrupt = 0; // interrupt 0 on D2 pin Arduino Nano

volatile int count; ////integer needs to be set as volatile to ensure it updates correctly during the interrupt process. 

int pot_init= 0;
int pump_init= 0;
int percentValue =0;



void setup() {

  lcd.begin(20,4);  // A4 - A5 connection SDA - SCL
  lcd.backlight();
  Serial.begin(9600); 
   
  pinMode( flowPin,INPUT); // Set D2 pin as an input
  attachInterrupt(sensorInterrupt,Flow,RISING); // Configures interrupt 0 ( pin D2 on Arduino Nano ) to run function "Flow" 
}
void flow_control(void) {
  count = 0; // reset counter so it could start counting from 0
  interrupts(); // enables interrupts on arduino nano
  delay(1000); // wait 1000 msec
  noInterrupts(); // disable interrupts on arduino nano
   
  //calculation for flowmeter 
  flowR = (count*8.93);   // 112 pulse/lt 423.84 pulse /gallon 
  flowRate= flowR*60;     // convert seconds to minutes, new unit is ml/minutes
  flowRate= flowRate/1000; // convert ml to liters, new unit is lt/minutes
  totalFlow += flowR;
  // Print the flow rate for this second in litres / minute
    Serial.print("Flow rate: ");
    Serial.print(int(flowRate));  // Print the integer part of the variable
    Serial.print("L/min");
    Serial.print("\t");       // Print tab space

    // Print the cumulative total of litres flowed since starting
    Serial.print("Output Liquid Quantity: ");       
    Serial.print(totalFlow/1000);
    Serial.println("L");

}

void Flow(void) 
{
  count++; // every time this function is called, increment  "count" by 1
}

void loop() {
  pressure_cal(); 
  pump_control();
  flow_control();

}


void pressure_cal(void) {

  float sensorVoltage = analogRead(press_pin);   // sensor voltage A0
  float psi = ((sensorVoltage-102)/204)*25;  // Offset    0 PSI= 0.5V=102 unit, 50 PSI= 2.5, 100 PSI= 4.5V, 1 PSI= 0.04V
  // calibration 
  float bar = psi*(0.0689475729);           // Conversion PSI to BAR


  lcd.setCursor (0,1);
  lcd.print (psi);
  lcd.print (" PSI");

  lcd.setCursor ( 10,1);
  lcd.print(bar);
  lcd.print( " BAR");

  //lcd.setCursor(17,1);
  //lcd.print(sensorVoltage);



  Serial.print("\t Sensor Value = ");
  Serial.print(sensorVoltage);
  Serial.print("\t Bar = ");
  Serial.print(bar);
  Serial.print("\t PSI = ");
  Serial.println(psi);

  delay (100);
}

void pump_control(void)

{
  // read the analog in value:
  pot_init = analogRead(pot_pin);
  // map it to the range of the analog out:
  pump_init = map(pot_init, 0, 1023, 50, 230);  //  duty cycle between %20 - %90: speed control , duty cycle between %0 - %20: turned off  , duty cycle between %90 - %100: full speed
  // map pump speed percent of full scale
  percentValue = map (pump_init, 50, 230,0,100);
  // change the analog out value:
  analogWrite(pump_pwm, pump_init);

  // print the results to the Serial Monitor:
  Serial.print("\t Speed Input = ");
  Serial.print(pot_init);
  Serial.print("\t Speed Output = ");
  Serial.print(pump_init);
  Serial.print("\t Pump Speed Percentage = ");
  Serial.println(percentValue);
  lcd.setCursor(2,0);         
  lcd.print("Speed: ");
  lcd.setCursor(8,0);         
  lcd.print("%");         
  lcd.setCursor(9,0);         
  lcd.print(percentValue); 
  lcd.print("     ");         

 //  delay after the last reading:
  delay(10);

}
 

Attachments

Reloadron

Joined Jan 15, 2015
7,523
I am seeing what you are seeing. Reading about these LCD Libraries is enlightening as there are likely a few dozen libraries out there and most have bugs and no well defined manuals. Great! :) Your code compiles just fine, I have to read through this more.

Ron
 
Top