Arduino interupts

I recently Made A Gps Based Arduino Clock Using Some Old Seven Segment Displays And Some 7447 Drivers I Have The Hour Pair Of Displays And Minute Pair Connected To The Same 7447s And The Displays Multiplexed Together I have Working code but every time the gps updates over serial the displays flickers slightly and its just barely visible and its just enough drive my ocd up a wall so i thought why not kill two birds with one stone and ask for some help setting up a interrupt to do this. I have goggled it before however none of the things I read helped. so i thought why don’t I ask the experts on the arduino forums.

lcd_7447.ino (6.5 KB)

I’m sTARTING tO gEt boRed wiTh poSting othEr peOple’s codE For theM.

/*
  22-02-2013
  This program uses the 7447 IC chip to display the number 0 to 9
  on a 7-segment-led. The 7447 IC chip is quite similar to the 
  7448 IC chip except the pins #9 to #15 will be active-LOW. This 
  will allow current to flow into chip toward the ground.  
 
  But a more important thing is that this BCD decoder chip not 
  only reduces the number of digital output pins needed but it 
  also simplify the C-programming of the source code.
  
  The 7447 is a 16 pin DIL IC chip. The pin connections are as
  follow:
  
  #1(B) --> pin 3 of Arduino
  #2(C) --> pin 4 of Arduino
  #3(LT')--> HIGH (5V) [connect to 0V to test]
  #4(BI/RBO') --> HIGH (5V) [connect to 0V to disenable]
  #5(RBI') --> X
  #6(D) --> pin 5 of Arduino
  #7(A) --> pin 2 of Arduino
  #8(Gnd) --> 0V
 
  #9(e) --> segment 'e' of LED
  #10(d) --> segment 'd' 
  #11(c) --> segment 'c'
  #12(b) --> segment 'b'
  #13(a) --> segment 'a'
  #14(g) --> segment 'g'
  #15(f) --> segment 'f'
 
 To simplify the wiring connection, a common resistor of ~330 ohm
 may be connected between the supply voltage and the +5V terminal 
 of 7-segment LED (common anode type). See wiring circuit below. 
 
 Alternative, you may connect each resistor for each of the seven
 segments of the LED. With this type of connection, the brightness
 of the lighted segments will be even. 
 
 Note: With 4 bits (A,B,C,D), it is possible to display the number 
 0 to 15. However, numbers above 9 will be displayed  using 
 special symbols. You can test this out yourself.
 
*/
#include <TinyGPS++.h>
//declaration
int pin0 = 2; // bit-1 connected to pin 2 of Arduino
int pin1 = 3; // bit-2 connected to pin 3 of Arduino
int pin2 = 4; // bit-3 connected to pin 4 of Arduino
int pin3 = 5; // bit-4 connected to pin 5 of Arduino
int pin0l = 7; // bit-1 connected to pin 2 of Arduino
int pin1l = 8; // bit-2 connected to pin 3 of Arduino
int pin2l = 9; // bit-3 connected to pin 4 of Arduino
int pin3l = 10; // bit-4 connected to pin 5 of Arduino
int led = 11;
int ld = 6;
int rd = 12;
int x = 0;
int d1;
int d2;
int h = 88;
int s = 88;
void displayled(int val) {
  d1 = val / 10;
  d2 = val % 10;
  if (d1 == 0) {
    d1 = 10;
  }
  dip1(d1);
  dip2(d2);
}
void updatedisp() {
  if (x==1) {
    x=0;
    doff();
    displayled(h);
    ldon();
  }
  else {
    x=1;
    doff();
    displayled(s);
    rdon();
  }
}
void dip2(int var) {
  if(var==0) {
    digitalWrite(pin0,LOW);
    digitalWrite(pin1,LOW);
    digitalWrite(pin2,LOW);
    digitalWrite(pin3,LOW);  // 1=(0,0,0,1)
  }
  if(var==1) {
    digitalWrite(pin0,HIGH);
    digitalWrite(pin1,LOW);
    digitalWrite(pin2,LOW);
    digitalWrite(pin3,LOW);  // 1=(0,0,0,1)
  }
  if(var==2) {
    digitalWrite(pin0,LOW);
    digitalWrite(pin1,HIGH);
    digitalWrite(pin2,LOW);
    digitalWrite(pin3,LOW);  // 2=(0,0,1,0)
  }
  if(var==3) {
    digitalWrite(pin0,HIGH);
    digitalWrite(pin1,HIGH);
    digitalWrite(pin2,LOW);
    digitalWrite(pin3,LOW);  // 3=(0,0,1,1)
  }
  if(var==4) {
  digitalWrite(pin0,LOW);
  digitalWrite(pin1,LOW);
  digitalWrite(pin2,HIGH);
  digitalWrite(pin3,LOW);  //4=(0,1,0,0)
  }
  if(var==5) {
    digitalWrite(pin0,HIGH);
    digitalWrite(pin1,LOW);
    digitalWrite(pin2,HIGH);
    digitalWrite(pin3,LOW);  // 5=(0,1,0,1)
  }
  if(var==6) {
    digitalWrite(pin0,LOW);
    digitalWrite(pin1,HIGH);
    digitalWrite(pin2,HIGH);
    digitalWrite(pin3,LOW);  //6=(0,1,1,0)
  }
  if(var==7) {
    digitalWrite(pin0,HIGH);
    digitalWrite(pin1,HIGH);
    digitalWrite(pin2,HIGH);
    digitalWrite(pin3,LOW);  // 7=(0,1,1,1)
  }
  if(var==8) {
    digitalWrite(pin0,LOW);
    digitalWrite(pin1,LOW);
    digitalWrite(pin2,LOW);
    digitalWrite(pin3,HIGH);  // 8=(1,0,0,0)
  }
  if(var==9) {
    digitalWrite(pin0,HIGH);
    digitalWrite(pin1,LOW);
    digitalWrite(pin2,LOW);
    digitalWrite(pin3,HIGH);  // 9=(1,0,0,1)
  }
  if(var==10) {
    digitalWrite(pin0,HIGH);
    digitalWrite(pin1,HIGH);
    digitalWrite(pin2,HIGH);
    digitalWrite(pin3,HIGH);  // 1=(0,0,0,1)
  }
}
void dip1(int var) {
  if(var==0) {
    digitalWrite(pin0l,LOW);
    digitalWrite(pin1l,LOW);
    digitalWrite(pin2l,LOW);
    digitalWrite(pin3l,LOW);  // 1=(0,0,0,1)
  }
  if(var==1) {
    digitalWrite(pin0l,HIGH);
    digitalWrite(pin1l,LOW);
    digitalWrite(pin2l,LOW);
    digitalWrite(pin3l,LOW);  // 1=(0,0,0,1)
  }
  if(var==2) {
    digitalWrite(pin0l,LOW);
    digitalWrite(pin1l,HIGH);
    digitalWrite(pin2l,LOW);
    digitalWrite(pin3l,LOW);  // 2=(0,0,1,0)
  }
  if(var==3) {
    digitalWrite(pin0l,HIGH);
    digitalWrite(pin1l,HIGH);
    digitalWrite(pin2l,LOW);
    digitalWrite(pin3l,LOW);  // 3=(0,0,1,1)
  }
  if(var==4) {
  digitalWrite(pin0l,LOW);
  digitalWrite(pin1l,LOW);
  digitalWrite(pin2l,HIGH);
  digitalWrite(pin3l,LOW);  //4=(0,1,0,0)
  }
  if(var==5) {
    digitalWrite(pin0l,HIGH);
    digitalWrite(pin1l,LOW);
    digitalWrite(pin2l,HIGH);
    digitalWrite(pin3l,LOW);  // 5=(0,1,0,1)
  }
  if(var==6) {
    digitalWrite(pin0l,LOW);
    digitalWrite(pin1l,HIGH);
    digitalWrite(pin2l,HIGH);
    digitalWrite(pin3l,LOW);  //6=(0,1,1,0)
  }
  if(var==7) {
    digitalWrite(pin0l,HIGH);
    digitalWrite(pin1l,HIGH);
    digitalWrite(pin2l,HIGH);
    digitalWrite(pin3l,LOW);  // 7=(0,1,1,1)
  }
  if(var==8) {
    digitalWrite(pin0l,LOW);
    digitalWrite(pin1l,LOW);
    digitalWrite(pin2l,LOW);
    digitalWrite(pin3l,HIGH);  // 8=(1,0,0,0)
  }
  if(var==9) {
    digitalWrite(pin0l,HIGH);
    digitalWrite(pin1l,LOW);
    digitalWrite(pin2l,LOW);
    digitalWrite(pin3l,HIGH);  // 9=(1,0,0,1)
  }
  if(var==10) {
    digitalWrite(pin0l,HIGH);
    digitalWrite(pin1l,HIGH);
    digitalWrite(pin2l,HIGH);
    digitalWrite(pin3l,HIGH);  // 1=(0,0,0,1)
  }
}
TinyGPSPlus gps;
void setup()
{                
 pinMode(pin0, OUTPUT);  
 pinMode(pin1, OUTPUT);  
 pinMode(pin2, OUTPUT);  
 pinMode(pin3, OUTPUT);  
 pinMode(pin0l, OUTPUT);  
 pinMode(pin1l, OUTPUT);  
 pinMode(pin2l, OUTPUT);  
 pinMode(pin3l, OUTPUT); 
 pinMode(led, OUTPUT); 
 pinMode(ld, OUTPUT);
 pinMode(rd, OUTPUT);
 digitalWrite(ld, HIGH);
 digitalWrite(rd, HIGH);
 Serial.begin(9600);
}
void ldon() {
 digitalWrite(rd, LOW);
 digitalWrite(ld, HIGH);
}
void rdon() {
 digitalWrite(ld, LOW);
 digitalWrite(rd, HIGH);
}
void doff() {
 digitalWrite(rd, LOW);
 digitalWrite(ld, LOW);
}
void loop()
{
  if (Serial.available()) {
    gps.encode(Serial.read());
  }
if (gps.time.isValid())
  {
    h = gps.time.hour();
    h = h - 5; // TimeZone Setup
    if (h >= 13) {
      h = h - 12;
      digitalWrite(led, HIGH);
    }
    else {
      digitalWrite(led, LOW);
    }
    s = gps.time.minute();
  }
  else {
  }
  updatedisp();
}

I can't see how interrupts would solve the problem.
And a good rule of thumb is that, if you have to ask how, you should not use interrupts. They are not easy to debug.

Perhaps you can reorganize your program logic so that only the digits that need to change do so. That way the Arduino does not waste time where it is not needed and the unchanged digits won't flicker.

Another thought is that you may be using the doff() function rather too liberally.

And put some white space between your functions to make the code easier to read.

...R

I had to do a project a few years ago that needed to control about 8 four digit displays, (this was pc based not arduino) , I was going to multiplex them but ran into flicker problems, in the end I used a shift register with latched outputs

you simply clock the data in and the outputs stay at that state until new data arrives, in your project you would only have to update the displays once a second (assuming it displays seconds) or once a min.

If I remember correctly I used a common clock line and used the CS (chip select) pin to address each digit

something like 74HC595 would work ok

There are some multi 7 segment boards out now with onboard multiplexer/drivers. Some are I2C, some have a custom clocked serial interface. I have two on order now, can't wait to play with them. With these, there is no problem with flicker unless they're written improperly. They're also quite inexpensive. Basically cost no more than a simple shield. Fewer wires too.

Robin2:
I can't see how interrupts would solve the problem.

I can. But the ISR would have to be very optimized, so not to interfere with the serial used for GPS, and whatever else. If you have a periodic interrupt (timer driven) updating the 7 segment display, there should be no flicker. I wrote one once, driven from the NMI of an MC6802. In that case, the NMI was actually connected to a 60Hz square wave.