Pages: 1 [2] 3 4   Go Down
Author Topic: Time functions  (Read 3112 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Edison Member
*
Karma: 9
Posts: 1010
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is the millis led blink : http://arduino.cc/en/Tutorial/BlinkWithoutDelay

Here is some code.
But I'm not happy with it. I should have created an command queue after all.
The MultiBlink is better programming: http://arduino.cc/playground/Code/MultiBlink

Valve 1 activates at time '0', and Valve 2 activates at time '140'.
You can make that '140' any value, even '0' or while Valve 1 is still active.

Code:
// Indepent valve control
//
// I would like to use a hardware timer,
// and a queue with times and events.
// But it's only for two valves,
// so I use variables for everything.
// But then I needed some kind of state machine,
// which makes it unnecessary complicated.
//

// Set the times.
// The start time is independent of each other.
const unsigned int valve_1_start    = 0;   // time for valve 1
const unsigned int valve_1_duration = 55;  // size of first drop in ms
const unsigned int valve_2_start    = 140; // time for valve 2
const unsigned int valve_2_duration = 55;  // size of second drop in ms
const unsigned int wait = 6000;      // wait a few seconds before starting all over

#define STATE_WAITING_FOR_ACTIVATING 0
#define STATE_VALVE_ON               1
#define STATE_DONE                   2


void setup()
{
  // initialize the digital pins as an output.

  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  
  Serial.begin(9600);
  
}

void loop()
{
  // Timing for valve 1 and 2 are totally independent.
  // Calculate the times in milliseconds.
  unsigned long currentMillis           = millis();
  unsigned long valve_1_start_millis    = currentMillis + valve_1_start;
  unsigned long valve_1_duration_millis = currentMillis + valve_1_start + valve_1_duration;
  unsigned long valve_2_start_millis    = currentMillis + valve_2_start;
  unsigned long valve_2_duration_millis = currentMillis + valve_2_start + valve_2_duration;
  unsigned long wait_millis             = currentMillis + wait;

  int valve_1_state = STATE_WAITING_FOR_ACTIVATING;
  int valve_2_state = STATE_WAITING_FOR_ACTIVATING;

  int ready = false;

  // run a (very fast) loop in which is checked if something needs to be done.
  while(!ready)
  {
    currentMillis = millis();


    // Check to see if it's time to do something for valve 1.
    switch (valve_1_state)
    {
    case STATE_WAITING_FOR_ACTIVATING:
      if (currentMillis >= valve_1_start_millis)
      {
        digitalWrite(6, HIGH);    // Turns ON Relay 3  on digital pin 6 (blue)
        valve_1_state = STATE_VALVE_ON;  
//        Serial.println(F("Valve 1 On"));
      }
      break;
    case STATE_VALVE_ON:
      if (currentMillis >= valve_1_duration_millis)
      {
        digitalWrite(6, LOW);     // Turns OFF Relay 3 on digital pin 6
        valve_1_state = STATE_DONE;  
//        Serial.println(F("Valve 1 Off"));
      }
      break;
    case STATE_DONE:
    default:
      break;
    }
    

    // Check to see if it's time to do something for valve 2.
    switch (valve_2_state)
    {
    case STATE_WAITING_FOR_ACTIVATING:
      if (currentMillis >= valve_2_start_millis)
      {
        digitalWrite(7, HIGH);    // Turns ON Relay 2 on digital pin 7 (yellow)
        valve_2_state = STATE_VALVE_ON;  
//        Serial.println(F("Valve 2 On"));
      }
      break;
    case STATE_VALVE_ON:
      if (currentMillis >= valve_2_duration_millis)
      {
        digitalWrite(7, LOW);     // Turns OFF Relay 2 on digital pin 7
        valve_2_state = STATE_DONE;  
//        Serial.println(F("Valve 2 Off"));
      }
      break;
    case STATE_DONE:
    default:
      break;
    }


    // Check to see if we need to start all over again.
    if (valve_1_state == STATE_DONE && valve_2_state == STATE_DONE && currentMillis >= wait_millis)
    {
      ready = true;
    }
  }
}
« Last Edit: July 23, 2012, 07:46:01 pm by Krodal » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I only want the event to happen once then stop
...
Code:
// Check to see if we need to start all over again.

Why check to see if we need to start over again, then?
Logged

Offline Offline
Edison Member
*
Karma: 9
Posts: 1010
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I only want the event to happen once then stop
...
Code:
// Check to see if we need to start all over again.

Why check to see if we need to start over again, then?
Oh, well, I thought "once per loop". So I used the loop() function for a complete sequence, and run a second loop inside it to keep track of time. The original code starts again after a few seconds, so that's what did.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

One thing I would like to know. Why is everything dealing with blinking LEDs, when I only want the event to happen once then stop

You want something to happen. Then something else a bit later. Then repeat (or do you?). It's almost like blinking two LEDs at different rates, isn't it? Of course, you don't have to have LEDs on the pins, you could have, say, valves.

http://www.gammon.com.au/blink
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 58
Posts: 4036
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Still studying all of the examples. One thing I would like to know. Why is everything dealing with blinking LEDs, when I only want the event to happen once then stop

Blink Without Delay shows how to use the clock to make things happen (turn led/whatever On or Off) when you want without holding everything else up.

With 1 blinking light you might want to add a variable with a name like stopLed that starts = FALSE and add that into your conditionals ( if statements and like ) so that stopLed must be true to keep on blinking. With more than 1, an array ( stopLed[ leds ] ) would be better.

That's one way to add control, by using variables that your code sets and checks. Throw in user I/O through the Serial Monitor or switches/buttons/sensors if you want. Code is your clay to mold to your own needs. The kinds of complexity or simpleness you can get up to through code are literally up to you and the limits of your hardware (UNO has 2k RAM for example).
Logged

Examples can be found in your IDE.

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes I know the downside of using delay and that is why I want to use millis.
Since you are all very good at using examples to prove your point. Look at this one.
 
At a sports event when a race starts they don't look at the clock and note that is say 10:15:35 and when the race ends they don't subtract the final time from the start time. No they start a stopwatch from 0 at the beginning of the race, and note the time at the end. At the end of the race they all don't start over again. There is a rest period, then they start another race from zero time again.

If I wrote a chapter of a book in English would you expect me to make a perfect gramatically correct translation into Chinese after learning the language for a two days. Of course not.

Anyone can find one to justify their argument

You all know a lot about programming. You need to look at your explanations from the point of view of someone who does not know much , but is trying to learn, and then they would not have to keep asking so many similar questions that obviously annoy some ofyou.

I understanrd the flow path of the events that I want.I am just trying to translate this into a foreign language.

If PaulS looked at my sample sketch at reply#4 that I have been using with delay in it he would understand what I was trying to do.

Thanks to those trying to help
« Last Edit: July 24, 2012, 04:23:12 am by Ramigrafx » Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 19
Posts: 3114
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
At a sports event when a race starts they don't look at the clock and note that is say 10:15:35 and when the race ends they don't subtract the final time from the start time. No they start a stopwatch from 0 at the beginning of the race, and note the time at the end.
That's quite true, because they have a hardware timer that can do that. The Arduino doesn't, and so a different technique is required.
Logged

Offline Offline
Edison Member
*
Karma: 9
Posts: 1010
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks to those trying to help

So ? Did you try my working sketch ?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 551
Posts: 46266
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
If PaulS looked at my sample sketch at reply#4 that I have been using with delay in it he would understand what I was trying to do.
I did look at it. If you'd read #3, you'd know that.

Quote
Thanks to those trying to help
What part have you contributed? What have you come up with? Are you expecting us to write the code for you?
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You all know a lot about programming.

Well? Listen to what we are saying rather than trying to prove we are idiots.
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 58
Posts: 4036
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
At a sports event when a race starts they don't look at the clock and note that is say 10:15:35 and when the race ends they don't subtract the final time from the start time. No they start a stopwatch from 0 at the beginning of the race, and note the time at the end.
That's quite true, because they have a hardware timer that can do that. The Arduino doesn't, and so a different technique is required.

Not true. He could go to the extra trouble to set up a timer and interrupt and have his stopwatch. Hell, it's possible to reset the millis() counter with precautions on how you do it.

We just tried to take him through the -easy- way but what the heck do WE know?
Logged

Examples can be found in your IDE.

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks to those trying to help

So ? Did you try my working sketch ?

Thanks Krodal. I have printed out your sketch and am currently going through it, trying to understand it.
I am writting my sketch at the moment so it is helping me, together with many other pieces of information I have gathered.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
If PaulS looked at my sample sketch at reply#4 that I have been using with delay in it he would understand what I was trying to do.
I did look at it. If you'd read #3, you'd know that.

Quote
Thanks to those trying to help
What part have you contributed? What have you come up with? Are you expecting us to write the code for you?

I am trying to write the code myself, when I understand the procedure. I don't want anyone to do it for me.
If you are going to get so bad tempered I suggest that you chill out for a while and give this job a rest. You put people off.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 551
Posts: 46266
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
If you are going to get so bad tempered I suggest that you chill out for a while and give this job a rest.
Fine. Good luck.
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 58
Posts: 4036
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Look, Rami,

The chip has counter-timer circuits inside. Every cycle they add 1 and you know by your cycle time how many ticks makes a millisecond and that adds 1 to another memory register. That already happens. That's what's behind millis().

You can -make- your own count-down timer. You can put a time value in a volatile global variable and run an interrupt off a timer so when it rolls over the IRQ decrements the time value. Then your regular code has until the next interrupt to recognize when the value hits zero -or- it can know the time passed zero -if- it keeps the last time value stored and not be time-critical. If your time value increments are 1 ms or more then tight code will never miss when it zeroes.

You can make one without interrupt, IRQ and volatile variables just by using code that uses... millis(), and it will be simpler and work cleaner.

It's up to you.......
Logged

Examples can be found in your IDE.

Pages: 1 [2] 3 4   Go Up
Jump to: