I try to programme interruptions on attiny85. ILS 1 and ILS 2 are reed switches.
When ILS1 is activated and ILS2 is not, or vice versa when ILS1 is not activated and ILS2 is activated, I want both LEDs 1 and 2 to be set to HIGH. However, if both ILS1 and ILS2 have been activated, I want both LEDs to be switched off.
The programme does not work and I do not see why.
Thanks for your help.
#include <avr/io.h>
#include <avr/interrupt.h>
#define INT_PIN_ILS1 PB4 // interrupt change pin of choice: PB4
#define INT_PIN_ILS2 PB3 // interrupt change pin of choice: PB3
#define LED_PIN1 PB0 // LED 1
#define LED_PIN2 PB1 // LED 2
#define PCINT_VECTOR PCINT0_vect // naming the ISR for clarity
int ILS1=0, ILS2=0;
void setup() {
pinMode(LED_PIN1, OUTPUT);
pinMode(LED_PIN2, OUTPUT);
cli();
PCMSK =0b000011000; //|= (1<<INTERRUPT_PIN); // enable interrupt handler ISR for the PB3 and PB4
GIMSK |=(1<<PCIE); // enable PCINT interrupt in the general interrupt mask
pinMode(INT_PIN_ILS1, INPUT_PULLUP);
pinMode(INT_PIN_ILS2, INPUT_PULLUP);
sei();
}
ISR(PCINT_VECTOR) {
if ((digitalRead(INT_PIN_ILS1) == LOW) && ILS2==0) {
ILS1=1;} else if ((digitalRead(INT_PIN_ILS2) == LOW) && ILS1==0) {
ILS2=1;} else if (ILS2==1 && ILS1==1) {
ILS2=0;
ILS1=0;}
}
void loop() {
if (ILS1 ==0 && ILS2 ==1) {
digitalWrite(LED_PIN1, HIGH);
digitalWrite(LED_PIN2, HIGH);
} else if (ILS1 ==1 && ILS2 ==2) {
digitalWrite(LED_PIN1, HIGH);
digitalWrite(LED_PIN2, HIGH);
} else if (ILS1 ==1 && ILS2 ==1) {
digitalWrite(LED_PIN1, LOW);
digitalWrite(LED_PIN2, LOW);
}
}
I have tried to optimize the programme:
But even if the ILS are triggered, the change of state (declared as a volatile boolean) does not happen and the loop cannot read the state of change.
may I ask you to help me?
Thanks
#include <avr/io.h>
#include <avr/interrupt.h>
#define INT_PIN_ILS1 PB3 // interrupt pin of choice: PB4
#define INT_PIN_ILS2 PB4 // interrupt pin of choice: PB3
#define LED_PIN1 PB0 // LED 1
#define LED_PIN2 PB1 // LED 2
volatile static boolean State = false; // the train is not in the area where railscrossing must be triggered
void setup() {
pinMode(LED_PIN1, OUTPUT);
pinMode(LED_PIN2, OUTPUT);
digitalWrite(LED_PIN1,LOW);
digitalWrite(LED_PIN2,LOW);
cli();
PCMSK =0b00011000; //|= (1<<INTERRUPT_PIN); // enable interrupt handler ISR for the PB3 and PB4
GIMSK |=(1<<PCIE); // enable PCINT interrupt in the general interrupt mask
pinMode(INT_PIN_ILS1, INPUT_PULLUP);
pinMode(INT_PIN_ILS2, INPUT_PULLUP);
sei();
}
ISR(PCINT0_vect) {
// ISR is triggered by ils1 or ils2
if (digitalRead(INT_PIN_ILS1)==LOW || digitalRead(INT_PIN_ILS2)==LOW ) {
State != State ;
}
}
void loop() {
if(State == true) {up();}
else if(State == false) {down();}
}
void up(){
digitalWrite(LED_PIN1,HIGH);
digitalWrite(LED_PIN2,HIGH);
}
void down(){
digitalWrite(LED_PIN1,LOW);
digitalWrite(LED_PIN2,LOW);
}
That's okay. Sorry.
I put : volatile static uint8_t State=0;
... when first ILS triggered then led switched and when 2nd ILS triggered then Led switched off.
I put a delay/millis to kill the bounce.
so it s workinng. apologize.
#include <avr/io.h>
#include <avr/interrupt.h>
#define INT_PIN_ILS1 PB3 // interrupt pin of choice: PB4
#define INT_PIN_ILS2 PB4 // interrupt pin of choice: PB3
#define LED_PIN1 PB0 // LED 1
#define LED_PIN2 PB1 // LED 2
volatile static uint8_t State=0; // the train is not in the area where railscrossing must be triggered
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 700; //the value is a number of milliseconds
void setup() {
pinMode(LED_PIN1, OUTPUT);
pinMode(LED_PIN2, OUTPUT);
digitalWrite(LED_PIN1,LOW);
digitalWrite(LED_PIN2,LOW);
cli();
PCMSK =0b00011000; //|= (1<<INTERRUPT_PIN); // enable interrupt handler ISR for the PB3 and PB4
GIMSK |=(1<<PCIE); // enable PCINT interrupt in the general interrupt mask
pinMode(INT_PIN_ILS1, INPUT_PULLUP);
pinMode(INT_PIN_ILS2, INPUT_PULLUP);
sei();
}
ISR(PCINT0_vect) {
// ISR is triggered by ils1 or ils2
currentMillis = millis(); //get the current "time" (actually the number of milliseconds since the program started)
if (currentMillis - startMillis >= period) //test whether the period has elapsed
{
if (digitalRead(INT_PIN_ILS1)==LOW || digitalRead(INT_PIN_ILS2)==LOW ) {
if (State>1) {State = 0;} else
{State ++;}
startMillis = currentMillis;
}
}
}
void loop() {
if(State >0) {up();}
else
{down();}
}
void up(){
digitalWrite(LED_PIN1,HIGH);
digitalWrite(LED_PIN2,HIGH);
}
void down(){
digitalWrite(LED_PIN1,LOW);
digitalWrite(LED_PIN2,LOW);
}