Delay() function assumes 16MHz for 1Mhz ATtiny

Hello, I've written a code for ATtiny24A which includes "delay()" function. I noticed my buzzer which is connected to ATtiny was beeping longer than expected. I've set the buzzer pin high and delayed the turn off by: delay(1000);
The buzzer beeped 16 seconds precisely. I realized the compiler assumes default 16Mhz clock of Arduino. But my settings are correct:

Settings:
image

Also I use Arduino as ISP, I've uploaded the ArduinoISP sketch to Arduino beforehand by enabling the "old style wiring" definition.

I've seen things about fuses but couldn't manage to fix it, I'll be glad if you help. Thanks.

You need to do "burn bootloader" first after you select 1MHz clock and after that upload your sketch.

I've already done it. Still didn't help.

Does this cause a delay of 1 second?

void delay2(uint16_t ms)
{
  //Max allowed delay 65535 ms, change to uint32_t for longer
  uint16_t now = millis();
  while (millis() - now < ms) ;
}

void loop()
{
  delay2(1000);
}

Also, when you compile your sketch, look at the command line for "-dF_CPU=XXX" and check whether XXX is 1M or 16M.

1 Like


It is 1M

Also, millis() doesn't work because I configured Timer 0 differently. I fixed the delay issue by dividing the delay values by 16 but still would love to know a better solution. The code you gave checks if millis() works properly. I created another sketch without Timer configuration and yes, it created a 1 second delay. Even the regular "delay()" function works.

I then have done the same configurations in timer0 and timer1, timer1 doesn't ruin anything but I shouldn't touch timer0 otherwise millis and delay are ruined. problem solved. I already knew delay was counted in timer0 but it didn't make sense that timer was off by 1/16 exactly. Anyway problem solved, I will rewrite my code without touching timer0.

Delay depends on micros() which again depends on Timer0. If you configure Timer0 differently you break the timing API (delay, millis, micros). The only thing that should still work is delayMicroseconds().

1 Like

Obvious question, did you burn bootloader to set fuses for correct CPU speed?

I’m not sure the 24 will run at 16Mhz on the internal clock and needs an external Crystal for that - check the data sheet

Nick Gammon's AVR Fuse Calculator

Yes, delay() in arduino is dependent on timer0, which assume the clock rate specified at compile time.

If you need timer0 for something else, you could consider using _delay_ms() from avr-libcurl

Is _delay_ms() not "counting instructions" as is done by delayMicroseconds()?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.