Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: micros() and delay() - novice question

  1. #1
    Junior Member
    Join Date
    Sep 2014
    Posts
    9

    micros() and delay() - novice question

    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();

    }

  2. #2
    Senior Member Epyon's Avatar
    Join Date
    Apr 2013
    Location
    Belgium
    Posts
    443
    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.

  3. #3
    Junior Member
    Join Date
    Sep 2014
    Posts
    9
    Thank you so much! It works very nicely now.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •