0

I'm currently writing a program with Arduino for an ATTINY24 (running on 16Mhz external crystal). Since 32bit arithmetic is expensive compared to 16bit and also take up more program memory I casted the millis() to uint16_t. By this I managed to reduce the sketch size to just fit into the 2k PROGMEM.

But I"m facing a problem I currently cant explain. After exactly 5:30 minutes the LED stops blinking. I guess this is due to the timer overflow. I followed all instruction (at least I think so) from this answer, but I cant seem to get it right and meanwhile I start suspecting the cast to uint16 is doing something wired....

My code thats not working:

uint16_t _ledLastTime = 0;
const uint16_t LED_BLINK_TIME = 400;

uint16_t millis16() {
  return (uint16_t)millis();
}

void loop()
{ 
  uint16_t now = millis16();
  if ((now-_ledLastTime) > LED_BLINK_TIME) {
    if ((PINB & _BV(PIN_LED))==0) {
        PORTB |= _BV(PIN_LED);
    } else {
        PORTB &= ~(_BV(PIN_LED));
    }
    _ledLastTime = now;     
  }
  //do a bunch of other stuff here
}

//-----------------------------------------Edit-------------------------------------------

Previously I was not using the 'now' variable (as suggested in the comments and the code looked like this (with the same result). I added the now to test if this could solve it.

uint16_t _ledLastTime = 0;
const uint16_t LED_BLINK_TIME = 400;

uint16_t millis16() {
  return (uint16_t)millis();
}

void loop()
{ 
  if ((millis16()-_ledLastTime) > LED_BLINK_TIME) {
    if ((PINB & _BV(PIN_LED))==0) {
        PORTB |= _BV(PIN_LED);
    } else {
        PORTB &= ~(_BV(PIN_LED));
    }
    _ledLastTime = millis16();      
  }
  //do a bunch of other stuff here
}
  • I suggest editing your question to show the whole sketch (except perhaps the “bunch of other stuff”). Why would anyone want to look at a bit of code with a bunch of undefined constants and undeclared variables, and no clue as to initialization? – James Waldby - jwpat7 Jul 2 '16 at 18:36
  • Also, if you post a whole sketch, verify it still has the problem. Eg, the “bunch of other stuff” part might be overwriting part of RAM. – James Waldby - jwpat7 Jul 2 '16 at 18:42
  • It is certainly possible that you will get stuck when the lower 16 bits of millis() roll over, but hard to say more without seeing the full program. What type is _ledLastTime? What does the definition of LED_BLINK_TIME look like? – bigjosh Jul 2 '16 at 20:22
  • Please, post a minimal testable program that shows the problem. What you posted won't compile, as _ledLastTime and LED_BLINK_TIME are not defined. Did you define them as 16-bit variables? Note that millis16() is useless, you can just uint16_t now = millis();, which may save you a tiny bit of flash. Also, your problem may well lie in the “bunch of other stuff”. – Edgar Bonet Jul 2 '16 at 21:28
  • 2
    You can simplify toggling the pin by replacing those five lines with: PINB = _BV(PIN_LED); – Nick Gammon Jul 2 '16 at 22:30

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.