I have a problem with a sketch that runs too fast (using millis()) for a staggering 17 seconds per minute!
Of course I suspected my inefficient way of coding to be the cause, but when I run a simple millis() code (blink without delay) that turns the onboard LED on/off, the timing problem is still there.
The code was adjusted to use 60000 instead of 1000 as an interval.
I have read (older) posts about Ceramic resonator vs. Quartz crystal for the arduino and I was wondering how I can tell what is on my board and if it is a ceramic, could it cause this problem?
You could look for the loading capacitors. They are required for a crystal but not a resonator.
Resonators have three leads while the crystals used in the Arduino world will have two. With surface mount parts you might be able to see this from the traces on the board.
If the manufacturer of your board has published the schematic or design file for your board it should be quite easy to find out.
Be aware that there will usually be two clock devices on the Arduino board. One for the USB chip and one for the primary microcontroller. The exception is Arduino boards where the primary microcontroller has native USB (e.g. Leonardo, Pro Micro), in which case there is not separate USB chip. For your purposes, the microcontroller's clock source is the one of interest.
The clock frequency depends on several factors, mostly temperature. There exist TCXO devices for a very stable frequency, or a RTC.
If your clock has a constant deviation, you can adjust the delay accordingly. It also is possible to hack the library for using a corrected divider from micros to millis, but this has to be done for every single board.
Thanks, I think I'll go with a RTC then. Adjusting this per board would not be very practical. I actually never thought gave this any thought. I assumed that the frequency would be something that would be spot on.
I am using the blink without delay from the examples that come with the ide. All I changed was the 1000 to 60000.
I time using the clock on my mac. I also tried it with the clock on my phone... same thing.
I have another board, from ebay so not an original, I will try that when I get home and see if that made a difference. I’d ‘understand’ if it was running slow because of my lack of skills, but running fast was a surprise.
Using the other board and same blink-without-delay I get 2 seconds too fast.
Could it be because I power it using the computers USB instead of a PU?
/* Blink without Delay
*/
// constants won't change. Used here to set a pin number :
const int ledPin = 13; // the number of the LED pin
// Variables will change :
int ledState = LOW; // ledState used to set the LED
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change :
const long interval = 60000; // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
void loop() {
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
By default, an integer constant is treated as an int with the attendant limitations in values. To specify an integer constant with another data type, follow it with:
a 'u' or 'U' to force the constant into an unsigned data format. Example: 33u
a 'l' or 'L' to force the constant into a long data format. Example: 100000L
a 'ul' or 'UL' to force the constant into an unsigned long constant. Example: 32767ul
Perhaps the error is that you are assigning an int value in const long interval = 60000;
Try using 60000L
For total happiness make the variable "interval" and the constant value unsigned long so that all values in the comparison are the same datatype
The suggested changes worked perfectly!
Using the sketch below fixed it on the blink without delay.
Going to try it now on the other board and sketch.
Thanks!!
/* Blink without Delay
*/
// constants won't change. Used here to set a pin number :
const int ledPin = 13; // the number of the LED pin
// Variables will change :
int ledState = LOW; // ledState used to set the LED
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change :
unsigned long interval = 60000L; // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
void loop() {
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}