I'm using the Max7219 (8 digits, 7bits) led display to try and make a timer. I have downloaded an example code from the following site to set the led digits:
https://www.brainy-bits.com/arduino-countdown-timer-using-the-max7219-display/
However the original code simply loops as fast as possible and decriment the timer so it is not a true time. I tried to add a 10 ms delay to make it decriment 10ms on the right most digit so the 3rd digit to the right would be seconds, however I found this to be inaccurate and taking slightly longer than 1 second .
My question is is it possible to make a timer with 1ms accuracy using led display and if so how do I do it?
/* CountDown Timer version 2 using Max7219
Created by Yvan / https://Brainy-Bits.com
This code is in the public domain...
You can: copy it, use it, modify it, share it or just plain ignore it!
Thx!
*/
#define Max7219DIN 7 // Pin 7 connected to DIN (DataIN)
#define Max7219CLK 6 // Pin 6 connected to CLK
#define Max7219CS 5 // Pin 5 connected to CS
#define Buzzer 8 // Pin 8 connected to Buzzer +positive pin
int BuzzTrigger=0; // Variable to store buzzer trigger value
#include "LedControl.h" // LedControl Library created by Eberhard Fahle at http://playground.arduino.cc/Main/LedControl
LedControl lc=LedControl(Max7219DIN,Max7219CLK,Max7219CS,1); // Last number represent the number of Max7219 Modules connected
long int countnumber=24001000 ; // Countdown timer start value HH:MM:SSSS
// Variables to store individual numbers
int firstnum=0;
int secondnum=0;
int thirdnum=0;
int fournum=0;
int fivenum=0;
int sixnum=0;
int sevennum=0;
int eightnum=0;
void setup() {
lc.shutdown(0,false); // Wake up the display
lc.setIntensity(0,7); // Set Brightness 0-15
lc.clearDisplay(0); // Clear display
pinMode(Buzzer, OUTPUT);
digitalWrite(Buzzer, LOW); //Buzzer Off at startup
}
void loop() {
for (countnumber; countnumber != -1; countnumber--) {
String mystring = String(countnumber); // Transform Counter Int to String for manipulation
// Convert number to a time value
for (int z = 0; z < 6; z++) {
if (mystring.substring(z) == "999999") {
countnumber = (countnumber - 400000);
}
if (mystring.substring(z) == "9999") {
countnumber = (countnumber - 4000);
}
}
// Display number on Display depending on number of digits remaining
if (countnumber > 9999999) {
firstnum = ((countnumber / 10000000) % 10);
secondnum = countnumber / 1000000 % 10;
thirdnum = countnumber / 100000 % 10;
fournum = countnumber / 10000 % 10;
fivenum = countnumber / 1000 % 10;
sixnum = countnumber / 100 % 10;
sevennum = countnumber / 10 % 10;
eightnum = countnumber % 10;
lc.setDigit(0, 7, firstnum, false);
lc.setDigit(0, 6, secondnum, false);
lc.setDigit(0, 5, thirdnum, false);
lc.setDigit(0, 4, fournum, false);
lc.setDigit(0, 3, fivenum, false);
lc.setDigit(0, 2, sixnum, false);
lc.setDigit(0, 1, sevennum, false);
lc.setDigit(0, 0, eightnum, false);
delay(10); //<<<<<<<<<<< I ADDED THIS
} else {
if (countnumber > 999999) {
// firstnum = ((countnumber/10000000)%10);
secondnum = countnumber / 1000000 % 10;
thirdnum = countnumber / 100000 % 10;
fournum = countnumber / 10000 % 10;
fivenum = countnumber / 1000 % 10;
sixnum = countnumber / 100 % 10;
sevennum = countnumber / 10 % 10;
eightnum = countnumber % 10;
lc.setChar(0, 7, '-', false);
lc.setDigit(0, 6, secondnum, false);
lc.setDigit(0, 5, thirdnum, false);
lc.setDigit(0, 4, fournum, false);
lc.setDigit(0, 3, fivenum, false);
lc.setDigit(0, 2, sixnum, false);
lc.setDigit(0, 1, sevennum, false);
lc.setDigit(0, 0, eightnum, false);
delay(10); //<<<<<<<<<<< I ADDED THIS
} else {
if (countnumber > 99999) {
// firstnum = ((countnumber/10000000)%10);
// secondnum = countnumber/1000000%10;
thirdnum = countnumber / 100000 % 10;
fournum = countnumber / 10000 % 10;
fivenum = countnumber / 1000 % 10;
sixnum = countnumber / 100 % 10;
sevennum = countnumber / 10 % 10;
eightnum = countnumber % 10;
lc.setChar(0, 7, '-', false);
lc.setChar(0, 6, '-', false);
lc.setDigit(0, 5, thirdnum, false);
lc.setDigit(0, 4, fournum, false);
lc.setDigit(0, 3, fivenum, false);
lc.setDigit(0, 2, sixnum, false);
lc.setDigit(0, 1, sevennum, false);
lc.setDigit(0, 0, eightnum, false);
delay(10); //<<<<<<<<<<< I ADDED THIS
} else {
if (countnumber > 9999) {
// firstnum = ((countnumber/10000000)%10);
// secondnum = countnumber/1000000%10;
// thirdnum = countnumber/100000%10;
fournum = countnumber / 10000 % 10;
fivenum = countnumber / 1000 % 10;
sixnum = countnumber / 100 % 10;
sevennum = countnumber / 10 % 10;
eightnum = countnumber % 10;
lc.setChar(0, 7, '-', false);
lc.setChar(0, 6, '-', false);
lc.setChar(0, 5, '-', false);
lc.setDigit(0, 4, fournum, false);
lc.setDigit(0, 3, fivenum, false);
lc.setDigit(0, 2, sixnum, false);
lc.setDigit(0, 1, sevennum, false);
lc.setDigit(0, 0, eightnum, false);
delay(10);//<<<<<<<<<<< I ADDED THIS
} else {
if (countnumber > 999) {
// firstnum = ((countnumber/10000000)%10);
// secondnum = countnumber/1000000%10;
// thirdnum = countnumber/100000%10;
// fournum = countnumber/10000%10;
fivenum = countnumber / 1000 % 10;
sixnum = countnumber / 100 % 10;
sevennum = countnumber / 10 % 10;
eightnum = countnumber % 10;
lc.setChar(0, 7, '-', false);
lc.setChar(0, 6, '-', false);
lc.setChar(0, 5, '-', false);
lc.setChar(0, 4, '-', false);
lc.setDigit(0, 3, fivenum, false);
lc.setDigit(0, 2, sixnum, false);
lc.setDigit(0, 1, sevennum, false);
lc.setDigit(0, 0, eightnum, false);
delay(10);//<<<<<<<<<<< I ADDED THIS
} else {
// firstnum = ((countnumber/10000000)%10);
// secondnum = countnumber/1000000%10;
// thirdnum = countnumber/100000%10;
// fournum = countnumber/10000%10;
// fivenum = countnumber/1000%10;
sixnum = countnumber / 100 % 10;
sevennum = countnumber / 10 % 10;
eightnum = countnumber % 10;
a
lc.setChar(0, 7, '-', false);
lc.setChar(0, 6, '-', false);
lc.setChar(0, 5, '-', false);
lc.setChar(0, 4, '-', false);
lc.setChar(0, 3, '-', false);
lc.setDigit(0, 2, sixnum, false);
lc.setDigit(0, 1, sevennum, false);
lc.setDigit(0, 0, eightnum, false);
delay(10);//<<<<<<<<<<< I ADDED THIS
}
}
}
}
}
}
}
new implementation using millis
#define Max7219DIN 7 // Pin 7 connected to DIN (DataIN)
#define Max7219CLK 6 // Pin 6 connected to CLK
#define Max7219CS 5 // Pin 5 connected to CS
#include "LedControl.h" // LedControl Library created by Eberhard Fahle at http://playground.arduino.cc/Main/LedControl
LedControl lc=LedControl(Max7219DIN,Max7219CLK,Max7219CS,1); // Last number represent the number of Max7219 Modules connected
unsigned long countnumber;
// Variables to store individual numbers
int firstnum=0;
int secondnum=0;
int thirdnum=0;
int fournum=0;
int fivenum=0;
int sixnum=0;
int sevennum=0;
int eightnum=0;
void setup() {
lc.shutdown(0,false); // Wake up the display
lc.setIntensity(0,7); // Set Brightness 0-15
lc.clearDisplay(0); // Clear display
Serial.begin(9600);
}
void loop() {
countnumber = millis();
firstnum = countnumber / 10000000 % 10;
secondnum = countnumber / 1000000 % 10;
thirdnum = countnumber / 100000 % 10;
fournum = countnumber / 10000 % 10;
fivenum = countnumber / 1000 % 10;
sixnum = countnumber / 100 % 10;
sevennum = countnumber / 10 % 10;
eightnum = countnumber % 10;
lc.setDigit(0, 7, firstnum, false);
lc.setDigit(0, 6, secondnum, false);
lc.setDigit(0, 5, thirdnum, false);
lc.setDigit(0, 4, fournum, false);
lc.setDigit(0, 3, fivenum, false);
lc.setDigit(0, 2, sixnum, false);
lc.setDigit(0, 1, sevennum, false);
lc.setDigit(0, 0, eightnum, false);
}
1 Answer 1
You generally cannot rely on a processor for correct time keeping without a real time clock somewhere in your circuit. However, the best way of doing things at certain times, is to call millis() which will return the number of milliseconds since the program started. With that number you can determine how long something has taken (eg. 1 second) and then do something in response. You can, for example, print out how long your loop is taking by setting a long integer to millis() at the start of the sketch and then subtracting it from mills() at the end of the loop and printing out the result.
void loop() {
long start_time = millis();
delay(500);
long end_time = mills();
Serial.println(end_time - start_time);
}
-
What do you rekon is the accuracy without real time clock? within 20ms?Lightsout– Lightsout2019年10月31日 07:21:37 +00:00Commented Oct 31, 2019 at 7:21
-
1From this article I understand that millis is incremented each 1.024ms, but if the error approaches 1ms then value is automatically corrected. Therefore in span of 20 ms error could accumulate to be close to half of a millisecond.Filip Franik– Filip Franik2019年10月31日 07:47:12 +00:00Commented Oct 31, 2019 at 7:47
-
1@bakalolo Try
micros()
?ElectronSurf– ElectronSurf2019年10月31日 08:36:40 +00:00Commented Oct 31, 2019 at 8:36
millis()
at the beginning of the loop, and them at the end of the loop, wait till the difference betweenmillis()
and the stored millis value is greater that, or equal to 10.