Time functions

Ramigrafx:
Thanks to those trying to help

So ? Did you try my working sketch ?

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.

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?

Ramigrafx:
You all know a lot about programming.

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

dxw00d:

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?

Krodal:

Ramigrafx:
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.

PaulS:

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.

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.

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.

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.......

Hi Krodel.
Been playing around with my sketch. I ran 'verify' on it (whatever that does) and everything was ok , but in practice it stopped after digitalWrite (9,HIGH). Obviously something is wrong, but to me the flow of it seems ok. What are your comments please?

unsigned long startTime = millis();  // current value of millis is assigned


// here I want to enter the variables of a,b,c,etc so that they will be entered automatically later

const unsigned long a = 30;           // camera trigger duration
const unsigned long b = 55;           //  1st valve open duration
const unsigned long c = 100;          // time from beginning to 2nd valve opening
const unsigned long d = 55;           //  2nd valve open duration
const unsigned long e = 110;          // time from beginning to 3rd valve opening
const unsigned long f = 55;           //  3rd valve open duration
const unsigned long g = 200;          // time from beginning to 4th valve opening
const unsigned long h = 55;           //  4th valve open duration

const unsigned long x = 10000;        // 10 sec recycling period

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


  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);  
  pinMode(7, OUTPUT); 
  pinMode(8, OUTPUT); 
  pinMode(9, OUTPUT); 

}


void loop() {
  // triggering camera (immediately)
  if (startTime < millis())         
  {
    digitalWrite (9,HIGH);
  }
  if (startTime + a  < millis())  // if  current millis is  greater than startTime  + a then proceed 
  {
    digitalWrite (9,LOW);
  }

  //triggering first valve (immediately)
  if (startTime < millis())
  {
    digitalWrite (6,HIGH);
  }
  if (startTime + b <millis())
  {
    digitalWrite (6,LOW);
  }

  //triggering second valve 
  if (startTime +c < millis())
  {
    digitalWrite (6,HIGH);
  }
  if (startTime + d <millis())
  {
    digitalWrite (6,LOW);
  }

  //triggering third valve     
  if (startTime + e < millis())
  {
    digitalWrite (6,HIGH);
  }
  if (startTime + f <millis())
  {
    digitalWrite (6,LOW);
  }

  //triggering fourth valve 
  if (startTime + g < millis())
  {
    digitalWrite (6,HIGH);
  }
  if (startTime + h <millis())
  {
    digitalWrite (6,LOW);
  }  

  // I now want to wait for x seconds and start all over again.
 // so I need to check that various things have all happend 
  // Can this be done by checking that all pins 5 to 9 are low 
  // and then adding x to the startTime value
  if ( 5, LOW && 6,LOW && 7,LOW && 8,LOW && 9,LOW)
  {
    startTime += x;

  }
}

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

You can do that by hitting the # button above the posting area.

 if ( 5, LOW && 6,LOW && 7,LOW && 8,LOW && 9,LOW)

No.
Just, no.

const unsigned long a = 30;           // camera trigger duration
const unsigned long b = 55;           //  1st valve open duration
const unsigned long c = 100;          // time from beginning to 2nd valve opening

Here's an idea! Meaningful data names:

const unsigned long cameraTriggerDuration = 30;       
const unsigned long firstValveOpenDuration = 55;
const unsigned long timeTillSecondValveOpening = 100;

And so on. Then the whole sketch becomes self-documenting, largely.

This is indeed wrong code:

if ( 5, LOW && 6,LOW && 7,LOW && 8,LOW && 9,LOW)

This is how to read the digital pins:

if (digitalRead(5) == LOW && digitalRead(6) == LOW && digitalRead(7) == LOW && digitalRead(8) == LOW && digitalRead(9) == LOW)

You are making it harder for yourself, if you don't use the serial monitor. I can't do without it.
In setup(), you initialize with the baudrate: Serial.begin(9600);
In loop(), you can print messages and variables to the serial monitor: Serial.println("hello");
The Serial.println() function will delay your code, so use it only during testing.

You need variables for the valves, to make it more readable. Like so:

const int pinTrigger = 9;
const int pinValve1 = 6;
...
digitalWrite (pinTrigger, HIGH);

You have copied the code, so you use pin '6' for all valves.

I have tested your code in my Arduino Uno, and placed Serial.println() messages to show what it does. I'm sorry to say, but your code is not working.
At start, all pins are low, and millis() has not increased yet, so the "startTime += x;" is executed every time.
After x is added to startTime, no code is executed since no 'if' condition is true, so startTime is again increased.

That is why I needed to keep track of the state for every valve.
A simple solution is to check also for the same value of millis():

if (startTime <= millis())

Can you add a variable for the time to open the first valve.
I would even add a variable for the trigger.
That would make your code more readable.

const unsigned long start_trigger = 0;      // time from beginning to trigger
const unsigned long start_1 = 2;      // time from beginning to 1nd valve opening

I am fond of meaningfull names. If you change the a,b,c...h variables into start_1, duration_1 and so on, you will make it easier for yourself if you have to change something later.

Rami, those are quote tags like the word balloon button makes. Just to the left of the word balloon button is the # button that generates code tags. Or you can modify your post and replaces the two words quote with the word code.

 if ( 5, LOW && 6,LOW && 7,LOW && 8,LOW && 9,LOW)

Big mystery to me is how people come up with syntax like that, and they do!

You quoted your previous post.

Can you follow my advice in my previous post. If you follow that, and upload it, it is easier for everyone to comment.

Hi Krodel. Sorry about that. I have inplemented some of the suggestions so far.. viz meaningful titles. Got this far

unsigned long startTime = millis();  // current value of millis is assigned


// here I want to enter the variables  so that they will be entered automatically later 

const unsigned long time_to_trigger_camera = 0;             // time to trigger camera from beginning
const unsigned long camera_trigger_duration = 30;           // camera trigger duration
const unsigned long time_to_open_first_valve = 0;           // time from beginning to 1st valve opening
const unsigned long first_valve_open_duration = 55;         //  1st valve open duration
const unsigned long time_to_open_second_valve = 100;        // time from beginning to 2nd valve opening
const unsigned long second_valve_open_duration = 55;        //  2nd valven open duration
const unsigned long time_to_open_third_valve = 110;         // time from beginning to 3rd valve opening
const unsigned long third_valve_open_duration = 55;         //  3rd valve open duration
const unsigned long time_to_open_fourth_valve = 200;        // time from beginning to 4th valve opening
const unsigned long fourth_valve_open_duration = 55;        //  4th valve open duration

const unsigned long recycling_period = 10000;        // 10 sec recycling period

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


  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);  
  pinMode(7, OUTPUT); 
  pinMode(8, OUTPUT); 
  pinMode(9, OUTPUT); 
  Serial.begin(9600);

}


void loop() {
  // triggering camera (immediately)
  if (startTime + time_to_trigger_camera< millis())         
  {
    digitalWrite (9,HIGH);
  }
  if (startTime +  camera_trigger_duration < millis())  // if  current millis is  greater than startTime  + a then proceed 
  {
    digitalWrite (9,LOW);
  }

  //triggering first valve (immediately)
  if (startTime + time_to_open_first_valve< millis())
  {
    digitalWrite (6,HIGH);
  }
  if (startTime + first_valve_open_duration <millis())
  {
    digitalWrite (6,LOW);
  }

  //triggering second valve 
  if (startTime + time_to_open_second_valve < millis())
  {
    digitalWrite (6,HIGH);
  }
  if (startTime + second_valve_open_duration <millis())
  {
    digitalWrite (6,LOW);
  }

  //triggering third valve     
  if (startTime + time_to_open_third_valve < millis())
  {
    digitalWrite (6,HIGH);
  }
  if (startTime + third_valve_open_duration <millis())
  {
    digitalWrite (6,LOW);
  }

  //triggering fourth valve 
  if (startTime + time_to_open_fourth_valve < millis())
  {
    digitalWrite (6,HIGH);
  }
  if (startTime + fourth_valve_open_duration <millis())
  {
    digitalWrite (6,LOW);
  }  

  // I now want to wait for recycling_period seconds and start all over again.
 // so I need to check that various things have all happend 
  // Can this be done by checking that all pins 5 to 9 are low 
  // and then adding recycling_period to the startTime value
  if (digitalRead(5) == LOW && digitalRead(6) == LOW && digitalRead(7) == LOW && digitalRead(8) == LOW && digitalRead(9) == LOW);
  {
    startTime += recycling_period;

  }
}

I have inplemented some of the suggestions so far.. viz meaningful titles.

Sure you did.

  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);  
  pinMode(7, OUTPUT); 
  pinMode(8, OUTPUT); 
  pinMode(9, OUTPUT);

Now, we know exactly what was designated as an output.

  if (startTime + time_to_trigger_camera< millis())

Subtraction involving unsigned longs is guaranteed to work. Addition is not. If now minus then is greater than in interval is what you want here.

Once you do something, you want to update the relevant "i did this then" variable. I don't see you doing that anywhere.

Got this far

Which describes point A, but says nothing about where point B is, or what issues remain in getting from point A to point B.

if (startTime + time_to_open_first_valve< millis())
  {
    digitalWrite (6,HIGH);
  }
  if (startTime + first_valve_open_duration <millis())
  {
    digitalWrite (6,LOW);
  }

  //triggering second valve 
  if (startTime + time_to_open_second_valve < millis())
  {
    digitalWrite (6,HIGH);
  }
  if (startTime + second_valve_open_duration <millis())
  {
    digitalWrite (6,LOW);
  }

Better get started on "6" now.

Hi,
I have spent all evening reading and testing. I know my hardware works ok because it works ok with my delay sketch. I learnt how to use the serial monitor and used it to check the values when the program was running .The values for the unsigned long variables that are increased by the recycling period are increasing at the correct rate. The camera is releasing at the correct time, but the valves are not opening. Why ? Have I missed something? Guess it's time for bed!

/* sequence of events
   camera triggered, and valves triggerd at a time according  to' time to open valve'
   for a period of time 'duration'
   at the end of the sequence there is a predetermined pause and all starts again.*/

unsigned long startTime = millis();  // current value of millis is assigned

unsigned long time_to_trigger_camera = 0;             // time to trigger camera from beginning
unsigned long camera_trigger_duration = 30;           // camera trigger duration
unsigned long time_to_open_first_valve = 0;           // time from beginning to 1st valve opening
unsigned long first_valve_open_duration = 55;         //  1st valve open duration
unsigned long time_to_open_second_valve = 100;        // time from beginning to 2nd valve opening
unsigned long second_valve_open_duration = 55;        //  2nd valve open duration
unsigned long time_to_open_third_valve = 110;         // time from beginning to 3rd valve opening
unsigned long third_valve_open_duration = 55;         //  3rd valve open duration
unsigned long time_to_open_fourth_valve = 200;        // time from beginning to 4th valve opening
unsigned long fourth_valve_open_duration = 55;        //  4th valve open duration

unsigned long recycling_period = 10000;        // 10 sec recycling period

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


  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);  
  pinMode(7, OUTPUT); 
  pinMode(8, OUTPUT); 
  pinMode(9, OUTPUT); 
  Serial.begin(9600);  // setup serial

}


void loop() {
  
  
  
  
  // triggering camera (immediately)
  if ( (millis()-startTime) >= time_to_trigger_camera )        
  {
    digitalWrite (9,HIGH);
    time_to_trigger_camera += recycling_period;
  }
  if ( (millis()-startTime) >=  camera_trigger_duration )  
  {
    digitalWrite (9,LOW);
    
  }

 // triggering first valve (immediately)
  if ( (millis() - startTime) >= time_to_open_first_valve)
  {
    digitalWrite (6,HIGH);
    //time_to_open_first_valve += recycling_period;
  }
  if ( (millis() - startTime) >= first_valve_open_duration )
  {
    digitalWrite (6,LOW);
  }

  //triggering second valve 
  if ( (millis() - startTime) >= time_to_open_second_valve)
  {
    digitalWrite (7,HIGH);
    time_to_open_second_valve += recycling_period;
  }
  if ( (millis() - startTime) >= second_valve_open_duration)
  {
    digitalWrite (7,LOW);
  }

 //triggering third valve     
  if ( (millis() - startTime) >= time_to_open_third_valve)
  {
    digitalWrite (8,HIGH);
    time_to_open_third_valve += recycling_period;
  }
  if ( (millis() - startTime) >= third_valve_open_duration)
  {
    digitalWrite (8,LOW);
  }

  //triggering fourth valve 
  if ( (millis() - startTime) >= time_to_open_fourth_valve )
  {
    digitalWrite (5,HIGH);
    time_to_open_fourth_valve += recycling_period;
  }
  if ( (millis() - startTime) >= fourth_valve_open_duration)
  {
    digitalWrite (5,LOW);   
  }  
}

You have improved it, but there are still some things to do.
I have tested the sketch, and the first valve is opening and closing (just once).
You could make the delays a few seconds. Perhaps the valve doesn't react to 55ms.

You increase the time for the next period, that's okay, but you should do that also for the other times.

The duration is not the moment in time, but the time after the valve is opened.
So you have to make a choice: define the duration as the duration or define it as the moment in milliseconds.
Suppose you define it as the duration, then this :

// triggering first valve (immediately)
if ( (millis() - startTime) >= time_to_open_first_valve)
{
  digitalWrite (6,HIGH);
  time_to_open_first_valve += recycling_period;
}
if ( (millis() - startTime) >= first_valve_open_duration )
{
  digitalWrite (6,LOW);
}

should be this:

if ( (millis() - startTime) >= time_to_open_first_valve)
{
  digitalWrite (6,HIGH);
}
if ( (millis() - startTime) >= (time_to_open_first_valve + first_valve_open_duration) )
{
  digitalWrite (6,LOW);
  // Now that the first valve has been opened and closed,
  // the new time can be set for the next period.
  time_to_open_first_valve += recycling_period;
}

Do you know that the digitalWrite() is called many times ?
To set an output, calling digitalWrite() just once is nicer.
In your code the conditions are valid for some time, and digitWrite() is called during every loop.

I also would call millis() just once per loop.
In the loop function you could do this: unsigned long time_millis = millis() - starttime;
And use the variable time_millis in the code.