Go Down

Topic: Water level analog sensor (Read 3175 times) previous topic - next topic


Aug 12, 2015, 11:16 am Last Edit: Aug 12, 2015, 11:26 am by arnix
Flow rate would be best solution. Anyhow, i can use just one sensor/probe.

I found some tutorials regarding flow rate measurements but most of then are using digital inputs and different approach. I was planning to implement this code into our code:

We dont need two buttons for now...
I dont know if i done this right, but i changed the digital sensor pin to analog pin 0.
I get some serial readings but they have nothing to do with the probe. I try to move probe slider and nothing happens. If this would work i would implement the code into our existing code so i could have tank level and flow rate in one solution.

Code: [Select]

#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Specify the pins for the two counter reset buttons and indicator LED
byte resetButtonA = 11;
byte resetButtonB = 12;
byte statusLed    = 13;

byte sensorInterrupt = 0;  // 0 = pin 2; 1 = pin 3
//byte sensorPin       = 2;
int sensorPin = analogRead(0);

// The hall-effect flow sensor outputs approximately 4.5 pulses per second per litre/minute of flow.
float calibrationFactor = 4.5;

volatile byte pulseCount; 

float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitresA;
unsigned long totalMilliLitresB;

unsigned long oldTime;

void setup()
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("                ");
  lcd.setCursor(0, 1);
  lcd.print("                ");
  // Initialize a serial connection for reporting values to the host
  // Set up the status LED line as an output
  pinMode(statusLed, OUTPUT);
  digitalWrite(statusLed, HIGH);  // We have an active-low LED attached
  // Set up the pair of counter reset buttons and activate internal pull-up resistors
  pinMode(resetButtonA, INPUT);
  digitalWrite(resetButtonA, HIGH);
  pinMode(resetButtonB, INPUT);
  digitalWrite(resetButtonB, HIGH);
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);

  pulseCount        = 0;
  flowRate          = 0.0;
  flowMilliLitres   = 0;
  totalMilliLitresA = 0;
  totalMilliLitresB = 0;
  oldTime           = 0;

  // The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
  // Configured to trigger on a FALLING state change (transition from HIGH
  // state to LOW state)
  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);

 * Main program loop
void loop()
  if(digitalRead(resetButtonA) == LOW)
    totalMilliLitresA = 0;
    lcd.setCursor(0, 1);
    lcd.print("0L      ");
  if(digitalRead(resetButtonB) == LOW)
    totalMilliLitresB = 0;
    lcd.setCursor(8, 1);
    lcd.print("0L      ");
  if( (digitalRead(resetButtonA) == LOW) || (digitalRead(resetButtonB) == LOW) )
    digitalWrite(statusLed, LOW);
  } else {
    digitalWrite(statusLed, HIGH);
  if((millis() - oldTime) > 1000)    // Only process counters once per second
    // Disable the interrupt while calculating flow rate and sending the value to the host
    //lcd.setCursor(15, 0);
    // Because this loop may not complete in exactly 1 second intervals we calculate
    // the number of milliseconds that have passed since the last execution and use
    // that to scale the output. We also apply the calibrationFactor to scale the output
    // based on the number of pulses per second per units of measure (litres/minute in
    // this case) coming from the sensor.
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    // Note the time this processing pass was executed. Note that because we've
    // disabled interrupts the millis() function won't actually be incrementing right
    // at this point, but it will still return the value it was set to just before
    // interrupts went away.
    oldTime = millis();
    // Divide the flow rate in litres/minute by 60 to determine how many litres have
    // passed through the sensor in this 1 second interval, then multiply by 1000 to
    // convert to millilitres.
    flowMilliLitres = (flowRate / 60) * 1000;
    // Add the millilitres passed in this second to the cumulative total
    totalMilliLitresA += flowMilliLitres;
    totalMilliLitresB += flowMilliLitres;
    // During testing it can be useful to output the literal pulse count value so you
    // can compare that and the calculated flow rate against the data sheets for the
    // flow sensor. Uncomment the following two lines to display the count value.
    //Serial.print(pulseCount, DEC);
    //Serial.print("  ");
    // Write the calculated value to the serial port. Because we want to output a
    // floating point value and print() can't handle floats we have to do some trickery
    // to output the whole number part, then a decimal point, then the fractional part.
    unsigned int frac;
    // Print the flow rate for this second in litres / minute
    Serial.print(int(flowRate));  // Print the integer part of the variable
    Serial.print(".");             // Print the decimal point
    // Determine the fractional part. The 10 multiplier gives us 1 decimal place.
    frac = (flowRate - int(flowRate)) * 10;
    Serial.print(frac, DEC) ;      // Print the fractional part of the variable

    // Print the number of litres flowed in this second
    Serial.print(" ");             // Output separator

    // Print the cumulative total of litres flowed since starting
    Serial.print(" ");             // Output separator
    Serial.print(" ");             // Output separator
    lcd.setCursor(0, 0);
    lcd.print("                ");
    lcd.setCursor(0, 0);
    lcd.print("Flow: ");
    if(int(flowRate) < 10)
      lcd.print(" ");
    lcd.print((int)flowRate);   // Print the integer part of the variable
    lcd.print('.');             // Print the decimal point
    lcd.print(frac, DEC) ;      // Print the fractional part of the variable
    lcd.print(" L");
    lcd.setCursor(0, 1);
    lcd.print(int(totalMilliLitresA / 1000));
    lcd.setCursor(8, 1);
    lcd.print(int(totalMilliLitresB / 1000));

    // Reset the pulse counter so we can start incrementing again
    pulseCount = 0;
    // Enable the interrupt again now that we've finished sending output
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);

 * Invoked by interrupt0 once per rotation of the hall-effect sensor. Interrupt
 * handlers should be kept as small as possible so they return quickly.
void pulseCounter()
  // Increment the pulse counter

There is one other approach:
Code: [Select]

volatile int NbTopsFan; //measuring the rising edges of the signal
int Calc;                               
int hallsensor = 8;    //The pin location of the sensor

void rpm ()     //This is the function that the interupt calls
  NbTopsFan++;  //This function measures the rising and falling edge of the
// The setup() method runs once, when the sketch starts
void setup() //
  pinMode(hallsensor, INPUT); //initializes digital pin 2 as an input
  Serial.begin(9600); //This is the setup function where the serial port is initialised,
  attachInterrupt(0, rpm, RISING); //and the interrupt is attached
// the loop() method runs over and over again,
// as long as the Arduino has power
void loop ()   
  NbTopsFan = 0;  //Set NbTops to 0 ready for calculations
  sei();    //Enables interrupts
  delay (1000); //Wait 1 second
  cli();    //Disable interrupts
  Calc = (NbTopsFan * 60 / 7.5); //(Pulse frequency x 60) / 7.5Q, = flow rate in L/hour
  Serial.print (Calc, DEC); //Prints the number calculated above
  Serial.print (" L/hour\r\n"); //Prints "L/hour" and returns a  new line


What about pressure sensors for measuring tank levels?
But they are not cheap!

Go Up