Transform void loop() into timer with intterrupts

post your current code

//declararea butoanelor
const int b1 = 2;
const int b2 = 3; 
const int b3 = 4;
const int b4 = 5;
const int b5 = 11; //buton resetare conexiune

//declararea ledurilor

int ledRAD = 6;
int ledCD = 7;
int ledDVD = 8;
int ledTV = 9;
int ledpv = 10; //program si volum

byte lastButton1Value = LOW;
byte lastButton2Value = LOW;
byte lastButton3Value = LOW;
byte lastButton4Value = LOW;

int blinkRepeats;
int seconds;

void setup() 
{
  noInterrupts();
  //declararea ledurilor ca si OUTPUT-uri
  pinMode(ledTV, OUTPUT);
  pinMode(ledDVD, OUTPUT);
  pinMode(ledCD, OUTPUT);
  pinMode(ledRAD, OUTPUT);
  pinMode(ledpv, OUTPUT);
  
  //declararea butoanelor ca si INPUT-uri
  pinMode(b1, INPUT);
  pinMode(b2, INPUT); 
  pinMode(b3, INPUT); 
  pinMode(b4, INPUT); 
  pinMode(b5, INPUT);

  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;

  OCR1A = 312;
  TCCR1B |= (1<<WGM12);
  TCCR1B |= (1<<CS10);
  TIMSK1 |= (1<<OCIE1A);

  interrupts();
  Serial.begin(9600);
}

int Q = 1;

void blinky(int ledPin, int delayTime, int blinkies)
{
  int b;
  noInterrupts();
  for(b=0; b<blinkies; b++)
  {
    digitalWrite(ledPin, HIGH);
    delay(delayTime);
    digitalWrite(ledPin, LOW);
    delay(delayTime);
  }
  interrupts();
}
  
ISR (TIMER1_COMPA_vect)
{
  int bs1, bs2, bs3, bs4;
  switch (Q)
  {
    case 1:
      if(digitalRead(b1)==HIGH)
        Q=2;
        else 
          if(digitalRead(b2)==HIGH)
            Q=3;
          else 
            if(digitalRead(b3)==HIGH)
              Q=4; 
            else 
              if(digitalRead(b4)==HIGH)
                Q=5; 
    break;
    
    case 2:
      digitalWrite(ledRAD, HIGH);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, LOW);
      digitalWrite(ledTV, LOW);
        
      bs1 = digitalRead(b1);
      bs2 = digitalRead(b2);
      bs3 = digitalRead(b3);
      bs4 = digitalRead(b4);
      if(bs1 == HIGH)
        blinky(ledpv, 20, 5);
      if(bs2 == HIGH)
        blinky(ledpv, 40, 5);
      if(bs3 == HIGH)
        blinky(ledpv, 60, 5);
      if(bs4 == HIGH)
        blinky(ledpv, 80, 5);
      if(digitalRead(b5)==HIGH)
      {
        Q=1;
        digitalWrite(ledRAD, LOW);
      }
      
    break;
    
    case 3:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledCD, HIGH);
      digitalWrite(ledDVD, LOW);
      digitalWrite(ledTV, LOW);
      if(digitalRead(b5)==HIGH)
      {
        Q=1;
        digitalWrite(ledCD, LOW);
      }
    break;
    
    case 4:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, HIGH);
      digitalWrite(ledTV, LOW);
      if(digitalRead(b5)==HIGH)
      {
        Q=1;
        digitalWrite(ledDVD, LOW);
      }
    break;
    
    case 5:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, LOW);
      digitalWrite(ledTV, HIGH);
      if(digitalRead(b5)==HIGH)
      {
        Q=1;
        digitalWrite(ledTV, LOW);
      }
    break;
  }
}

void loop() {}

blinky is the function that should blink that led. After choosing the state in which i want to go, i have 4 options: button 1 pressed, button 2 pressed, b3 pressed, b4 pressed. If b1 is pressed do some blinky stuff, if b2 is pressed, do other blink stuff…

But what my code does now: is that after selecting the first case, the led stays on the same amount of time as the button is pressed… And it shouldn`t do that. it should wait for a button to be pressed, and do something acording to that button.

Hope i explained my self corectly…

Also ive found an interesting thing. if im in case 1 and i keep pressing the 3rd button... it will jump to case 3... that shouldn`t happen

You cannot use delay() inside an ISR (your call to blinky) so that will be a problem for case 2.

Other than that, it should change states correctly when pressing buttons. However, you should look at button edge detection as right now, you are detecting button levels and not button edges.

https://www.arduino.cc/en/Tutorial/StateChangeDetection

If you wanted to, you could move your current ISR code into loop for now so you can use Serial.print() while you are debugging.

But, to be sure we're headed down the right path, can you post the actual assignment question?

"Using interrupts, 5 buttons, 5 leds, make a remote control. example:

State 1: (q=1); B1 == HIGH? q=2 State 2: (q=2) LED2 = HIGH B1 == HIGH? blink LED5 a certain number of time B2 == HIGH? blink LED5 a certain number of time same for b3 and b4 B5 == HIGH? q = 1;

And so on for 3 more states, q=3, q=4, q=5."

All i need now, is to be able to make LED5 blink when of that 4 buttons is pressed, withing one of the 4 states, 2, 3, 4, and 5

This is the code i`m working on:

//declararea butoanelor
const int b1 = 2;
const int b2 = 3; 
const int b3 = 4;
const int b4 = 5;
const int b5 = 11; //buton resetare conexiune

//declararea ledurilor

int ledRAD = 6;
int ledCD = 7;
int ledDVD = 8;
int ledTV = 9;
int ledpv = 10; //program si volum

byte lastButton1Value = LOW;
byte lastButton2Value = LOW;
byte lastButton3Value = LOW;
byte lastButton4Value = LOW;

void setup() 
{
  noInterrupts();
  //declararea ledurilor ca si OUTPUT-uri
  pinMode(ledTV, OUTPUT);
  pinMode(ledDVD, OUTPUT);
  pinMode(ledCD, OUTPUT);
  pinMode(ledRAD, OUTPUT);
  pinMode(ledpv, OUTPUT);
  
  //declararea butoanelor ca si INPUT-uri
  pinMode(b1, INPUT);
  pinMode(b2, INPUT); 
  pinMode(b3, INPUT); 
  pinMode(b4, INPUT); 
  pinMode(b5, INPUT);
  
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;

  OCR1A = 512;
  TCCR1B |= (1<<WGM12);
  TCCR1B |= (1<<CS10);
  TIMSK1 |= (1<<OCIE1A);

  interrupts();
}

int Q = 1;

ISR (TIMER1_COMPA_vect)
{
  int bs1, bs2, bs3, bs4;
  switch (Q)
  {
    case 1:
      if(digitalRead(b1)==HIGH)
        Q=2;
        else 
          if(digitalRead(b2)==HIGH)
            Q=3;
          else 
            if(digitalRead(b3)==HIGH)
              Q=4; 
            else 
              if(digitalRead(b4)==HIGH)
                Q=5; 
    break;
    
    case 2:
      digitalWrite(ledRAD, HIGH);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, LOW);
      digitalWrite(ledTV, LOW);
        
      bs1 = digitalRead(b1);
      bs2 = digitalRead(b2);
      bs3 = digitalRead(b3);
      bs4 = digitalRead(b4);
      /*
      if(bs1 == HIGH)
        //blink ledpv X times
      if(bs2 == HIGH)
        //blink ledpv Y times
      if(bs3 == HIGH)
        //blink ledpv Z times
      if(bs4 == HIGH)
        //blink ledpv A times 
      */
      if(digitalRead(b5)==HIGH)
      {
        Q=1;
        digitalWrite(ledRAD, LOW);
      }
      
    break;
    
    case 3:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledCD, HIGH);
      digitalWrite(ledDVD, LOW);
      digitalWrite(ledTV, LOW);
      if(digitalRead(b5)==HIGH)
      {
        Q=1;
        digitalWrite(ledCD, LOW);
      }
    break;
    
    case 4:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, HIGH);
      digitalWrite(ledTV, LOW);
      if(digitalRead(b5)==HIGH)
      {
        Q=1;
        digitalWrite(ledDVD, LOW);
      }
    break;
    
    case 5:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, LOW);
      digitalWrite(ledTV, HIGH);
      if(digitalRead(b5)==HIGH)
      {
        Q=1;
        digitalWrite(ledTV, LOW);
      }
    break;
  }
}

void loop() {}

Where are the ifs in /* */, there should be added the blinky function. And that`s all i need. To be able to blink that led acording to the button is pressed

Any idea how to make a blink function into the ISR?

If it were me, I would call the blink function from loop(). Set a variable in the ISR, and read it in the loop to start/stop the blink function.

If you posted the exact question, the teacher doesn't explicitly say the loop has to be empty, just that you have to use interrupts somewhere. I would be asking the teacher what I was and was not allowed to do.

Unfortunelty, theres no more time for me to ask what im allowed, or not to do. So, let`s call the blink function from the loop ().

I don`t understand the: set a variabile in the isr…

I think loop will look like this:

if(variable == x)
blink 3 times
if variable == y
blink 5 times
and so on…

but what do you mean by setting a variable in the isr. something like: variable = digitalRead(button)? or…

//declararea butoanelor
const int b1 = 2;
const int b2 = 3; 
const int b3 = 4;
const int b4 = 5;
const int b5 = 11;

//declararea ledurilor

int ledRAD = 6;
int ledCD = 7;
int ledDVD = 8;
int ledTV = 9;
int ledpv = 10;

byte lastButton1Value = LOW;
byte lastButton2Value = LOW;
byte lastButton3Value = LOW;
byte lastButton4Value = LOW;

void setup() 
{
  noInterrupts();
  //declararea ledurilor ca si OUTPUT-uri
  pinMode(ledTV, OUTPUT);
  pinMode(ledDVD, OUTPUT);
  pinMode(ledCD, OUTPUT);
  pinMode(ledRAD, OUTPUT);
  pinMode(ledpv, OUTPUT);
  
  //declararea butoanelor ca si INPUT-uri
  pinMode(b1, INPUT);
  pinMode(b2, INPUT); 
  pinMode(b3, INPUT); 
  pinMode(b4, INPUT); 
  pinMode(b5, INPUT);
  
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;

  OCR1A = 512;
  TCCR1B |= (1<<WGM12);
  TCCR1B |= (1<<CS10);
  TIMSK1 |= (1<<OCIE1A);

  interrupts();
}

int Q = 1;
int variable;

ISR (TIMER1_COMPA_vect)
{
  int bs1, bs2, bs3, bs4;
  switch (Q)
  {
    case 1:
      if(digitalRead(b1)==HIGH)
        Q=2;
        else 
          if(digitalRead(b2)==HIGH)
            Q=3;
          else 
            if(digitalRead(b3)==HIGH)
              Q=4; 
            else 
              if(digitalRead(b4)==HIGH)
                Q=5; 
    break;
    
    case 2:
      digitalWrite(ledRAD, HIGH);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, LOW);
      digitalWrite(ledTV, LOW);
      /*
      if(bs1 == HIGH)
        //blink ledpv X times
      if(bs2 == HIGH)
        //blink ledpv Y times
      if(bs3 == HIGH)
        //blink ledpv Z times
      if(bs4 == HIGH)
        //blink ledpv A times 
      */
      if(digitalRead(b4) == HIGH)
        variable = 2;
      if(digitalRead(b5)==HIGH)
      {
        Q=1;
        digitalWrite(ledRAD, LOW);
      }
      
    break;
    
    case 3:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledCD, HIGH);
      digitalWrite(ledDVD, LOW);
      digitalWrite(ledTV, LOW);
      if(digitalRead(b5)==HIGH)
      {
        Q=1;
        digitalWrite(ledCD, LOW);
      }
    break;
    
    case 4:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, HIGH);
      digitalWrite(ledTV, LOW);
      if(digitalRead(b5)==HIGH)
      {
        Q=1;
        digitalWrite(ledDVD, LOW);
      }
    break;
    
    case 5:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, LOW);
      digitalWrite(ledTV, HIGH);
      if(digitalRead(b5)==HIGH)
      {
        Q=1;
        digitalWrite(ledTV, LOW);
      }
    break;
  }
}

void loop() 
{
  if( variable == 2)
    blinkpv(ledpv, 5, 1000);
}

void blinkpv(int led, int count, int seconds)
{
  static unsigned long lastMillis = 0;
  static int interval = 1;
  static int lastCount = 0;
  if (count > lastCount)
  {
    interval = seconds / 2 / count;
    lastMillis = millis();
  }
  if (count <= 0)
  {
    count = 0;
    return;
  }
  if (millis() - lastMillis > interval)
  {
    if (digitalRead(led))  
      count--;
    digitalWrite(led, !digitalRead(led));
    lastMillis += interval;
  }
  lastCount = count;
}

this is what i understood… When i press b4 after selecting first case, it does nothing. but if i press b5, the led starts to blink continuisly, instead for 1 second. How do i exit the loop and come back to ISR?

ISR stands for Interrupt Service Routine. It interrupts whatever else is happening, executes, then gives control back.

For example, You are reading a book. You are happily doing that. Then, you need to go to the bathroom. You stop reading the book and go to the bathroom. When you've finished, you go back to reading you book. Every time you need to go to the bathroom, the reading stops, you go to the bathroom, and when finished, return to reading your book.

The main task you are trying to perform is reading your book. But, whenever it needs to, the bathroom ISR interrupts your reading to perform its task. When it has finished, it lets you go back to reading.

Since you have your state machine in your ISR in your program, you need to signal to the loop program that it should start blinking the LEDS now. Just set a global variable in your ISR, and read it inside loop() so that loop() knows what it should be doing about the blinking, if anything.

//declararea butoanelor
const int b1 = 2;
const int b2 = 3; 
const int b3 = 4;
const int b4 = 5;
const int b5 = 11;

//declararea ledurilor

int ledRAD = 6;
int ledCD = 7;
int ledDVD = 8;
int ledTV = 9;
int ledpv = 10;

void setup() 
{
  noInterrupts();
  //declararea ledurilor ca si OUTPUT-uri
  pinMode(ledTV, OUTPUT);
  pinMode(ledDVD, OUTPUT);
  pinMode(ledCD, OUTPUT);
  pinMode(ledRAD, OUTPUT);
  pinMode(ledpv, OUTPUT);
  
  //declararea butoanelor ca si INPUT-uri
  pinMode(b1, INPUT);
  pinMode(b2, INPUT); 
  pinMode(b3, INPUT); 
  pinMode(b4, INPUT); 
  pinMode(b5, INPUT);
  
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;

  OCR1A = 512;
  TCCR1B |= (1<<WGM12);
  TCCR1B |= (1<<CS10);
  TIMSK1 |= (1<<OCIE1A);

  interrupts();
}

int Q = 1;

ISR (TIMER1_COMPA_vect)
{
  int bs1, bs2, bs3, bs4;
  [b]int var;[/b]
 //switch case stuffs
}

void loop()
{
  if(digitalRead(b4)==HIGH)
    var = 1;
  if(var == 1)
    blinkpv(ledpv, 4, 2000);
}

void blinkpv(int led, int count, int seconds)
{
  //stuff to make a led blink
}

Error: ‘var’ was not declared in this scope. I got only a few hours left, and i cant make this idiot leds blink... i dont understand this last part, of calling loop to read, and do stuff…

remove the [ b ][ /b ] bold tags from your code to fix the var issue.

const int b1 = 2;
const int b2 = 3;
const int b3 = 4;
const int b4 = 5;
const int b5 = 11;

const int ledRAD = 6;
const int ledCD = 7;
const int ledDVD = 8;
const int ledTV = 9;
const int ledpv = 10;

int state = 1;

void setup() 
{
  noInterrupts();
   
  pinMode(b1, INPUT);
  pinMode(b2, INPUT);
  pinMode(b3, INPUT);
  pinMode(b4, INPUT);
  pinMode(b5, INPUT);

  pinMode(ledRAD, OUTPUT);
  pinMode(ledCD, OUTPUT);
  pinMode(ledDVD, OUTPUT);
  pinMode(ledTV, OUTPUT);
  pinMode(ledpv, OUTPUT);

  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;

  OCR1A = 312;              // compare match register 16MHz/1/100Hz
  TCCR1B |= (1 << WGM12);   // CTC mode
  TCCR1B |= (1 << CS10);    // 1 prescaler 
  TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
  
  interrupts();
}

void loop() {}

void blinky(int led, int delayT, int blinkies) 
{
  int i;

  noInterrupts();
  
  for (i = 0; i < blinkies; i++) {
    digitalWrite(led, HIGH);
    delay(delayT);
    digitalWrite(led, LOW );
    delay(delayT);
  }

  interrupts();
}

void hold(int button) 
{
  while (digitalRead(button) == HIGH)
    delay(50);
}

ISR(TIMER1_COMPA_vect) 
{
  int b1s, b2s, b3s, b4s;
    
  switch (state) 
  {
    case 1:
      b1s = digitalRead(b1);
      b2s = digitalRead(b2);
      b3s = digitalRead(b3);
      b4s = digitalRead(b4);
      if (b1s == HIGH) 
      {
        hold(b1);
        state = 2;
        break;
      }
      if (b2s == HIGH) 
      {
        hold(b2);
        state = 3;
        break;
      }
      if (b3s == HIGH) 
      {
        hold(b3);
        state = 4;
        break;
      }
      if (b4s == HIGH) 
      {
        hold(b4);
        state = 5;
        break;
      }
    break;
    //device-ul 1
    case 2:
      digitalWrite(ledRAD, HIGH);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, LOW);
      digitalWrite(ledTV, LOW);
      b1s = digitalRead(b1);
      b2s = digitalRead(b2);
      b3s = digitalRead(b3);
      b4s = digitalRead(b4);
      if (b1s == HIGH) 
      {
        blinky(ledpv, 1000, 5);
        hold(b1);
        break;
       }
      if (b2s == HIGH) 
      {
        blinky(ledpv, 2000, 5 );
        hold(b2);
        break;
      }
      if (b3s == HIGH) 
      {
        blinky(ledpv, 3000, 5 );
        hold(b2);
        break;
      }
      if (b4s == HIGH) 
      {
        blinky(ledpv, 4000, 5 );
        hold(b2);
        break;
      }
      if (digitalRead(b5) == HIGH) 
      {
        state = 1;
        digitalWrite(ledRAD, LOW);
        break;
      }
    break;
    //device-ul 2
    case 3:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledCD, HIGH);
      digitalWrite(ledDVD, LOW);
      digitalWrite(ledTV, LOW);
      b1s = digitalRead(b1);
      b2s = digitalRead(b2);
      b3s = digitalRead(b3);
      b4s = digitalRead(b4);
      if (b1s == HIGH) 
      {
        blinky(ledpv, 1000, 5);
        hold(b1);
        break;
       }
      if (b2s == HIGH) 
      {
        blinky(ledpv, 2000, 5 );
        hold(b2);
        break;
      }
      if (b3s == HIGH) 
      {
        blinky(ledpv, 3000, 5 );
        hold(b2);
        break;
      }
      if (b4s == HIGH) 
      {
        blinky(ledpv, 4000, 5 );
        hold(b2);
        break;
      }
      if (digitalRead(b5) == HIGH) 
      {
        state = 1;
        digitalWrite(ledCD, LOW);
        break;
      }
    break;
    //device-ul 3
    case 4:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, HIGH);
      digitalWrite(ledTV, LOW);
      b1s = digitalRead(b1);
      b2s = digitalRead(b2);
      b3s = digitalRead(b3);
      b4s = digitalRead(b4);
      if (b1s == HIGH) 
      {
        blinky(ledpv, 1000, 5);
        hold(b1);
        break;
       }
      if (b2s == HIGH) 
      {
        blinky(ledpv, 2000, 5 );
        hold(b2);
        break;
      }
      if (b3s == HIGH) 
      {
        blinky(ledpv, 3000, 5 );
        hold(b2);
        break;
      }
      if (b4s == HIGH) 
      {
        blinky(ledpv, 4000, 5 );
        hold(b2);
        break;
      }
      if (digitalRead(b5) == HIGH) 
      {
        state = 1;
        digitalWrite(ledDVD, LOW);
        break;
      }
    break;
    //device-ul 4
    case 5:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, LOW);
      digitalWrite(ledTV, HIGH);
      b1s = digitalRead(b1);
      b2s = digitalRead(b2);
      b3s = digitalRead(b3);
      b4s = digitalRead(b4);
      if (b1s == HIGH) 
      {
        blinky(ledpv, 1000, 5);
        hold(b1);
        break;
       }
      if (b2s == HIGH) 
      {
        blinky(ledpv, 2000, 5 );
        hold(b2);
        break;
      }
      if (b3s == HIGH) 
      {
        blinky(ledpv, 3000, 5 );
        hold(b2);
        break;
      }
      if (b4s == HIGH) 
      {
        blinky(ledpv, 4000, 5 );
        hold(b2);
        break;
      }
      if (digitalRead(b5) == HIGH) 
      {
        state = 1;
        digitalWrite(ledTV, LOW);
        break;
      }
    break;
  }
}

This code is aprox. the same as mine, but it has that HOLD function and a different blink function.

And guess what: this code works PERFECTLY!!!