ATTINY85 & interruptions

Hi everyone,

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);
  }

}

Poorly formatted, but this might be an issue…

else if (ILS1 ==1 && ILS2 ==2) {

should be ILS2==1, thanks but still does not work

a much better way would be


volatile uint8_t ILS = 0;  // remember the volatile !!! 
ISR(PCINT_VECTOR) {

  if ((digitalRead(INT_PIN_ILS1) == LOW) && (digitalRead(INT_PIN_ILS2) == HIGH)) {
    ILS = 1;
    else if ((digitalRead(INT_PIN_ILS2) == LOW) && (digitalRead(INT_PIN_ILS1) == HIGH) {
    ILS =2;
    } 
    else if ((digitalRead(INT_PIN_ILS2) ==HIGH) && (digitalRead(INT_PIN_ILS1) == HIGH) {
    ILS =3 ;
    }
    else {
    ILS=0;
    }
}

and then in loop do a simple switch/case

thanks! working well

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);
 
}




this should mean that 'State' toggles every time 1 or both of the inputs goes 'LOW'
What do you want it to do ?

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);
 
}




the static doesn't do anything in this statement.

if (State>1) {State = 0;} else

                     {State ++;}

this doesn't look quite right either, don't you mean ?

if (State>0) {State = 0;} else

                     {State ++;}