Transform void loop() into timer with intterrupts

Hello there guys. So, i have this 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 ledTV = 9;
int ledDVD = 8;
int ledCD = 7;
int ledRAD = 6;
int ledpv = 10; //program si volum

void setup() 
{
  //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);
  Serial.begin(9600);
}

int bs1 = 0;
int bs2 = 0;
int bs3 = 0;
int bs4 = 0;
int bs5 = 0;

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

int blinkRepeats;
int seconds;


void loop() 
{
  read_bs();
  int device = bs1 + bs2*2 + bs3*4 + bs4*8;
  int exitd;
  switch(device)
  {
    case 1:
      digitalWrite(ledRAD, HIGH);
      exitd=0;
      while(exitd<1)
      {
        blinkpv(ledpv, blinkRepeats, 1000);
        if(digitalRead(b5)==HIGH)
          exitd++; 
      }
      break;
      
    case 2:
      digitalWrite(ledCD, HIGH);
      reset_bs(); 
      exitd=0;
      while(exitd<1)
      {
        blinkpv(ledpv, blinkRepeats, 2000);
        if(digitalRead(b5)==HIGH)
          exitd++; 
      }
      break;
      
    case 4:
      digitalWrite(ledDVD, HIGH);
      reset_bs(); 
      exitd=0;
      while(exitd<1)
      {
        blinkpv(ledpv, blinkRepeats, 3000);
        if(digitalRead(b5)==HIGH)
          exitd++; 
      }
      break;
      
    case 8:
      digitalWrite(ledTV, HIGH);
      reset_bs(); 
      exitd=0;
      while(exitd<1)
      {
        blinkpv(ledpv, blinkRepeats, 4000);
        if(digitalRead(b5)==HIGH)
          exitd++; 
      }
      break;
  }
  turnOff();
}

void read_bs()
{
  bs1=digitalRead(b1);
  bs2=digitalRead(b2);
  bs3=digitalRead(b3);
  bs4=digitalRead(b4);
}

void reset_bs()
{
  bs1=bs2=bs3=bs4=0;
}

void turnOff()
{
  static int lastbs5 = LOW;
  bs5=digitalRead(b5);
  if((bs5==HIGH)&&(bs5!=lastbs5))
  {
    digitalWrite(ledTV, LOW);
    digitalWrite(ledDVD, LOW);
    digitalWrite(ledRAD, LOW);
    digitalWrite(ledCD, LOW);
    digitalWrite(ledpv, LOW);
  }
  lastbs5=bs5;
}

void blinkpv(int led, int &count, int seconds)
{
  byte button1Value = digitalRead(b1);
  byte button2Value = digitalRead(b2);
  byte button3Value = digitalRead(b3);
  byte button4Value = digitalRead(b4);
  if (button1Value == LOW && lastButton1Value == HIGH)
    blinkRepeats = 1;
  else 
    if (button2Value == LOW && lastButton2Value == HIGH) 
      blinkRepeats = 2;
      else 
        if (button3Value == LOW && lastButton3Value == HIGH) 
          blinkRepeats = 3;
        else 
          if (button4Value == LOW && lastButton4Value == HIGH) 
            blinkRepeats = 4;
  lastButton1Value = button1Value;
  lastButton2Value = button2Value;
  lastButton3Value = button3Value;
  lastButton4Value = button4Value;
  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;
}

Basically, this code is used to connect to four devices, using 4 buttons. After connecting to one device, the same 4 buttons are used to light a 5th led in different ways.

The problem is that I am not allowed to use void loop()… How can i integrate a timer with interrupts that allows me to run the program?!

Thank you very much!

Xeyow: The problem is that I am not allowed to use void loop()...

Why not?

Because the teacher wants to use interrupts.

I think that all the code in the void loop () must be integrated into a timer... how can i do that? i know nothing about timers...

byte lastButton1Value = LOW;
byte lastButton2Value = LOW;
byte lastButton3Value = LOW;
byte lastButton4Value = LOW;
...
  byte button1Value = digitalRead(b1);
  byte button2Value = digitalRead(b2);
  byte button3Value = digitalRead(b3);
  byte button4Value = digitalRead(b4);

You realize these are different variables, right?

[quote author=Nick Gammon link=msg=2561064 date=1452581403]

byte lastButton1Value = LOW;
byte lastButton2Value = LOW;
byte lastButton3Value = LOW;
byte lastButton4Value = LOW;
...
  byte button1Value = digitalRead(b1);
  byte button2Value = digitalRead(b2);
  byte button3Value = digitalRead(b3);
  byte button4Value = digitalRead(b4);

You realize these are different variables, right? [/quote]

yes... whats wrong with that? ive used them to be able to select the number of blinks per interval of seconds....

I want to make the void loop () empty, but the code that was in it, the switch case and other stuff, to be integrated into a timer...

try this:

http://lmgtfy.com/?q=arduino+timers

arduinodlb: try this:

http://lmgtfy.com/?q=arduino+timers

You are not helping me. First of all: i have never used interrupts on arduino... i do not understand how they work. help me and provide me a sketch or something...

i have never used interrupts on arduino...

Read this discussion and examples: http://www.gammon.com.au/interrupts .

I am being a great help to you telling you that you will have to learn how to use a search engine like google.

You are very welcome if you have specific questions or problems you need help with, but you do not tell people that they "provide you a sketch or something". Especially not if you're doing homework.

//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 ledTV = 9;
int ledDVD = 8;
int ledCD = 7;
int ledRAD = 6;
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);
}

ISR (TIMER1_COMPA_vect)
{
  int Q = 1;
  
  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(ledTV, LOW);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, LOW);
      if(digitalRead(b5)==HIGH)
        Q=1;
      blinkpv(ledpv, 0, 4000);
    break;
    
    case 3:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledTV, LOW);
      digitalWrite(ledCD, HIGH);
      digitalWrite(ledDVD, LOW);
      if(digitalRead(b5)==HIGH)
        Q=1;
      blinkpv(ledpv, 0, 4000);
    break;
    
    case 4:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledTV, LOW);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, HIGH);
      if(digitalRead(b5)==HIGH)
        Q=1;
      blinkpv(ledpv, 0, 4000);
    break;
    
    case 5:
      digitalWrite(ledRAD, LOW);
      digitalWrite(ledTV, HIGH);
      digitalWrite(ledCD, LOW);
      digitalWrite(ledDVD, LOW);
      if(digitalRead(b5)==HIGH)
        Q=1;
      blinkpv(ledpv, 0, 4000);
    break;
  }
}

void loop() {}

void blinkpv(int led, int count, int seconds)
{
  byte button1Value = digitalRead(b1);
  byte button2Value = digitalRead(b2);
  byte button3Value = digitalRead(b3);
  byte button4Value = digitalRead(b4);
  int blinkrepeats;
  if (button1Value == LOW && lastButton1Value == HIGH)
    blinkRepeats = 1;
  else 
    if (button2Value == LOW && lastButton2Value == HIGH) 
      blinkRepeats = 2;
      else 
        if (button3Value == LOW && lastButton3Value == HIGH) 
          blinkRepeats = 3;
        else 
          if (button4Value == LOW && lastButton4Value == HIGH) 
            blinkRepeats = 4;
  lastButton1Value = button1Value;
  lastButton2Value = button2Value;
  lastButton3Value = button3Value;
  lastButton4Value = button4Value;
  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;
}

Is this correct?! I do not have the breadboard / leds / buttons… Do you think it will work?!

ISR (TIMER1_COMPA_vect)
{
  int Q = 1;

  switch (Q)
  {
    case 1:

Every time the ISR is called then Q will be set to 1 and case 1 will be executed. How are the other cases ever going to be executed ?

Xeyow:
You are not helping me. First of all: i have never used interrupts on arduino… i do not understand how they work. help me and provide me a sketch or something…

Actually, I am helping you. The first link that is displayed EXPLAINS in great detail the TIMER1 system on Arduinos, and how to use the interrupts associated with timers. Read it. And learn how to use google.

Don’t be lazy. Do the research and learn. That is the point of your homework. We will not do your homework for you, but we will help you when you get stuck. But, you have to put in some effort yourself.

Xeyow: i do not understand how they work. help me and provide me a sketch or something...

Do my homework for me? Is that it?

UKHeliBob: ``` ISR (TIMER1_COMPA_vect) {   int Q = 1;

  switch (Q)   {     case 1:



Every time the ISR is called then Q will be set to 1 and case 1 will be executed. How are the other cases ever going to be executed ?

Yup... i think int Q=1, should be declared global, right?!

Xeyow: Yup... i think int Q=1, should be declared global, right?!

or you could declare it inside your function as static. It would have the same effect as declaring it global, but only things executing inside your function could access it (local visibility).

ISR (TIMER1_COMPA_vect)
{
  static int Q = 1;

  Q++;
  Serial.print(Q); // would show Q increasing each time the ISR is executed
...
}

i will try to upload the code on my arduino and see if the button/leds are working. Hope it works.

arduinodlb: or you could declare it inside your function as static. It would have the same effect as declaring it global, but only things executing inside your function could access it (local visibility).

ISR (TIMER1_COMPA_vect)
{
  static int Q = 1;

 Q++;  Serial.print(Q); // would show Q increasing each time the ISQ is executed ... }

Don't do serial prints inside an ISR.

http://www.gammon.com.au/interrupts

arduinodlb God Member Posts: 897

Don't even suggest it.

I didn't intend that he should run that code. I was merely trying to demonstrate what would happen to Q, but I take your point.

Oke, so my code works untill the point of blinkpv function. Lets say Q=1; I press button 1 => q=2. i turn led2 ON, but the function blinkpv, doesnt work…