#define MAXIMUM 5 //capienza massima stanza
#define MINIMUM 0 //capienza minima stanza
#define SET_HIGH1 -125 //500us, servomotore a 0°
#define SET_HIGH2 -368 //1472us, servomotore a 90°
#define SET_HIGH3 -613 //2450us, servomotore a 180°
volatile uint8_t people = 0; //numero persone attualmente nella stanza
void setup() {
DDRD &= ~_BV(2); //PIR entrata impostato come INPUT
DDRD &= ~_BV(3); //PIR uscita impostato come INPUT
DDRD |= _BV(4); //servomotore impostato come OUTPUT
EICRA &= ~_BV(ISC01); //interrupt PIR entrata attivato...
EICRA |= _BV(ISC00); //in qualunque cambiamento logico
EIMSK |= _BV(INT0); //interrupt PIR entrata abilitato
EICRA &= ~ _BV(ISC11); //interrupt PIR uscita attivato...
EICRA |= _BV(ISC10); //in qualunque cambiamento logico
EIMSK |= _BV(INT1); //interrupt PIR uscita abilitato
TCCR1A = 0; //valore di default
TCCR1B &= ~_BV(CS12); //prescaler a 64...
TCCR1B |= _BV(CS11); //un tick ogni...
TCCR1B |= _BV(CS10); //64 cicli di clock
TIMSK1 |= _BV(TOIE1); //interrupt TIMER abilitato
}
void loop() {
//...
}
/*questa routine di servizio serve ad aprire la porta in entrata quando il
PIR di entrata passa da LOW ad HIGH e la richiude quando da HIGH torna a LOW*/
ISR(INT0_vect){
if(people <= MAXIMUM) {
TIMSK1 &= ~_BV(TOIE1); //interrupt TIMER disabilitato
EIMSK &= ~_BV(INT1); //interrupt PIR uscita disabilitato
PORTD |= _BV(4); //servomotore in HIGH per farlo ruotare
if((PIND & _BV(2)) && (people < MAXIMUM)) {
TCNT1 = SET_HIGH3; //tempo rotazione servomotore a 180°
people++; //una persona sta entrando
} else {
TCNT1 = SET_HIGH2; //tempo rotazione servomotore a 90°
EIMSK |= _BV(INT1); //interrupt PIR uscita abilitato
}
TIMSK1 |= _BV(TOIE1); //interrupt TIMER abilitato
}
}
/*questa routine di servizio serve ad aprire la porta in uscita quando il
PIR di uscita passa da LOW ad HIGH e la richiude quando da HIGH torna a LOW*/
ISR(INT1_vect){
if(people >= MINIMUM) {
TIMSK1 &= ~_BV(TOIE1); //interrupt TIMER disabilitato
EIMSK &= ~_BV(INT0); //interrupt PIR entrata disabilitato
PORTD |= _BV(4); //servomotore in HIGH per farlo ruotare
if((PIND & _BV(3)) && (people > MINIMUM)) {
TCNT1 = SET_HIGH1; //tempo rotazione servomotore a 0°
people--; //una persona sta uscendo
} else {
TCNT1 = SET_HIGH2; //tempo rotazione servomotore a 90°
EIMSK |= _BV(INT0); //interrupt PIR entrata abilitato
}
TIMSK1 |= _BV(TOIE1); //interrupt TIMER abilitato
}
}
/*questa routine di servizio serve a fermare il servomotore nella posizione
richiesta dopo il tempo di HIGH*/
ISR(TIMER1_OVF_vect) {
PORTD &= ~_BV(4); //servomotore in LOW per fermarlo
}