I don't have the ATtiny24A yet in my hands. I am pre programming it. I don't want any mistakes because I will probably build the circuit with hard work (drawing, printing, etching, tinning, components placement) and I don't want to waste hard work. The whole code is a complete alarm system, It would over complicate things but sure anyone can see, I am open to suggestions. (Editing the code according to suggestions)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>
volatile uint8_t state = 1; //1: idle 2: to be armed 3: armed/to be rang/ringing
uint16_t armDelay = 30;
uint16_t alarmDelay;
uint16_t alarmDuration;
uint16_t counter;
unsigned long t1;
unsigned long t1_;
volatile bool flagBUT = false;
volatile bool flagPIR = false;
volatile bool flagTIM = false;
#define LEDButtonPin PA3
#define BuzzerPin PA4
#define AlarmPin PA5
#define PotEnablePin PA2
#define PIRPin PB2
#define ButtonPin PA7
#define pot_DEL_pin PA0
#define pot_DUR_pin PA1
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
void setup() {
TCCR1A = (0<<WGM11)|(0<<WGM10);
TCCR1B = ((0<<CS10)|(0<<CS11)|(0<<CS12))|(1<<WGM12)|(0<<WGM13)|(0<<ICNC1)||(0<<ICES1); //Set CTC by WGM12
TIMSK1 |= (1<<TOIE1); //Timer/Counter0 Overflow interrupt is enabled
OCR1A = 15624;
pinMode(LEDButtonPin,OUTPUT);
pinMode(AlarmPin,OUTPUT);
pinMode(PotEnablePin,OUTPUT);
pinMode(PIRPin, INPUT);
pinMode(ButtonPin, INPUT_PULLUP);
sbi(GIMSK, PCIE0); //Turn on pin change interrupt
GIMSK |= (1<<INT0); //INT0
sei(); //enable global interrupt
Led (1);
beep(1,100);
}
ISR(PCINT0_vect){ // button interrupt
flagBUT = true;
}
ISR(INT0_vect){ // sensor interrupt
if (digitalRead(PIRPin)) flagPIR = true;
}
void loop() {
if (flagBUT || flagPIR || flagTIM){
if (flagBUT){
t1 = millis();
if (abs(t1-t1_) < 800) {flagBUT = false; t1_= t1; return;}
else {
t1_= t1;
flagBUT = false;
if (state == 1) state = 2;
else state = 1;
}
}
switch (state) {
case 1:
cbi(PCMSK0,PCINT7); // Turn On PIR sensor interrupt
timer(false);
alarm(false);
Led (1);
beep(1,100);
break;
case 2:
counter = armDelay;
timer(true);
beep(2,500);
while (!flagTIM){
Led(1);
delay(1000);
if (flagBUT) return;
Led(0);
delay(1000);
if (flagBUT) return;
}
flagTIM = false;
digitalWrite(PotEnablePin, HIGH);
sbi(ADCSRA,ADEN); // Switch ADC on
delay (200);
alarmDelay = map(analogRead(pot_DEL_pin),0,1023,0,60);
alarmDuration = map(analogRead(pot_DUR_pin),0,1023,0,3600);
cbi(ADCSRA,ADEN); //Switch ADC off
digitalWrite(PotEnablePin, LOW);
sbi(PCMSK0,PCINT7); // Turn On PIR sensor interrupt
beep(3,100);
state = 3;
sleep();
break;
case 3:
flagPIR = false;
counter = alarmDelay;
timer(true);
beep(5,80);
while (!flagTIM){
Led(1);
delay(200);
Led(0);
delay(200);
if (flagBUT) return;
}
alarm(1);
counter = alarmDuration;
timer(true);
while (!flagTIM){
if (flagPIR) counter = alarmDuration;
if (flagBUT) return;
}
alarm(0);
beep(3,100);
sleep();
break;
}
} else delay(10);
}
ISR(TIM1_COMPA_vect)
{
counter--;
if (counter<=0) {
flagTIM = true;
timer(false);
}
}
void timer(bool command1){
if (command1)
{
TCCR1B |= (1<<CS11)|(1<<CS10);
TCCR1B &= ~(1<<CS12); //set prescaler
}
else {
TCCR1B &= ~((1<<CS10)|(1<<CS11)|(1<<CS12));
}
}
void beep (uint8_t repeat, uint16_t interval){
pinMode(BuzzerPin,OUTPUT);
for (int i = repeat; i > 0; i--){
digitalWrite(BuzzerPin, HIGH);
delay(interval);
digitalWrite(BuzzerPin, LOW);
if (i > 1) delay(interval);
}
}
void alarm(bool on_off){
if (on_off == 1){
digitalWrite(AlarmPin, HIGH);
} else{
digitalWrite(AlarmPin, LOW);
}
}
void Led (uint8_t ledmode){
if (ledmode) digitalWrite(LEDButtonPin, HIGH);
else digitalWrite(LEDButtonPin, LOW);
}
void sleep(){
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode
sleep_mode(); //System sleep
}
The suspected parts are: Timer interrupt, button interrupt and sensor interrupt. Attention on them please, thanks.