Arduino Liquid Metering Apparatus

Hi, My mechanical engineering class asked us to make a liquid metering device to dispense a requested amount of water anywhere form 10mL to 1000mL accurate to +-2mL. So we thought small and put an aquarium pump in a bucket, spliced the AC power wire to a relay...and used the arduino to activate the pump for a given amount of time. You would think this was an easy solution. Nope. I used the delay function to keep the pump running for X amount of time specified by the serial user input. Strange thing is that delay(1000) did not keep the pump on for 1 second. It was about 1/4 of a second. And if we wanted to pour out 1L it needed an input of one followed by about 200 zeros! Apparently the more zeros you add, the more water pumps out. We calculated this as 1 and 8 zeros is about 1.5mL. These values are consistent but what if the prof asks us to pour out a value not along the 1.5mL increment? This makes no sense due to the fact that the pump runs at 212L/hour...our little receiving bucket would be filled 10 times over (guesstimate) before 1*10^200 would finish. Ill post the code, can anyone help me make sense of this/code a better timer to shut off the pump using real timing, like 1000 will run for 1 sec etc etc.

int flowRate = 0.05833; int timeDispense; int errorConstant = 9.65; int volumeDesired;

void setup() { Serial.begin(19200); //sets port speed pinMode(8, OUTPUT); //sets pin 8 as output }

void loop() { if (Serial.available()) //if port is open { int volumeDesired = Serial.read(); //set desired volume as numeric value of keyboard input calculate(); //calculate dispensing time digitalWrite(8, HIGH); //activate pump circuit on pin 8 delay(timeDispense); //keep it on for x amount of time digitalWrite(8, LOW); //shut off pump

} }

void calculate() { timeDispense = (volumeDesired/flowRate)+ errorConstant; }

int flowRate = 0.05833;

This got rounded off to 0.

int errorConstant = 9.65;

This got rounded off to 9.

My mechanical engineering class

This implies a college level course. One would think that by the time you got to college, someone in the class would KNOW the definition of integer.

timeDispense = (volumeDesired/flowRate)+ errorConstant;

Oh, excellent, dividing by 0. That generally produces useful results, eh?

What is sending the data to the serial port? Is it sending it as a number, as you expect? Or is it, more likely, sending it as a string that you are mis-reading and pretending that you got a number?

int flowRate = 0.05833;
int timeDispense;
int errorConstant = 9.65;
int volumeDesired;

void setup() {  Serial.begin(19200); //sets port speed  pinMode(8, OUTPUT); //sets pin 8 as output }

void loop() {    if (Serial.available()) //if port is open   {     int volumeDesired = Serial.read(); //set desired volume as numeric value of keyboard input     calculate(); //calculate dispensing time     digitalWrite(8, HIGH); //activate pump circuit on pin 8     delay(timeDispense); //keep it on for x amount of time     digitalWrite(8, LOW); //shut off pump      } }   void calculate() { timeDispense = (volumeDesired/flowRate)+ errorConstant; }

Oh, your piece of code is a marvel. I think I'm going to use for my next class as an example how one can layer errors to yield totally unpredictable results indistinguishable from magic.

Just to sum it up:

  • As Paul wrote, int with fractional parts are not what you expect.
  • Dividing by 0 isn't very healthy either.
  • Your delay is thus a constant 9ms because of the errorConstant
  • And then you'll realise, that you get Ascii values from the serial console and not numbers, so if you type 2 you will deal with the number 50. 22 will dispense let you deal with twice with 50.
  • To top it off, I wouldn't be surprised if the way you calculate the time is amplifying rounding errors, and difference between 5 and 6 aren't that precise. But I might be wrong in this case, so lets give you the benefit of doubt and just call the formula inefficient.

Lovely, a work of art.

Korman

You might be better off using something like a baby oral medicine syring operated by a servo to pump measured amounts of liquids. You may need to google for metering pump designs to get some idea of what is currently in use.

One final thought:

if (Serial.available()) //[glow]if port is open[/glow]

This is NOT what Serial.available() means at all.

I see. I'm glad I saw this thread.

If this is the way I would have got treated if I ever came as far as writing a program that does anything at all, then I might as well give up now.

I can't say it's been an enjoyable experience so far, but obviously it only gets worse.

So, it's not OK to pick on stupid mistakes, but it is OK to ask a public forum why code full of stupid mistakes doesn't work.

I'll keep that in mind in the future. Or not.

You should.

If this is the way I would have got treated if I ever came as far as writing a program that does anything at all, then I might as well give up now.

This program is really exceptionally in the respect, that fixing one problem doesn't necessarily show any improvement and a beginner can get totally frustrated with such code Whatever he does to try to fix a problem won't, the program goes on behaving irrationally. Only if one has fixed the critical mass of problems that things will get better, but doing that may take more effort than a beginner might spend.

And this is the reason why I'm a big believer in taking small steps and validating each step along the way, even if it takes more time in the beginning. A simple Serial.println() of the calculated value might have shown that the calculated result is garbage, thus any delay and liquid will be garbage too. But I guess, that mindset is so common these days any more.

And yes, I will use that code as an example to show why taking small steps is a good idea.

Korman

And this is the reason why I'm a big believer in taking small steps and validating each step along the way, even if it takes more time in the beginning.

I am, too. The time spent compiling and uploading, adding a small handful of well thought out lines each time, and testing, is considerably less than that required to research why something is failing, and how to fix it.

OP could have discovered most of the issues without posting to the forum. Serial.print() is a very useful, but way under-utilized tool.

Print out each variable. See if the output meets expectations. In OPs code, almost nothing would have printed out correctly, leading to an AHA moment, instead of being publicly embarrassed by such sloppy code.

Okay. Lets get some things straight.

  1. The comments were added by a friend in order to help understand the code. I told him to write the comments and ill check to see if he understands it. Cleary i uploaded the incorrect version.

  2. The integer values were not intended to be used. That was more pseudocode than anything. We needed to present so it had to look like some math was used.

  3. I made the stupid mistake of forgetting that ascii serial will not read as integers. Silly me.

My question is how can anyone learn if they are ruthlessly bashed for their errors. I mean the level of sarcasm and malice in the replies I read were rediculous. >:( You people should be ashamed of yourselves. Those who were kind enough to point out my "errors" I thank whole heartedly for your CONSTRUCTIVE criticism. One can never learn from his mistakes if one is ridiculed for them. Why would I ever post again if this is how I am to be treated!?!?!

My question is how can anyone learn if they are ruthlessly bashed for their errors

The compiler will ruthlessly bash you for syntactic errors.
Symantic errors, it can’t help you with.
That’s what we’re here for. :slight_smile:

The integer values were not intended to be used

OK. So don’t use them.

I made the stupid mistake of forgetting that ascii and serial are not 1 to 1

I don’t understand this comment.

If next time you check the values of your variables - either read or calculated - yourself and localise the problem yourself, this whole thread will have had a positive effect. People tend to forget that a major part of development is debugging to first understand problems and then fix them.

Also you were very unfortunate that the code you presented was in such a poor state. We just saw what you posted, not what you had in mind or tried out. Asking the right question is often half the answer.

Korman

Whats with the sarcasm? Will it make me a better programmer? Will it teach me the errors of my ways? The only thing it taught me is to avoid forums like this one. Sadly this is the most active arduino forum so if I do need help I have to face the barrage of sarcastic artillery shells.

The best way to state the errors:

-Your dividing by zero
-ASCII strings will not read as integers
-BTW some of your comments (specify & clarify) are incorrect

You guys wasted your time trying to be cute with sarcasm in hopes of what? a few laughs? being pompous? not sure what you got but I hope it was worth the time youll never get back.

You guys wasted your time trying to be cute with sarcasm

I failed to spot any sarcasm in this thread. (Believe me, I have an masters degree in sarcasm).
What I did miss was scientific/engineering rigour in the statement of the problem.
You did say you were studying engineering, didn’t you?
(Ooo! there was sarcasm, I saw it! Right there!)

"Also you were very unfortunate that the code you presented was in such a poor state. We just saw what you posted, not what you had in mind or tried out. Asking the right question is often half the answer."

Like sharks to chum... A true teacher does NOT berate a student. EVER.

Oh, your piece of code is a marvel.

Lovely, a work of art.

Oh, excellent, dividing by 0. That generally produces useful results, eh?

This implies a college level course. One would think that by the time you got to college, someone in the class would KNOW the definition of integer.

A true teacher does NOT berate a student. EVER

And who told you that?

So did I clarify the points of sarcasm?

If you put a dunce hat on a student, the class will laugh. If the teacher is immature he/she might laugh as well. Eventually the student will become discouraged to learn for fear of being called an idiot. Dunce caps are highly frowned upon in scholastic practices. Whats with you people?

Whats with you people?

"Hi, I'm 14 years old, and trying to learn Arduino programming. I have some problems with this code that I don't understand. Please help!" will get completely different treatment than "We are mechanical engineering majors...".

It's about context. Certain expectations and assumptions are made, and latitude granted, to individual junior high students. That same latitude goes away when you, collectively, have grown up with computers all of your lives.

Your code contains basic, first 20 minutes of class, errors.