Interrupt

I have a trouble with my interrupt, I have got a code so long for my interrupt, I have to lit two 7 seg, and for that I use a swiitch with 99 cases. I have been trying to send argument to the interrupt function, but It seems that It doesnt work, I dont know If I can send arguments to that function, and by the way, will there be any way to reduce an interrupt function.

Thanks!!!

Post your code in code tags.

Winsu:
I have a trouble with my interrupt, I have got a code so long for my interrupt, I have to lit two 7 seg, and for that I use a swiitch with 99 cases. I have been trying to send argument to the interrupt function, but It seems that It doesnt work, I dont know If I can send arguments to that function, and by the way, will there be any way to reduce an interrupt function.

Thanks!!!

  • We need to see your code to tell what's wrong.
  • You cannot send parameters to an ISR (interrupt service routine).
  • The ISR gets and sends it's data to external volatile variables.
  • The ISR must be able to finish before it gets called again, else you will underflow the stack.
  • Running a 7 segment display with 99 switch cases sounds inherently wrong.

I have to lit two 7 seg, and for that I use a swiitch with 99 cases

Maybe a lookup table would help.
Or
Some kind of jump table.

Please show us your sketch, attach it with the <> button icon in the menu.

I dont know how to put the code with the meaning of leave it like It was on the arduino IDE, but I'm going to put just the interrupt function:

SR(TIMER1_COMPA_vect){//timer1 interrupt 1Hz toggles pin 13 (LED)
//generates pulse wave of frequency 1Hz/2 = 0.5kHz (takes two cycles for full wave- toggle high then toggle low)
int Lux;
Lux = BH1750_Read();
switch(Lux){
case 0:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[0]); // digitTwo //~ It means not, so It's like that due to 7 seg are common anode
shiftOut(DATA, CLK, MSBFIRST, digitOne[0]); // digitOne //My 7 seg are common catedo so I remove this ~
digitalWrite(LATCH, HIGH);
break;
case 1:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[1]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[0]);
digitalWrite(LATCH, HIGH);
break;
case 2:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[2]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[0]);
digitalWrite(LATCH, HIGH);
break;
case 3:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[3]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[0]);
digitalWrite(LATCH, HIGH);
break;
case 4:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[4]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[0]);
digitalWrite(LATCH, HIGH);
break;
case 5:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[5]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[0]);
digitalWrite(LATCH, HIGH);
break;
case 6:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[6]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[0]);
digitalWrite(LATCH, HIGH);
break;
case 7:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[7]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[0]);
digitalWrite(LATCH, HIGH);
break;
case 8:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[8]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[0]);
digitalWrite(LATCH, HIGH);
break;
case 9:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[9]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[0]);
digitalWrite(LATCH, HIGH);
break;
case 10:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[0]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[1]);
digitalWrite(LATCH, HIGH);
break;
digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[1]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[1]);
digitalWrite(LATCH, HIGH);
break;
case 12:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[2]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[1]);
digitalWrite(LATCH, HIGH);
break;
case 13:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[3]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[1]);
digitalWrite(LATCH, HIGH);
break;
case 14:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[4]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[1]);
digitalWrite(LATCH, HIGH);
break;
case 15:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[5]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[1]);
digitalWrite(LATCH, HIGH);
break;
case 16:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[6]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[1]);
digitalWrite(LATCH, HIGH);
break;
case 17:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[7]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[1]);
digitalWrite(LATCH, HIGH);
break;
case 88:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[8]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[8]);
digitalWrite(LATCH, HIGH);
break;

case 89:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[9]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[8]);
digitalWrite(LATCH, HIGH);
break;
case 90:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[0]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[9]);
digitalWrite(LATCH, HIGH);
break;
case 91:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[1]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[9]);
digitalWrite(LATCH, HIGH);
break;
case 92:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[2]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[9]);
digitalWrite(LATCH, HIGH);
break;
case 93:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[3]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[9]);
digitalWrite(LATCH, HIGH);
break;
case 94:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[4]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[9]);
digitalWrite(LATCH, HIGH);
break;
case 95:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[5]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[9]);
digitalWrite(LATCH, HIGH);
break;
case 96:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[6]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[9]);
digitalWrite(LATCH, HIGH);
break;
case 97:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[7]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[9]);
digitalWrite(LATCH, HIGH);
break;
case 98:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[8]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[9]);
digitalWrite(LATCH, HIGH);
break;
case 99:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[9]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[9]);
digitalWrite(LATCH, HIGH);
break;

}

It must lit two 7 segments, from 00 to 99, so 100 cases in total.I know It is so long besides that I have to red a sensor light, because that is the information I want to show on the two 7 segments.If I can not pass

Some very, very simple arithmetic would shorten that whole lot into about ten lines of code.

I'm going to set a very bad example for the sake of highlighting your problem, but please use code tags when posting code.

case 99:digitalWrite(LATCH, LOW);
shiftOut(DATA, CLK, MSBFIRST, digitTwo[9]);
shiftOut(DATA, CLK, MSBFIRST, digitOne[9]);
digitalWrite(LATCH, HIGH);
break;

How can I use code tags??, I think I have resolved my trouble and I would like to show it...I mean, I have make smaller the interrupt but It still doesnt work ...

Sorry, but or I need to go to the eye doctor or It's kidding me...I dont know yet where the smileys is and everything...sorrty for being tiresome...

#include "Wire.h"


#define LATCH 8        //latch of 74HC595
#define CLK 12          //clock of 74HC595
#define DATA 11 

byte digitOne[10]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x67};//It's anode common
byte digitTwo[10]= {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x98};//It's catode common

int BH1750_Device = 0x23;
int Lux;
int LedPin1 = 3;
int LedPin2 = 5;

void setup(){
  pinMode(LedPin1,OUTPUT);
  pinMode(LedPin2,OUTPUT);

  Wire.begin();
  Serial.begin(9600);
  configure_BH1750();
  //set timer1 interrupt at 1Hz
 cli();
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  OCR1A = 31248;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS12 and CS10 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);  
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  sei();
}

void loop(){
  
   Lux = BH1750_Read();
   Serial.print("measurement in lux:");
   Serial.print(Lux);
   analogWrite(LedPin1,Lux);
   analogWrite(LedPin2,Lux);
     
     
}

  int BH1750_Read()
{
  unsigned int i=0;
  Wire.beginTransmission(BH1750_Device);
  Wire.requestFrom(BH1750_Device, 2);
  while(Wire.available())
  {
    i <<=8;
    i|= Wire.read();
  }
  Wire.endTransmission();
  return i/1.2; // Convert to Lux
  
}

void configure_BH1750()
{
  Wire.beginTransmission(BH1750_Device);
  Wire.write(0x13);        //set resolution to 1 lux  countinouosly H-resolution mode,each 120ms make a measure
  Wire.endTransmission();
}

ISR(TIMER1_COMPA_vect){//timer1 interrupt 1Hz toggles pin 13 (LED)
//generates pulse wave of frequency 1Hz/2 = 0.5kHz (takes two cycles for full wave- toggle high then toggle low)
     int Lux,a,b;
     Lux = BH1750_Read();
     if(Lux>9){
       a = 0;
       b = Lux;
     }
      else{
        b = Lux/10;
        a = Lux - (b*10);
      }
     digitalWrite(LATCH, LOW);
     shiftOut(DATA, CLK, MSBFIRST, digitTwo[b]);      // digitTwo      //~ It means not, so It's like that due to 7 seg are common anode
     shiftOut(DATA, CLK, MSBFIRST, digitOne[a]);      // digitOne      //My 7 seg are common catedo so I remove this ~
     digitalWrite(LATCH, HIGH);
            
  

}

I'm using a two 7 segments with two 74HC595 to lit the 7 segments...I have a sensor light which is working and each two seconds I have set an interrupt, the interrupt must read the sensor and lit the 7 seg, but It looks like is crashing my program.I thing two seconds is enough, so I dont know what can be happening..

Thanks!!!

I think that is not the problem, when you use 74HC595 you must fristly send the digit with less valour(unit) and later the biggest valour(ten), It is like that because the digit are pushing themselves until get the right position.

so If I get 9 from the sensor I represent 09, if I get 56 from the sensor I represent 56 and the order in both cases would be:for 9 I send first 9 and after 0, and for 56 I sent 6 and later 5.

My problem is when I use the same program but I just lit a led with any pinout I works properly, but when I use this, my program doesnt work

Actually I'm not trying to blink a led, It's just a test.what I want to do is lit led strip according to a sensor light.So When It get dark the brightness gets dark(with PWM), I have tryed to use timer one because It has a libraty which makes bigger the range of PWM(until1025), but timer 1 is good to do a interrupt because It has a bigger pre-escalar.So I have got timer 1 to set an interrupt and PWM 3 and 5, to lit the led strips.

The trouble is If I'm reading permanently the sensor light and with that valour I attach the 7 segments, they keep bouncing, and It's good for the LED strip(being reading for the sensor permanently), but for the 7 seg I wnat to avoid that bounce.

Any idea o suggestions.Maybe I could sor it out without use a interrupt...

but for now I cant imagine other way, and my interrupt musy use a ruotine to read the sensor light, I hope you know a simpler way..

Yes you're right about the number....I should have right if(lux < 10){....

Thanks!!!

#include "Wire.h"
#define LATCH 8        //latch of 74HC595
#define CLK 12          //clock of 74HC595
#define DATA 11 

byte digitOne[10]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x67};//It's anode common
byte digitTwo[10]= {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x98};//It's catode common

int BH1750_Device = 0x23;
int Lux;
int LedPin1 = 3;
int LedPin2 = 5;
boolean toggle1 = 0;

void setup(){
  pinMode(LedPin1,OUTPUT);
  pinMode(LedPin2,OUTPUT);
  pinMode(13,OUTPUT);

  Wire.begin();
  Serial.begin(9600);
  configure_BH1750();
  //set timer1 interrupt at 1Hz
 cli();
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  OCR1A = 31248;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS12 and CS10 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);  
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  sei();
}

void loop(){
  
   Lux = BH1750_Read();
   Serial.print("measurement in lux:");
   Serial.print(Lux);
   analogWrite(LedPin1,Lux);
   analogWrite(LedPin2,Lux);
     
     
}

  int BH1750_Read()
{
  unsigned int i=0;
  Wire.beginTransmission(BH1750_Device);
  Wire.requestFrom(BH1750_Device, 2);
  while(Wire.available())
  {
    i <<=8;
    i|= Wire.read();
  }
  Wire.endTransmission();
  return i/1.2; // Convert to Lux
  
}

void configure_BH1750()
{
  Wire.beginTransmission(BH1750_Device);
  Wire.write(0x13);        //set resolution to 1 lux  countinouosly H-resolution mode,each 120ms make a measure
  Wire.endTransmission();
}

ISR(TIMER1_COMPA_vect){//timer1 interrupt 1Hz toggles pin 13 (LED)
//generates pulse wave of frequency 1Hz/2 = 0.5kHz (takes two cycles for full wave- toggle high then toggle low)
          // if (toggle1){
    //digitalWrite(13,HIGH);
    //toggle1 = 0;
  //}
  //else{
    //digitalWrite(13,LOW);
    //toggle1 = 1;
  //} 
      int Lux,a,b;
     Lux = BH1750_Read();
     if(Lux < 10){
       a = 0;
       b = Lux;
     }
      else{
        b = Lux/10;
        a = Lux - (b*10);
      }
     digitalWrite(LATCH, LOW);
     shiftOut(DATA, CLK, MSBFIRST, digitTwo[b]);      // digitTwo      //~ It means not, so It's like that due to 7 seg are common anode
     shiftOut(DATA, CLK, MSBFIRST, digitOne[a]);      // digitOne      //My 7 seg are common catedo so I remove this ~
     digitalWrite(LATCH, HIGH);
     
  

}

That's my whole code....probably I'm trying to use a table to pin a nail when I should use a hammer...a proper tool....could you explain me how you would do it with milles() function..

Thanks!!!

Maybe I could use a millis to count and when It counts a multiple of 2 seconds, the programm allows to change the display??, but I dont know if the programm should go where that instruction is at the same time millis counts a multiple of 2 seconds..

Ok, I'm doing it right now, you have adressed me in the right direction, thanks!!

Winsu:
I dont know how to put the code with the meaning of leave it like It was on the arduino IDE, but I'm going to put just the interrupt function:

The code in your ISR is way too complex. You should do all your calculations and decisions outside the ISR and simply let the ISR do simple updates.

Here are pieces of code I wrote to drive a 4 digit seven segment display which should give you enough ideas to proceed with writing better code:

// PORTC (digits & dp)
#define DIG_0 _BV(0)
#define DIG_1 _BV(1)
#define DIG_2 _BV(2)
#define DIG_3 _BV(3)
#define COLON_A _BV(4)
#define SEG_DP _BV(5)

// PORT D (segments)
#define SEG_A  _BV(1) // LED segments
#define SEG_B  _BV(2)
#define SEG_C  _BV(3)
#define SEG_D  _BV(4)
#define SEG_E  _BV(5)
#define SEG_F  _BV(6)
#define SEG_G  _BV(7)

// seven segment bit patterns, no DP
#define SEGS_0 ~(SEG_A|SEG_B|SEG_C|SEG_D|SEG_E|SEG_F)
#define SEGS_1 ~(SEG_B|SEG_C)
#define SEGS_2 ~(SEG_A|SEG_B|SEG_D|SEG_E|SEG_G)
#define SEGS_3 ~(SEG_A|SEG_B|SEG_C|SEG_D|SEG_G)
#define SEGS_4 ~(SEG_B|SEG_C|SEG_F|SEG_G)
#define SEGS_5 ~(SEG_A|SEG_C|SEG_D|SEG_F|SEG_G)
#define SEGS_6 ~(SEG_A|SEG_C|SEG_D|SEG_E|SEG_F|SEG_G)
#define SEGS_7 ~(SEG_A|SEG_B|SEG_C)
#define SEGS_8 ~(SEG_A|SEG_B|SEG_C|SEG_D|SEG_E|SEG_F|SEG_G)
#define SEGS_9 ~(SEG_A|SEG_B|SEG_C|SEG_D|SEG_F|SEG_G)
#define SEGS_OFF ~(SEG_A|SEG_B|SEG_C|SEG_D|SEG_E|SEG_F|SEG_G)

// we keep each number on for "N" * brite where "N" is the number
// of segments lit so that each number is the same brightness.
inline void display (int8_t digit, int8_t number)
{
    PORTC |= (_BV (digit) | ((digit == 1) ? 0 : SEG_DP)); // turn on the correct digit & d-point

    switch (number) {
        case -1:
            PORTD = (uint8_t) SEGS_OFF;
            break;
        case 0:
            PORTD = (uint8_t) SEGS_0;
            _delay_us (6 * brite);
            break;
        case 1:
            PORTD = (uint8_t) SEGS_1;
            _delay_us (2 * brite);
            break;
        case 2:
            PORTD = (uint8_t) SEGS_2;
            _delay_us (5 * brite);
            break;
        case 3:
            PORTD = (uint8_t) SEGS_3;
            _delay_us (5 * brite);
            break;
        case 4:
            PORTD = (uint8_t) SEGS_4;
            _delay_us (5 * brite);
            break;
        case 5:
            PORTD = (uint8_t) SEGS_5;
            _delay_us (5 * brite);
            break;
        case 6:
            PORTD = (uint8_t) SEGS_6;
            _delay_us (6 * brite);
            break;
        case 7:
            PORTD = (uint8_t) SEGS_7;
            _delay_us (3 * brite);
            break;
        case 8:
            PORTD = (uint8_t) SEGS_8;
            _delay_us (7 * brite);
            break;
        case 9:
            PORTD = (uint8_t) SEGS_9;
            _delay_us (6 * brite);
            break;
        default:
            break;
    }
    PORTC &= ~(DIG_0 | DIG_1 | DIG_2 | DIG_3 | SEG_DP); // turn off digits & dp
}

ISR (TIMER1_COMPA_vect)
{
    display (0, val[3]); // most significant digit first of course!
    display (1, val[2]);
    display (2, val[1]);
    display (3, val[0]);
}


////// this is inside the main() loop /////////
////// converts "v" into 4 discrete uint8_t values, each 0-9
    volatile uint8_t val[4];
    v = readAnalog (6, 1000); // port 6, average 1000 readings
    x = 4; // digit count
    y = 1000;
    while (x--) {
        val[x] = (v / y);
        v -= (val[x] * y);
        y /= 10;
    }
//////

Now, I didn't show the hardware initialization and other code... the idea is to show you how to select the proper segments and then use the ISR to do the MINIMUM amount of work (i.e. the least amount of CPU cycles).

Hope this helps.

Winsu, your code is basically OK. Please read your private message (PM) (icon with "head" ) on task / status bar on top right.