Decrementing Volume

AHewat: The flow sensor, Arduino and everything is already up and running,

I missed this earlier.

Post your code - then you will get help.

...R

You would not belive how filthy a beer line gets even after a short time. If you have seen the "snot" that comes out of a dirty line you do not want to think about the cultures growing on the wheel of this meter after a month.

GROSS ! (I think I'll start ordering bottled beer...)

I don't drink beer, so it's all the same to me anyway.

Cleaning the sensor is the same problem as cleaning the piping in the first place (presumably using bleach), with some concern about forcing liquid through too rapidly.

The carbon dioxide is used to pressurise the keg (thus carbonating it before dispensing) and is what makes it flow from the tap. While under pressure in the plumbing, the beer does not froth, so measuring is not a problem. In pubs, the kegs are usually "chained" so that beer flows from one to the next, combining the dispensing capacity of many kegs.

My concern in this project is the need for retention of the current value when the power to the device is turned off.

The "Kegomatic" uses a Pi as this made the Internet connection for "tweets" simpler. Other projects have performed this with an Arduino.

I used to work in a restaurant ages ago and there is protocol that should be followed. The equipment that needs periodic cleaning must be cleaned using SPARE units. Meaning the flowmeter must be removed and replaced with a SPARE . The dirty unit should be flushed and cleaned with the proper cleaning agents and then put in the SPAREs cabinet.

Paul__B: cleaning the piping in the first place (presumably using bleach), with some concern about forcing liquid through too rapidly.Arduino.

Cleaning the pipe is no problem, you get little squishy balls that do that. In big installations you have a special port and switch valve on one end of the line. You put the ball in there, switch the line from "beer" to "cleaning" and the ball gets pressed though the line and scrubs everything along the way.

On small installations you have to take of the hose by hand and attach it to the water line and do that. You get those in various sizes and shapes for all sort of piping:

Product Page

Greetings, Peter

WOW. Who knew ?

On the topic of cleaning, beer equipment is cleaned with a special no-rise sanitiser. The sanitiser kills all bacteria within 30 seconds of contact, does not foam up (like soap) and requires no rinsing. It is also orderless and tasteless (unlike bleach). Once ready to clean, you simply use a spare keg with the sanitiser inside, and run your system for 30 seconds as if you were pouring a long beer. It's that simple.

As requested here is the code I'm using. I previously stated, I am new and I'm not looking for someone to write my code, I want to learn how, but am starting with this sketch as a basis on which to modify.

Right now the code calculates the total fluid amount that has passed through the sensor, but I want to invert that so that it deducts from a set value of 19L.

My question therefore is, how? Is there an initial value I can set? Is it as simple as changing a "+" to a "-"? Can I create a mathematical function to do this? If someone can point me in the right direction, that is all I want.

If my question is out of line, obvious to answer then I apologize, trust me, its just my lack of knowledge and understanding.

include "LiquidCrystal.h"

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

// which pin to use for reading the sensor? can use any pin!

define FLOWSENSORPIN 2

// count how many pulses! volatile uint16_t pulses = 0; // track the state of the pulse pin volatile uint8_t lastflowpinstate; // you can try to keep time of how long it is between pulses volatile uint32_t lastflowratetimer = 0; // and use that to calculate a flow rate volatile float flowrate; // Interrupt is called once a millisecond, looks for any pulses from the sensor! SIGNAL(TIMER0_COMPA_vect) { uint8_t x = digitalRead(FLOWSENSORPIN);

if (x == lastflowpinstate) { lastflowratetimer++; return; // nothing changed! }

if (x == HIGH) { //low to high transition! pulses++; } lastflowpinstate = x; flowrate = 1000.0; flowrate /= lastflowratetimer; // in hertz lastflowratetimer = 0; }

void useInterrupt(boolean v) { if (v) { // Timer0 is already used for millis() - we'll just interrupt somewhere // in the middle and call the "Compare A" function above OCR0A = 0xAF; TIMSK0 |= _BV(OCIE0A); } else { // do not call the interrupt function COMPA anymore TIMSK0 &= ~_BV(OCIE0A); } }

void setup() { Serial.begin(9600); Serial.print("Flow sensor test!"); lcd.begin(16, 2);

pinMode(FLOWSENSORPIN, INPUT); digitalWrite(FLOWSENSORPIN, HIGH); lastflowpinstate = digitalRead(FLOWSENSORPIN); useInterrupt(true); }

void loop() // run over and over again { lcd.setCursor(0, 0); lcd.print("Pulses:"); lcd.print(pulses, DEC); lcd.print(" Hz:"); lcd.print(flowrate); //lcd.print(flowrate); Serial.print("Freq: "); Serial.println(flowrate); Serial.print("Pulses: "); Serial.println(pulses, DEC);

// if a plastic sensor use the following calculation // Sensor Frequency (Hz) = 7.5 * Q (Liters/min) // Liters = Q * time elapsed (seconds) / 60 (seconds/minute) // Liters = (Frequency (Pulses/second) / 7.5) * time elapsed (seconds) / 60 // Liters = Pulses / (7.5 * 60) float liters = pulses; liters /= 7.5; liters /= 60.0;

/* // if a brass sensor use the following calculation float liters = pulses; liters /= 8.1; liters -= 6; liters /= 60.0; */ Serial.print(liters); Serial.println(" Liters"); lcd.setCursor(0, 1); lcd.print(liters); lcd.print(" Liters ");

delay(100); }

[quote author=Nick Gammon date=1423024129 link=msg=2074805] Well that sounds simple enough. Where are you storing the previous total? [/quote]

I think the total appears to be stored within this section of code:

// if a plastic sensor use the following calculation // Sensor Frequency (Hz) = 7.5 * Q (Liters/min) // Liters = Q * time elapsed (seconds) / 60 (seconds/minute) // Liters = (Frequency (Pulses/second) / 7.5) * time elapsed (seconds) / 60 // Liters = Pulses / (7.5 * 60) float liters = pulses; liters /= 7.5; liters /= 60.0;

I think this is where the pulses are turned into an actual measurement in Litres. Would this be where I can add another line to create a subtraction function, or does the Arduino language support an easier method?

Please put your code in CODE TAGS by clicking the MODIFY button, highlighting the code and clicking the
"<>" CODE TAGS button just to the left of the QUOTES dialog cloud button, and click SAVE. Please do this
whenever you post code.

I’m having a little trouble understanding what this means:

The flow sensor, Arduino and everything is already up and running,

What exactly does that mean ? What status information are you in fact receiving ?
Please post a photo of the OLED with the status information displayed.
What , if anything , can you tell us about the code ?
You don’t seem to know anything about the variables.
Please install this terminal capture program and capture the serial output by select the comm port for your
arduino (make sure your arduino serial monitor is closed) and running the program until you have printed
out the to the terminal program screen . Then click “File/capture buffer to file” and save the file and post it
as an attachment along with the photo of the OLED display. Once you have done this we can debug the program.

CLEAR TERMINAL

What is this supposed to do ?

  liters /= 7.5;
  liters /= 60.0;
  liters /= 8.1;
  liters -= 6;
  liters /= 60.0;

Those don’t look like a valid math operations. Did you write that code ?
Did you write any of this code ? If not, then where did you get it from ?

When you said this:

I can follow the code when its written, but beyond simple changes I’m a a bit lost

What EXACTLY were you telling us ? (that you didn’t write the code and you got it somewhere and
want to modify it ?)

DIVISION

@AHewat: Please edit your post, select the code, and put it between [code][/code] tags.

You can do that by hitting the “Code” button above the posting area (It looks like a scroll with < > inside it).

Here is my Public Service contribution - the OPs code from Reply #26

#include "LiquidCrystal.h"
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

// which pin to use for reading the sensor? can use any pin!
#define FLOWSENSORPIN 2

// count how many pulses!
volatile uint16_t pulses = 0;
// track the state of the pulse pin
volatile uint8_t lastflowpinstate;
// you can try to keep time of how long it is between pulses
volatile uint32_t lastflowratetimer = 0;
// and use that to calculate a flow rate
volatile float flowrate;
// Interrupt is called once a millisecond, looks for any pulses from the sensor!
SIGNAL(TIMER0_COMPA_vect) {
  uint8_t x = digitalRead(FLOWSENSORPIN);

  if (x == lastflowpinstate) {
    lastflowratetimer++;
    return; // nothing changed!
  }

  if (x == HIGH) {
    //low to high transition!
    pulses++;
  }
  lastflowpinstate = x;
  flowrate = 1000.0;
  flowrate /= lastflowratetimer;  // in hertz
  lastflowratetimer = 0;
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
  }
}

void setup() {
   Serial.begin(9600);
   Serial.print("Flow sensor test!");
   lcd.begin(16, 2);
   
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH);
   lastflowpinstate = digitalRead(FLOWSENSORPIN);
   useInterrupt(true);
}

void loop()                     // run over and over again
{
  lcd.setCursor(0, 0);
  lcd.print("Pulses:"); lcd.print(pulses, DEC);
  lcd.print(" Hz:");
  lcd.print(flowrate);
  //lcd.print(flowrate);
  Serial.print("Freq: "); Serial.println(flowrate);
  Serial.print("Pulses: "); Serial.println(pulses, DEC);

  // if a plastic sensor use the following calculation
  // Sensor Frequency (Hz) = 7.5 * Q (Liters/min)
  // Liters = Q * time elapsed (seconds) / 60 (seconds/minute)
  // Liters = (Frequency (Pulses/second) / 7.5) * time elapsed (seconds) / 60
  // Liters = Pulses / (7.5 * 60)
  float liters = pulses;
  liters /= 7.5;
  liters /= 60.0;

/*
  // if a brass sensor use the following calculation
  float liters = pulses;
  liters /= 8.1;
  liters -= 6;
  liters /= 60.0;
*/
  Serial.print(liters); Serial.println(" Liters");
  lcd.setCursor(0, 1);
  lcd.print(liters); lcd.print(" Liters        ");

  delay(100);
}

I can sort of understand why the OP is confused. Why on earth is there such complicated interrupt code when all that is needed is something like

void setup() {
  // other stuff
  attachInterrupt(0, pulseCount, RISING);
}

and

void pulseCount() {
   totalPulses ++;
}

...R

Robin2: I can sort of understand why the OP is confused. Why on earth is there such complicated interrupt code when all that is needed is something like

void pulseCount() {
   totalPulses ++;
}

Indeed, a reliable pulse count through polling is a bit problematic when writing to a LCD and serial port. The above mentioned solution is extremely simpel. In fact, the geiger counter that sits on my workbench right now uses the excact same method and delivers reliable data.

Accumulate every count delivered by the sensor, determine a equivilant pulse/liter ratio and you are done. But you should store the acumulated value in the EEPROM so the whole unit does not "forger" it when powered down or after a reset.

To get a pulse/liter ratio just set the counter to zero and draw one liter into a measuring cup.

pulsecount / calibrationvalue = liters remaining = startvalue - liters dislay remaining