Millis not accurate

I try to have a pulse 500ms wide every minute:

pin 13 : the pulse
pin 2 : to have a pulse every second

int relais = 13;
int avrapide = 2; 
unsigned long tempsactuel;
unsigned long ecoule;

void setup(){
  pinMode(relais, OUTPUT);
  pinMode(avrapide, INPUT_PULLUP);
  tempsactuel=0;
  ecoule = 0;


    }

void loop() {
    
   
 if (digitalRead(avrapide) ==LOW ){
   impulsion();
 }

if (millis()<tempsactuel){
    ecoule=4294967295-tempsactuel+millis();
     }

     else {
        ecoule = millis() - tempsactuel;
     }

if (ecoule >= 60000){

       tempsactuel= millis();
              impulsion();
          }

}
  
  void impulsion(){
      digitalWrite(relais, HIGH);  
  delay(500); 
  digitalWrite(relais, LOW); 
  delay(500); 
  }

After less than one hour, I have a gap of 2 seconds between the arduino pulse an accurate clock!

Is it a problem with my code or the Arduino clock isn’t accurate?

claudegu:

...

void impulsion(){
      digitalWrite(relais, HIGH); 
  delay(500);
  digitalWrite(relais, LOW);
  delay(500);
  }




After less than one hour, I have a gap of 2 seconds between the arduino pulse an accurate clock!

Is it a problem with my code or the Arduino clock isn't accurate?

Do you seriously think that the digitalWrite instructions take zero time to execute? And the looping?

No of course, I was thinking the time for the code was very short, about some micros seconds, so I’m sure to not be really accurate, but I’m a bit disapointed by the gap wich is really big. It seems the time for the loop and so on is about milliseconds…
Is there a way to know the time for each instrcution, so I will be able to modifiy the count.

Assuming your processor clock is not entirely accurate, but stable, I would do it empirically. That is, work out how much it is out in an hour, and subtract that from your delay. There is a delayMicroseconds which gives you finer control.

Thank's,
I just have removed 50ms from the delay and now it seems a bit better, I will try some hours and adjust.

I just have removed 50ms from the delay

Why are you using "delay" at all?

So I haven't to debounce the input for the button. :blush:
Anyway even without "Delay" the code will take some time so...

A half-second debounce? Interesting.

As AWOL says, if you check the time with millis() you don’t need to worry too much about how long the instructions inbetween take.

OK, I will do this, but I will have to debounce the button XD

If it is bouncing for 500 milliseconds, it’s not a button you’ve got, it’s a trampoline.

claudegu:
OK, I will do this, but I will have to debounce the button XD

That sounds complicated. Perhaps check if, like, 10 mS have elapsed before you take another button press.

I like very much your great sense of humor AWOL and Nick XD

I know how to debounce the button (yes, I know, I swear), but 500ms wasn’t idiot (from my point of view), the aim of this button is to give one 500ms pulse with at least 500ms off after this pulse, if you stay push, with my wonderful code, it just send pulses 500ms ON, 500ms0FF, with no other code and if you want to push this button more often, it does nothing.

You know I’m 53 so, I’m a bit lazy and I don’t remember well my programming lessons…with 8085 or 6800 processors… :blush:
But I know I have learned this before.

You know I'm 53 so, I'm a bit lazy

{shakes head sadly} Young people today...tut-tut.

http://www.ladyada.net/library/arduino/unofaq.html

So the Arduino is not as precise, timing-wise?

The short answer is: yes. The long answer is that most things that people are doing with Arduino do not rely on 20ppm precision timing where 100ppm would fail. For people who want long term precise timekeeping we suggest going with a TCXO (temperature compensation crystal oscillator) - but you would know if you needed that.

100ppm would give .36 second per hour error.

Perhaps more separation between the code that blinks the led and the button code would help?

additional: when checking time, all in unsigned longs;

if ( end_millis - start_millis >= interval_millis ) {
// time is up, do the thing
}

most often it's true "Millis not accurate"
Just tweak the 60000 interval.
I'm using a 10 second interval with 9996 rather than 10000
Each increment to the 9996 changes the clock 8.6 seconds/day.
Just my luck it hit an error of 4.2 seconds/day
But this could be tweaked more with a loop that each hour adds a few leap milli-ticks.
With 59993 or something you can get to 0.7 seconds/day (half the 1.4 seconds/day each step)
The limit should be the crystal's stability not the sketch

Or when you set an interval, scale it. Then the clock just runs until it's (pre-corrected) time to do something.

Ridgeland:
most often it's true "Millis not accurate"

I believe that millis() function has no fundamental flaws. Its accuracy would be based on the accuracy of the system clock, which I believe on the Uno is a resonator, not a crystal, and would be affected by temperature changes.

Also if you were to suspend interrupts for too long (so that a timer overflow was missed) it would return an incorrect value.

You may be able to compensate by building in an adjustment factor by measurement, or get a more accurate real time clock.

The use of delay() itself is likely to lead to errors, for one thing delay() has a resolution of a millisecond, so you potentially will lose (or gain) an average of 500 microseconds each time you call it.

With the correct design, that cause of error can be avoided.

    ecoule=4294967295-tempsactuel+millis();

Isyourspacekeyborken?

Do you honestly believe that 4294967295 is going to fit in an int?

claudegu:
After less than one hour, I have a gap of 2 seconds between the arduino pulse an accurate clock!

Is it a problem with my code or the Arduino clock isn't accurate?

Both:

  • Your code should be changed to use millis() or micros() to determine the time interval so that the time taken to execute the code does't affect the timing.

  • You didn't say which Arduino you are using. For the Uno, the ceramic resonator has a frequency tolerance of +/- 0.5%. That's +/- 18 seconds per hour.