2

I want to control an AC load such that it powered on for 1 minute, then off for 1 hour, then on again for 1 min, and so on, in a loop.

I just modified the blink sketch to do:

  1. Turn A1 on
  2. Then delay for 60,000 ms
  3. Then turn A1 off
  4. Then delay for 3,600,000 ms (3,600 sec, or 1 hr)

...but it doesn't seem to work.

It looks like the LED connected to A0 turns on but instead of turning off after 1 min, it turns off after 8 min 30 s.

Any suggestions?


I rectified the sketch. Now its takes 1 sec as actual 1 sec 1 choose 1 MHz clock in IDE.

int ledPin =  A3;      // the number of the LED pin
int ledState = HIGH;             // ledState used to set the LED
unsigned long previousMillis = 0;        // will store last time LED was updated
unsigned long OnTime = 60000;           // milliseconds of on-time
unsigned long OffTime = 10000;          // milliseconds of off-time

void setup()
{
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  // check to see if it's time to change the state of the LED
  unsigned long currentMillis = millis();

  if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
  {
    ledState = LOW;  // Turn it off
    previousMillis = currentMillis;  // Remember the time
    digitalWrite(ledPin, ledState);  // Update the actual LED
  }
  else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
  {
    ledState = HIGH;  // turn it on
    previousMillis = currentMillis;   // Remember the time
    digitalWrite(ledPin, ledState);    // Update the actual LED
  }
}

then it turns on for 1 sec and then turn off for 1 sec, then randomly turning on at 30 sec or 1 min 30 sec. I want to make it on for 1 min every hour.

I tried blink sketch modified as follows:

void setup() {
  pinMode(A3, OUTPUT);
}

void loop() {
  digitalWrite(A3, HIGH);
  delay(60000);
  digitalWrite(A3, LOW);
  delay(900000);
}

but it still turns on for 1 min and turns off for 1 min.

I also tried this:

void setup() {
  pinMode(A3, OUTPUT);
}

void loop() {
  digitalWrite(A3, HIGH);
  delay(60000);
  digitalWrite(A3, LOW);
  delay(3.6e+6);
}

No matter what I do on time and off time always remain same.

I just wanted to know one thing: can I set 1 hour off and 1 min on timer using ATtiny13A or not?

Tried 1.2 MHz, 1 MHz, all clocks in the IDE, nothing seems to work.

9
  • What are you running this on?
    – Majenko
    Sep 1 '20 at 17:01
  • 4
    Are you sure, that the Attiny is running at the frequency, that you think it runs? I once had my Attiny85 configured for 1MHz instead of the 8MHz, that I was expecting, so I wondered why my code was running 8 times slower.
    – chrisl
    Sep 1 '20 at 17:03
  • How fast does the LED blink when you run the original and unchanged blink sketch?
    – ocrdu
    Sep 1 '20 at 17:17
  • Its about 8.4 seconds Sep 1 '20 at 17:26
  • Sounds like ChrisL nailed it. Your attiny13a is running at 1 MHz instead of 8.
    – Duncan C
    Sep 1 '20 at 17:50
2

As the unchanged blink sketch blinks with 8.4 seconds, I think my assumption is right. The clock of the Attiny is running 8 times slower, than the code thinks.

When you have installed the Attiny core, there should be a menu entry for the clock frequency. Most likely the standard is 8MHz. But having 8MHz set does not mean, that the Attiny is using 8MHz. To choose between different clock sources and frequencies, you must change the fuses of the microcontroller (which are just some bits of special non-volatile memory in the chip, that set special hardware configuration; more information in this question). This is done, when you burn the bootloader to the chip. That's the easy version. Alternatively you can use the avrdude command directly to set the fuses. That's the advanced way.

Currently the fuses of your Attiny seem to be set to the 1MHz internal clock. But the compiler uses the frequency, that you have chosen in the menu, hence 8MHz internal clock. So the compiler thinks, that the chip runs at 8MHz and thus generates the timing code for this execution speed. But your chip is currently 8 times slower, than the compiler thinks.

TL;DR: Burn the bootloader onto the chip to let the Arduino IDE set the right fuses for your clock frequency.

1
  • I doubt an ATtiny13a is large enough for a bootloader, having only 1K of Flash / program memory. My experience with ATtinyCore (which does not support the tiny13 AFAIK) is that it correctly sets the fuses when choosing the "burn bootloader" option even when, in the board settings, the "ATTiny XX (No Bootloader)" option is chosen.
    – StarCat
    Sep 2 '20 at 12:54
0

The code you wrote should work as expected. If it doesn't, I suspect there is something broken in the Arduino core you are using. However, such a trivial task can very easily be programmed in plain C, at the avr-libc level:

#define F_CPU 1000000  // 1 MHz
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    DDRB |= _BV(PB3);  // PB3 as output
    for (;;) {
        PORTB |= _BV(PB3);   // PB3 high
        _delay_ms(60e3);     // 1 min
        PORTB &= ~_BV(PB3);  // PB3 low
        _delay_ms(3.6e6);    // 1 h
    }
}

I would compile it with:

avr-gcc -mmcu=attiny13a -Os -Wall -Wextra 1h-timer.c -o 1h-timer.elf

See the Port Registers Arduino tutorial for the meaning of the macros used here. You can tweak F_CPU to fine-tune the delays, in case your ATtiny clock is not quite 1 MHz.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.