Go Down

Topic: varying interval timer (Read 172 times) previous topic - next topic

Killarado

Hi everyone, I have an arduino mega hooked up to an 8 relay module. Each relay runs 1 peristaltic pump. Since each pump varies slightly I need to be able to calibrate each pump individually. The way I thoughat to do this was to have individual intervals for each pump. Representing how long it takes that pump to pump 1ml. then every time the interval has passed it counts up 1ml.
when the specified amount of milliliters is pumped then it shuts the pump off and starts the next pump till its all done with all 8 pumps. This is my code but for some reason it does not work properly. The interval if smaller starts off slow then works up to specified speed. Please help.
Code: [Select]
int relaypin [8]={3,4,5,6,7,8,9,10};
int ledpin [8]={11,12,13,14,15,16,17,18};
int ledState=LOW;
long interval [8]={1000,1200,1400,1150,900,1000,1300,1250};
int intervalLimit[8]={10,20,15,13,11,15,23,13};
int z=0; //counter for interval
long previousMillis=0;
void setup(){
    int i;
    for(i=0;i<8;i++)
    {
        pinMode(relaypin[i], OUTPUT);
        pinMode(ledpin[i], OUTPUT);
        digitalWrite(relaypin[i], HIGH);
        digitalWrite(ledpin[i], LOW);
     }
}

void loop()
{
    int i=0;     
    for(i=0;i<8;)
    {
       
       unsigned long currentMillis = millis();      
      if(currentMillis - previousMillis > interval[i])
      {
        digitalWrite(relaypin[i], LOW);
        z++;
        if (ledState==HIGH)
          {
            ledState=LOW;
          }
        else
          ledState=HIGH;
       
        if (z>=intervalLimit[i])
          {
              digitalWrite(relaypin[i], HIGH);
              digitalWrite(ledpin[i], LOW);
              i++;
           }
      }
}
}
   

PaulS

What is ledState doing?

Why is your code so poorly indented?

What do i and z mean? Use names that make sense!

aarg

#2
Mar 18, 2015, 12:02 am Last Edit: Mar 18, 2015, 12:04 am by aarg
What do i and z mean? Use names that make sense!
I agree, what is "z"?

But "i" is a well accepted short form for "iteration" or "index", take your pick. It's used standardly in some mathematical notations.
It is considered by many skilled programmers to be perfectly acceptable for a small iterated or indexed loop in C, take your pick. Where it is obvious that it is used for that purpose, is completely local in scope, and has no other uses besides the iteration and indexing that is performed in that small loop.

If you use it for anything else, then yes, it's not good. But in this case the coder is following a well established general practice. I have seen some textbooks that even specifically recommend it, but only with the limitations I've listed above, for small loops or functions.

It's actually less cluttered, and very concise and easy to read. But it has to be used judiciously.


PaulS

Quote
But "i" is a well accepted short form for "iteration" or "index", take your pick. It's used standardly in some mathematical notations.
Sure. But, doesn't relayNumber make more sense? How many times do you really have to type that? If typing relayNumber is more trouble than typing i, I'd suggest that programming is NOT in your future.

(Or whatever i is supposed to mean).

aarg

#4
Mar 18, 2015, 12:56 am Last Edit: Mar 18, 2015, 01:02 am by aarg
Yes. Actually the "i" in loop() is confusing. It really does correspond to a relay number. It also spans far too many lines of code for this kind of use. It's easy to forget what it stands for.

In some cases, a variable doesn't refer to anything at all, it's just an iterator. There are only four lines of code inside the for loop inside his setup().

The idea is that he wants to to the same thing with a certain number ( 8 ) if relaypin[]'s and ledpin[]'s. In that case, the thing called "i" doesn't actually refer to anything like a relay. It's just an iterator. When it's used to refer to a relay, as in relaypin, it's easy to see that the meaning is just something like "the relaypin that we are indexing at the moment". It is just an index to vector through 0 to 7 in ways that are defined by the way "i" is used. It might point to a relay, or a led, or a half dozen other things. Hence the best label you could give it would be "index" or something like that, so relaypin[index]. Or "relaypin[pinIndex]". So it becomes a question of style. But there is a point of diminishing returns with this specificity.

Some variables have a historical mathematical context that makes their meaning clear, provided there is adequate context.If you see a function declaration like:

widgetPosition(x, y, z)

You would have little problem understanding the role of x, y, and z. Also, the name of the function tells you what they are coordinates of. That is the context. Again, it depends on module size. If widgetPosition is a 2,000 line function, then you might be stumped by a reference to "x" in the middle of it. In that case, something like passedXposition would be preferable. But not if it consists of 8 lines. In that case, it's just extra junk that the brain would discard anyway.

Module size is really central to this. I've heard of a company that prohibited its programmers from creating functions that exceeded 20 lines. Perhaps that is excessive, but I'll bet it removes a lot of the burden from variable names for conveying meaning.

Killarado

Well you guys are on the wrong topic. Z is a counter to let me know how many ml have been pumped (also to let the Controller know when to stop pumping). i is just to keep track of which pump is working at any given time. The led state toggles at the same speed as ml being pumped. A kind of metronome if you will. Since all the pumps share one power supply the only way to accurately pump is to go down the line and pump them individually. One then the other. My real problem is when it comes to varying the interval for each pump. I had the code written out with the interval for each pump in its own menu screen but the inervals are not changing. I want to be able to dial each pump in for ml/ms. Then I'll just make an address in EEPROM and save these calibrations. Also be able to recalibrate on the fly. Thank you guys for your input.

Killarado

I see what you're saying though in my actual code at the end of each  interval I digitalWrite(ledpin, ledstate);. This toggles the led at the rate of milliliters per milliseconds.

aarg

Well you guys are on the wrong topic. Z is a counter to let me know how many ml have been pumped
Really good proof that you should pay attention to the advice about your variable naming conventions.

Killarado

ok, but moving on can someone please try uploading the code. And try changing the intervals to different lengths. And help me fix my actual problem.Don't forget to add the digitaWrite(ledpin, ledState); At the end of the interval. I already know my programming could use work. I'm self tought and I will head all good advice.  Thanks guys.

tmd3

... in my actual code ...
Maybe you want to post actual code.  I'm not sure that we want to spend time analyzing this, only for you to tell us that what we've found isn't relevant.

[quote... can someone please try uploading the code.[/quote]Have you uploaded it?  I suspect not.  I think that you're running one sketch, while showing us another.  The posted sketch never updates the value of previousMillis, so, after a little bit of time, this test -
Code: [Select]
     if(currentMillis - previousMillis > interval[i])

- will always pass.  I can't see any way that this sketch does what you say it does.  If your "actual code" updates previousMillis properly, I've wasted time figuring that out.

I'll recommend that you read, "How to use this forum - please read."  It's accessible from the top of the topic list in each section of the forum.  In particular, you'll want to read item #11, "Tips for getting the most out of your post," with particular attention to this part:
Quote
Post a complete sketch (program code)! If you don't you waste time while people ask you to do that. However, with coding problems, if possible post a "minimal" sketch that demonstrates the problem - not hundreds of lines of code.
It looks like you've tried to post a minimal sketch, but it appears to demonstrate a problem that's not the same as the on you describe.  Please show us a minimal sketch that demonstrates the problem you want to solve.

Robin2

And try changing the intervals to different lengths.
And help me fix my actual problem.
Don't forget to add the digitaWrite(ledpin, ledState); At the end of the interval.
Seems to me that people have been trying but you don't want to meet them half way. How about YOU updating your code with meaningful variable names and any missing pieces added and then posting the revised version.

The reason people are suggesting meaningful names is because it will make it very much easier to help you if we can make sense of your program just by reading it.

...R

Killarado

Sorry guys trying to post code. But it's too long.

tmd3

Please don't post long code.  Few will be motivated to even look at it.  Instead, please trim the code to something small that clearly illustrates the problem that you want to solve.  Please be sure that the code you post will compile, and please test it yourself to verify that it does what you describe.

If you post a small, complete, compilable sketch that demonstrates the behavior that you want to resolve, a surprising number of readers will examine it and start to work on your behalf.

No one objects to posting a small subset of your total code, as long as it compiles, runs, and illustrates your problem.  You will, however, find objections to code that won't compile, is hard to read or understand, or doesn't do what you say it does.

Robin2

I agree completely and entirely with @tmd3.

However if you MUST post a long program you can add it as an attachment.

...R

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy