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