what effects millis() ?

I sometimes have problems with timing accuracy when using the millis() for timing a clock.

I can run the timer alone and its fine, but in some of my projects I also use VirtualWire which evidently uses clock1, and often I have an interrupt connected to pin 2 .

I know you mustnt use pins 9 or 10 for pwm if you are running the VW library.

Is there a problem with either of these libraries affecting the millis accuracy?

I have searched and found a post where someone had problems with VW and another library, and was recommended to change the setup of the VW clock ? ( I didnt understand it )

If an interrupt service routine takes too long it can slow down the millis timer because it is not updated duriring an ISR.

I think that might be the problem on one of my projects Mike, I will try chamnging it just setting a flag to be picked up in the loop.

Meanwhile I have just done a test with a simple sketch to count secs and minutes . Without the libraries it keeps perfect time compared to my pc clock,

With VW running I lose about 2 seconds in 30 minutes, even if I send nothing to the RX pin.

Is there an easy way of making millis or VW use the other clock?

 #include <SPI.h>
        #include <VirtualWire.h>
        #include <MemoryFree.h>
         unsigned long  currentMillis;
        unsigned long  previousMillis = 0;
   int secU=0;  
 int minU=0;  
        void setup(){ 
          Serial.begin(19200);
           vw_set_rx_pin(19);        // set Rx
          vw_setup(2000);	 // Bits per sec
          vw_rx_start();    
        }          
          void loop (){   
    currentMillis = millis()  ;
     if(currentMillis > previousMillis)   
     {        
       previousMillis = currentMillis  +1000; secU ++ ;    
    
      if (secU >= 60 )  { secU = 0 ; minU ++  ;}    
        Serial.print(" min= "); Serial.println(minU); Serial.print(" sec = "); Serial.println(secU);
      }
      
        uint8_t buf[VW_MAX_MESSAGE_LEN];  //  get message
          uint8_t buflen = VW_MAX_MESSAGE_LEN;
          if (vw_get_message(buf, &buflen)) // Non-blocking
          {
            Serial.println("Got: ");  // Show on PC for debugging
 
       

          }  //  end of if message
     
   
  }
       previousMillis = currentMillis  +1000; secU ++ ;

In spite of the horrid indenting, I read your code. Man, some of your names are terrible. How can now + 1000 milliseconds equal previousMillis?

You might be interested in just how many milliseconds there ARE in a second.

LOL Paul,, if you knew how many changes I have played with here !
I did try micros as well, so that had odd names too.

I had tried targetMillis, previousMillis and all sorts along the way.

I guess I should have tidied it up, but I had been up all night.

John,
Try replacing this:

       void loop (){   
    currentMillis = millis()  ;
     if(currentMillis > previousMillis)   
     {        
       previousMillis = currentMillis  +1000;

with

       void loop (){   
    currentMicros = micros()  ;
    elapsedMicros = currentMicros - previousMicros
     if(elapsedMicros > duration)   
     {        
       previousMicros = previousMicros  + duration;
       hundredths = hundreths +1;
       (if hundredths == 10){ 
           hundredths = 0;
           tenths = tenths +1;
           if (tenths == 10){
               tenths = 0;
               secU = secU +1;
           } 
        }
     }

with
unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedMicros;
unsigned long duration = 1000000UL;
byte tenths;
byte hundredths;

I usually keep track of 0.01S, setting duration to 10000UL and having a
hundreths and tenths counter.

The key is here tho:
previousMicros = previousMicros + duration;

So the next time event is always set the same, and not varying a little by how long the code might take in between loop passes.

The key is here tho:
previousMicros = previousMicros + duration;

The previousMicros variable does not hold the previous event time. It holds the next event time. Why use previous in the name when you mean next?

I waffle myself with what name to use there all the time. In the end I've stuck with current & previous & elapsed just to be consistent & keep the subtraction order the same from sketch to sketch.

Thats where I got the names from !
I have used quite a few of your bits of sketches Bob.

I have swapped things round and added and subtracted, but I will try it again as you have put it and report back.

Thats better, thanks Bob.

Its within a second after 3 hours with all libraries and things running.

Is that with a crystal, or a resonator?

Thats with a crystal, but when I say within a second, I am timing it by hitting "run" on the remote control, to start counting when the PCs clock changes minutes, so it can be a second or so different - thats why I say within a second.

I also remembered why I didnt use this code 2 years ago when I had the same problem, after pausing, and starting again, the countdown rapidly counts down at first.

At the time, it was beyond me, but this time I just stuck in targetMillis = targetMillis + 1000 in the case of the "run" button being pushed.
This also helps the first second always being a second, rather than jumping quickly to 59.