Please help with complex flow controller code

I'm working on an Arduino-based open source unit that will control flow in educational river models we build -- see

Having a hard time with parts of this code! The device is a waterproof box with three buttons for control: up, down, and an "aux" button. The Arduino inside sends control pulses to a Critical Velocity SP-315 PWM unit that controls a small 12-volt pump. Descriptive video here:

I'm having a hard time with the menu program; it works pretty well, but I can't quite figure out how to:

  1. call the menu with the "aux" button, got that to work--
  2. use the up/down buttons to go through choices; got that--
  3. then the third "aux" button to select and run a function, but not return to the menu program.

I have it working, but bugs are driving me crazy; can't quite grasp how to call the menu, then exit it to run the "hydrograph" routine without then coming back to it; my question is how to get out of the menuRun function for good!

In my menuRun function I want to call hyDroGraphRun and then go back to loop; I'm doing this using a while statement.

If I run "while menuOn =1" and then set menuOn = 0, do I exit the function and never come back? Is there a better way?

Here's the relevant code (too big to post here). The menuRun section is the one I'm having trouble with. Many thanks to those who've helped so far.[timestamp=1287629361]

The complex program flow of your complex flow controller is not very obvious from the code you posted (or maybe it is just my browser) - the indentation is insane.
Could you reformat and repost, please?

At first glance, you seem to have virtually all variables with global scope - this is not very helpful. Reducing scope and using function parameters will make your code easier to follow.
Also, the code is liberally sprinkled with magic number - these will be difficult to understand in a few months time.

  counter = 0;
  while(counter < 150)

Do you have an aversion to “for” loops?

void resetQt()
      qSum = 0;
      reset = millis();         //value subtracted from elapsed time

Unless you really know what you’re doing, recursion on the Arduino is a bad idea.

You could maybe get rid of some of the noise comments too;void whatever () { tells us it is the start of a function called “whatever”, so there’s no need to thrash your slash key telling us that.

analogWrite(speakerPin, 400);


delay (200);                                                // give voltage 3/10 sec to stabilize

Always good to align code with comment.

Even with code formatting,and forgetting the recursion, that's pretty horrible. I'd suggest scrapping, and restarting from scratch.

@AWOL; since I am geologist, machinist, janitor, crappy code writer, etc., etc. in my little organization, and this code works, I’m not throwing away the 50 hours or so I have in it (at least not now), even if it is horrible :slight_smile:

@Groove; I meant to comment out all those calls to loop (), thanks for finding that stray. Was trying to get out of my menu function, and still don’t know how to best do it.

By “magic numbers” you mean counters for timers, etc.? And very sorry about the indentation–I switch from Arduino interface to another text editor and somehow that got all messed up. I like the slash bars so I can find sections. Cue violins — I am working about 70 hours a week (now THAT is insane :slight_smile: now and clearly this could be better, but it’s going out if it works, and it won’t be perfect, we’ll update it later–our collaborators understand.

Will try to reformat and repost today; thanks for your help.

What’s the best way to post a huge chunk of code like this; is my link to a *.txt file OK?

And almost forgot, this was really the main question I have, can somebody help with it?

If I run "while menuOn =1" and then set menuOn = 0, do I exit the function and never come back? Is there a better way?

If I run "while menuOn =1" and then set menuOn = 0, do I exit the function and never come back?

The next time the loop starts, it will be detected that menuOn is no longer 1, so the while loop will not be processed. That may, or may not be the end of the function. Even if the function ends, that does not mean that it won't be called again.

Many thanks Paul, I think I understand. The stray call to loop() that Groove found was my bug; all working very nicely now, though not elegant I understand. I thought running the hydrogrphs would be the tricky part, but that turned out easy (with great help from Grumpy Mike). :)

The stray call to loop() that Groove found was my bug

Oi! ;)

Glad you got it going.

OK, rewritten code here (still riddled with horribleness, /////, and insane indentation) but it works fine:

And a video to show the equipment and operation:

Thanks for past and future help!