Timer relay control with Attiny85

Dear all!

I am new here and new to programming
I recently learn that microcontrollers like attiny85 can control relays with timer function...

I wish to have a controller of relay to power on a led at the following intervals:

  1. When powered on, the relay stays on for 15 seconds
  2. Afterwards it turns off the relay for 90mins (5400 seconds)
  3. Afterwards the relay is turned on for 10seconds
  4. revert to step 2) and loop continuously

I think it is not a complicated programme...
But i have been searching for a few days, reading tutorials and examples... Im still up on a blank wall

Could anyone help or give me directions for this?

Thank you so much

Please do not cross-post. Other thread removed.

Do some readings about state machines and have a look at the state diagram i attached.

relay timer.png

#include <avr/io.h>
#include <avr/interrupt.h>
 
uint8_t counter15;
#define WAIT15  15    // 15 seconds
#define CLOCK_FREQ 128000   // clock frequency
#define PRESCALER 16384    // timer1 prescaler
#define MAXCOUNT15 (uint8_t)WAIT15 / (255 / (CLOCK_FREQ / PRESCALER))
 
uint8_t counter10;
#define WAIT10  10    // 10 seconds
#define CLOCK_FREQ 128000   // clock frequency
#define PRESCALER 16384    // timer1 prescaler
#define MAXCOUNT10 (uint8_t)WAIT10 / (255 / (CLOCK_FREQ / PRESCALER))
 
uint8_t counter5400;
#define WAIT5400  5400    // 5400 seconds
#define CLOCK_FREQ 128000   // clock frequency
#define PRESCALER 16384    // timer1 prescaler
#define MAXCOUNT5400 (uint8_t)WAIT5400 / (255 / (CLOCK_FREQ / PRESCALER))
 
void initializeTimer15()
{
 counter = MAXCOUNT15;
 TCCR1 |= (1 << CS10) | (1 << CS11) | (1 << CS12) | (1 << CS13);  // set prescaler to clk/16384
 TIMSK |= (1 << TOIE1);   // enable timer1 overflow interrupt
}
 
void initializeTimer10()
{
 counter = MAXCOUNT10;
 TCCR1 |= (1 << CS10) | (1 << CS11) | (1 << CS12) | (1 << CS13);  // set prescaler to clk/16384
 TIMSK |= (1 << TOIE1);   // enable timer1 overflow interrupt
}
 
void initializeTimer5400()
{
 counter = MAXCOUNT5400;
 TCCR1 |= (1 << CS10) | (1 << CS11) | (1 << CS12) | (1 << CS13);  // set prescaler to clk/16384
 TIMSK |= (1 << TOIE1);   // enable timer1 overflow interrupt
}
 
int main(void)
{
 DDRB |= (1 << PB0);    // make pin PB0 output
 
 initializeTimer15();    // initialize the timer 15s
 counter--;      // decrement counter
 
 if (counter == 0)    // if counter is zero
 
void loop()
 {
 DDRB &= ~(1 << PB0);    // make pin PB0 input (hi-Z) 
 initializeTimer5400();   // initialize the timer 90mins
 counter--;      // decrement counter
 
 if (counter == 0)    // if counter is zero
 DDRB |= (1 << PB0);    // make pin PB0 output
 initializeTimer10();    // initialize the timer 10s
 counter--;      // decrement counter
 
 if (counter == 0)    // if counter is zero
DDRB |= (1 << PB0);     // make pin PB0 output
 
    }
}

Firstly apologise for the cross post... Im desperate for help...

But thank you for the response :slight_smile:

I have made up a script for the programme
Please advise if it will work...
How to correct it if there is problem?

Thanks!

#define CLOCK_FREQ 128000   // clock frequency

Is the ATtiny85 processor actually running at 128 kHz?

Hello and welcome :slight_smile:

Where did you find that code? It doesn't look like standard Arduino sketch.

Your sketch is not too hard to do:

const uint8_t relayPin = 10; // change to whatever pin you connected the relay to

const bool relayOn = HIGH; // you may need to invert these two values, depending if
const bool relayOff = LOW; // your relay is Active Low or Active High

void setup()
{
    pinMode( relayPin, OUTPUT );

    // step 1: turn on relay for 15 seconds
    digitalWrite( relayPin, relayOn );
    delay( 15000 );
}

void loop()
{
    // step 2: turn off relay for 90 minutes
    digitalWrite( relayPin, relayOff );
    delay( 5400000 );

    // step 3: turn on relay for 10 seconds
    digitalWrite( relayPin, relayOn );
    delay( 10000 );
}

That's it, basically. But, it's ugly, and can be made much better using the technique shown in the Blink Without Delay example and combine with nilton61's suggestion of a state machine :slight_smile:

Hello

Thank you for the input!

My script is based from a script found here:
http://www.wengenroth.co/projects/auto-shutoff-circuit/

For your suggestion on a simpler script, i really need the first "15 seconds" to be outside of the loop.. As i may have to adjust the initial "on-time" depending on situations

I thought of using DELAY... But from what i read... Delay function is unreliable and not accurary ( although i dont need really accurary time.. Deviation from 2-3a is ok)
But would the 90mins (long) interval delays be an issue? Especially in a looping

If you use my State machine library you can write your code with a perfect 1:1 relation between states and state function. Also non blocking timing is built in so the need for delay is eliminated.

#include <SM.h>

const int relayPin = 8;

const unsigned long InitDelay = 15*1000;
const unsigned long OffDelay = 90*60*1000;
const unsigned long OnDelay = 10*1000;

SM relayTimer(Init);

void setup(){
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, 1);//turn relay on at start
}//setup()

void loop(){
  EXEC(relayTimer);
}//loop()

State Init(){
  if(relayTimer.Timeout(InitDelay)){
    digitalWrite(relayPin, 0);
    relayTimer.Set(off);
  }//if(Timeout)
}//Init()

State on(){
  if(relayTimer.Timeout(OnDelay)){
    digitalWrite(relayPin, 0);
    relayTimer.Set(off);
  }//if(Timeout)    
}//on()

State off(){
  if(relayTimer.Timeout(OffDelay)){
    digitalWrite(relayPin, 1);
    relayTimer.Set(on);
  }//if(timeout)
}//off()

Yes it was a mistake, I moved the step 1 in setup, so only step 2 and 3 will loop forever.

delay is pretty accurate, from my tests, but I admit I never tried with a delay of more than one minute. My guess would be something like +/- 1 second per hour, but I can be wrong.

I habitually recommend to NOT use delay, but in simples cases like yours, it's just the easiest solution.

But nilson61's code is interesting none the less :wink:

#include "Timer.h"
 
 
Timer t;
int pin = 5;
 
void setup()
{
pinMode(pin, OUTPUT);
t.pulse(pin, 15 * 1000, HIGH); // 15 seconds 
}
 
 
void loop()
{
t.pulse(pin, 90 * 60 * 1000, LOW); // 90 minutes
t.pulse(pin, 10 * 1000, HIGH); // 10 seconds ;
}

Will it work this way? Seems much simpler

From the timer library: " the pulse method takes arguements of a pin to change, the period to change it for and its initial state."

Thanks

I've never worked with attinys, I have no idea if the Timer library is compatible with them.

But how do you plan to program your ATTiny85? Do you have an Arduino board that you can use as a programmer?

Here is a link that could help you: http://highlowtech.org/?p=1695

Thank you so much! I bought a programmer locally.... Will try the scripts on when the parts arrive