micros() and delay() - novice question

Status
Not open for further replies.

labRat

Member
Hi,

My circuit is a teensy 3.2, two shift registers, and two common anode 7-segment displays.

My sketch works great when I use delay() but when I use micros() I get an erratic count on the two 7-segments. My objective is to use the IntervalTimer so I want to get rid of the delay().

Any advice regarding troubleshooting the erratic count, or why does it cause the problem? Is the nested loop an inefficient algorithm when using micros()?

Code:


//variables in both sketch and ISR
volatile byte SER = 3;
volatile byte latch = 4;
volatile byte clockSR = 5;
volatile int ones;
volatile int tens;

unsigned long previousMillis = 0;
unsigned long myInterval = 1000;
unsigned long interval = 1000;
unsigned long currentMillis;

//IntervalTimer myTimer;

byte sevenSegmentDisplay[10] = {B00000011,//0
B10011111, //1
B00100101, //2
B00001101, //3
B10011001, //4
B01001001, //5
B11000001, //6
B00011111, //7
B00000001, //8
B00011001}; //9


void setup() {

pinMode(SER, OUTPUT);
pinMode(latch, OUTPUT);
pinMode(clockSR, OUTPUT);

// myTimer.begin(resetCount, 8000000);

}

void loop()
{

for(tens = 0; tens < 10; tens++)
{
for(ones = 0; ones < 10; ones++)
{
currentMillis = millis();

if (currentMillis - previousMillis >= interval) {

previousMillis = currentMillis;

digitalWrite(latch, LOW);
shiftOut(SER, clockSR, LSBFIRST, sevenSegmentDisplay[ones]);
shiftOut(SER, clockSR, LSBFIRST, sevenSegmentDisplay[tens]);
digitalWrite(latch, HIGH);
//get rid of delay() because Interrupts work on the same timer as interrupts
// delay(1000);
}//end if
}//end 'ones' inner loop
}//end 'tens' outer loop
}//end main loop

//ISR
void resetCount(){

noInterrupts();

digitalWrite(latch, LOW);
shiftOut(SER, clockSR, LSBFIRST, B00000011);
shiftOut(SER, clockSR, LSBFIRST, B00000011);
digitalWrite(latch, HIGH);

ones = 0;
tens = 0;

interrupts();
//sei();

}
 
Yes, of course. Your 'ones inner loop' just evaluates if currentMillis - previousMillis >= interval, and if not increments the loop counter 'ones'. What you did is not a replacement of delay(). You wrote something that will execute the shiftOut code every time currentMillis - previousMillis >= interval, but the values of ones and tens can be any value at that time because they keep incrementing every time the loop executes.

Try this for your main loop:
Code:
void loop()
{

  if(millis() - previousMillis >= interval){
    digitalWrite(latch, LOW);
    shiftOut(SER, clockSR, LSBFIRST, sevenSegmentDisplay[ones]);
    shiftOut(SER, clockSR, LSBFIRST, sevenSegmentDisplay[tens]);
    digitalWrite(latch, HIGH);
    ones++;
    if(ones < 10){
      tens++;
      ones = 0;
    }
    if(tens < 10){
      tens = 0;
    }
    previousMillis = millis();
  }
}//end main loop

This code will run every time millis() - previousMillis >= interval, and update your shift register. If ones are bigger then 10, it will increment tens and reset ones. If tens are bigger than 10, it will also reset tens.
 
Status
Not open for further replies.
Back
Top