I'm trying to run a 3-digit 7-segment using single 74HC595 based on Arduino. But I have a serious problem with delay()
function. When I want to count from 000 to 999 with delay(1000)
, this delay function causes all digits to be off! My code is as below and I uploaded a video Click Here to understand my purpose. This problem can affect some applications like reading the temperature of DS12b20 which requires a delay itself.
// 2 1 0
// ---- ---- ----
// | | | | | |
// ---- ---- ----
// | | | | | |
// ---- ---- ----
int latch = 8; //74HC595 pin STCP
int clock = 9; //74HC595 pin SHCP
int data = 10; //74HC595 pin DS
// Each annode pin (for those that don't know think of it as an on switch when it's assigned HIGH)
int dig1 = 2; // digit0
int dig2 = 3; // digit1
int dig3 = 4; // digit2
int digit[4]={dig1, dig2, dig3};
int timer=3;
// these are bits to make the 8 bit byte accepted by the segment display the 9th is the demical point
// 0-9 then invald numbers
byte table[] = {
B00111111, B00000110, B01011011, B01001111, B01100110,
B01101101, B01111101, B00000111, B01111111, B01101111, B01111111
};
void setup(){
pinMode(latch, OUTPUT);
pinMode(clock, OUTPUT);
pinMode(data, OUTPUT);
pinMode(dig1, OUTPUT);
pinMode(dig2, OUTPUT);
pinMode(dig3, OUTPUT);
}
//this sends the data to the digit
void RunNum(int num, int SelectDigit){
digitalWrite(latch, LOW);
shiftOut(data, clock, MSBFIRST, table[num]);
digitalWrite(latch, HIGH);
digitalWrite(digit[SelectDigit], LOW);
delay(timer);
digitalWrite(digit[SelectDigit], HIGH);
}
//main program
void loop() {
for (int i=0; i<10; i++){
for (int j=0; j<10; j++){
for (int k=0; k<10; k++){
RunNum(k, 0);
RunNum(j, 1);
RunNum(i, 2);
delay(1000); // <==== This line affects the project
}
}
}
}
I updated my code (only void loop()
) as below using millis()
. You can watch the results (Click Here). But, the delay problem has not been solved so far!
const long interval = 1000; // 1000 ms = 1 s
long previousMillis = 0;
unsigned long currentMillis=0;
//main program
void loop() {
for (int i=0; i<10; i++){
for (int j=0; j<10; j++){
for (int k=0; k<10; k++){
while (currentMillis - previousMillis < interval){
currentMillis=millis();
RunNum(k, 0);
RunNum(j, 1);
RunNum(i, 2);
}
previousMillis = currentMillis;
}
}
}
}
delay()
. To do timed things, you need to learn a non-blocking coding style, like in theBlinkWithoutDelay
example via themillis()
. Look a the example and at tutorials about millis(). When you fully understand them, you will be able to replace the delay with non-blocking code – chrisl Jun 17 '20 at 17:28millis
function. But it's useful for digital counting only like for making a digital clock. It's too bad for other applications like for DS18b20 temperature. – soheil Jun 17 '20 at 17:46millis()
should be too bad to use here.delay()
also just usesmillis()
in the background. And I also don't see how it should affect the temperature measurement. It is absolutely the way to go for handling the 1s delay there. – chrisl Jun 17 '20 at 18:33