problem with 7 seg led display

I'm using four 8 digit 7 seg displays with the ledcontrol driver from here LedControl on a Mega 2560.

I'm experiencing a strange problem and I hope some guru may be able to shed some light on this.

The displays get updated at various frequencies which vary from several times a second to once every few minutes depending upon external triggers.

What I'm experiencing is that occasionally when one (and it could be any one of the 4) of the 7 seg displays is to updated it goes blank and stays blank until a board reset. This may happen several times over a few minutes or may not happen for several days. It is not a cable issue. The cables have been tested many times and several times replaced with no effect - the problem persists. The really interesting fact is that this behavior doesn't happen on my Uno - only on the Mega (using the same displays, cable, drivers etc).

I'm wondering if this is a timing issue with the drivers with the faster Mega?

I would be grateful for any ideas please.

I'm wondering if this is a timing issue with the drivers with the faster Mega?

I would be grateful for any ideas please.

Try the code at line 23.

Failing that post your code.

Line 23 of what?

This is my code.

#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
#include "LedControl.h"
#include <stdio.h>

const int maxled = 4;

struct Ledctl {
  int DataIn;
  int Load;
  int Clk;
} ltl[maxled] = { {22, 23, 24},     //led 0
                  {26, 27, 28},     //led 1
                  {30, 31, 32},     //led 2
                  {34, 35, 36}};    //led 3

const char inind[] = "UGE1";

//Interrupt ports
const int gen = 2;      //int 0
const int expt = 3;     //int 1
const int impt = 19;    //int 4
const int land = 18;    //int 5

//Ports used
const int led = 13;

//LCD ports
const int RS = 4;
const int EN = 5;
const int D4 = 6;
const int D5 = 7;
const int D6 = 8;
const int D7 = 9;

//Constants
const unsigned int   baud = 57600;             //Baud rate
const unsigned long  interval = 5 * 60000;     //5 minute
const unsigned long  omin = 60000;             //1 minute
const unsigned long  daint = 5000;             //5 seconds
const unsigned int   mintim = 300;             //minimum interval between pulses eqv 12kw
const unsigned int   tdelta = 2500;            //time interval to update usage if no pulse received
const unsigned long  maxint = 4000000;         //max time interval for 0
const unsigned int   intensity = 1;
const unsigned int   led_delay = 20;

//Commands
const char DISCON  = 'c';    //c - display on console
const char SAVE    = 'f';    //f - save data to file
const char DATA    = 'd';    //d - data to Data buff
const char LOG     = 'l';    //l - log output
const char TIME    = 't';    //t - set date/time

//Global devices
LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);

RTC_DS1307 RTC;

LedControl seg0 = LedControl(ltl[0].DataIn, ltl[0].Clk, ltl[0].Load, 1);
LedControl seg1 = LedControl(ltl[1].DataIn, ltl[1].Clk, ltl[1].Load, 1);
LedControl seg2 = LedControl(ltl[2].DataIn, ltl[2].Clk, ltl[2].Load, 1);
LedControl seg3 = LedControl(ltl[3].DataIn, ltl[3].Clk, ltl[3].Load, 1);

LedControl *seg7[maxled] = {&seg0, &seg1, &seg2, &seg3};

//usage
float fg = 0.0;
float fe = 0.0;
float fi = 0.0;
float fl = 0.0;
float fu = 0.0;

//Used by interrupt so need volatile

//5 minute counts
volatile unsigned int gcnt = 0;
volatile unsigned int ecnt = 0;
volatile unsigned int icnt = 0;
volatile unsigned int lcnt = 0;

//5 second counts
volatile unsigned int gdat = 0;
volatile unsigned int edat = 0;
volatile unsigned int idat = 0;
volatile unsigned int ldat = 0;

//Time between pulses
volatile unsigned long gtim = 0;
volatile unsigned long etim = 0;
volatile unsigned long itim = 0;
volatile unsigned long ltim = 0;

//Last pulse time
volatile unsigned long glast = 0;
volatile unsigned long elast = 0;
volatile unsigned long ilast = 0;
volatile unsigned long llast = 0;

//Set when pulse received
volatile boolean gb = false;
volatile boolean eb = false;
volatile boolean ib = false;
volatile boolean lb = false;

volatile unsigned long gtot = 0;
volatile unsigned long etot = 0;
volatile unsigned long itot = 0;
volatile unsigned long ltot = 0;

volatile int ledstat = LOW;

//For 5 min file log
char output[50];
volatile boolean putout = false;

// the setup routine runs once when you press reset:
void setup()
{
char str[20];

char *out;
  
  Serial.begin(baud);
  Wire.begin();
  RTC.begin();
  lcd.begin(20, 4);
  
  if (!RTC.isrunning()) {
    Serial.print(LOG);
    Serial.println("RTC is NOT running!");
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  
  Serial.print(LOG);
  Serial.print("Reset at ");
  out = displayDateTime(str);
  *(out - 1) = 0;    //Remove trailing ,
  Serial.println(str);
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.write("rst");
  str[10] = ' ';
  lcd.setCursor(4, 0);
  lcd.write(str);
  
  onemin();
  
  //Set constant display chars  
  lcd.setCursor(0, 2);
  lcd.write('G');
  lcd.setCursor(11, 2);
  lcd.write ('E');
  lcd.setCursor(0, 3);
  lcd.write('I');
  lcd.setCursor(11, 3);
  lcd.write ('U');
  
  //Set LEDs
  for (int l = 0; l < maxled; l++) {
    initled(l);
  }
  
  //Initialize pins used
  pinMode (led, OUTPUT);
  pinMode (gen, INPUT_PULLUP);
  pinMode (expt, INPUT_PULLUP);
  pinMode (impt, INPUT_PULLUP);
  pinMode (land, INPUT_PULLUP);
  
  //Set interrupts
  attachInterrupt(0, gen_int, RISING);
  attachInterrupt(1, expt_int, RISING);
  attachInterrupt(4, imp_int, RISING);
  attachInterrupt(5, land_int, RISING);
  
  digitalWrite(led, ledstat);
  
  glast = elast = ilast = llast = millis();

  writeArduinoOn7Segment();
  delay(500);
}

// the loop routine runs over and over again forever:
void loop()
{
static unsigned long period = millis();
static unsigned long intv = millis();
static unsigned long minint = millis();
static int tries = 0;

static unsigned long uold = 0;

//5 second output
  if ((millis() - intv) >= daint) {
    intv = millis();
    sec5();   
     
    ledstat = (ledstat == HIGH) ? LOW : HIGH;
    digitalWrite(led, ledstat);   // turn the LED on (HIGH is the voltage level)
  }
  
//1 minute update
  if ((millis() - minint) >= omin) {
    minint = millis();
    onemin();
  }  

//5 minute output for file
  if ((millis() - period) >= interval) {
    period = millis();
    min5();
  }  
  
  if (gb || eb || ib) {
    
    noInterrupts();
    fg = ((gtim > 0) && (gtim < maxint)) ? 3600.0 / gtim : 0;
    fe = ((etim > 0) && (etim < maxint)) ? 3600.0 / etim : 0;
    fi = ((itim > 0) && (itim < maxint)) ? 3600.0 / itim : 0;
    //float fl = ((ltim > 0) && (ltim < maxint)) ltim ? 3600.0 / ltim : 0;
    gb = eb = ib = lb = false;    
    interrupts();
    
    fu = fg + fi - fe;
    
    lednum(0, fu);
    lednum(1, fg);
    lednum(2, fe);
    lednum(3, fi);
 
 char str[10];
 
    ftoa(str, gtot / 1000.);
    str[6] = 0;
    lcd.setCursor(2, 2);
    lcd.print(str);
    
    ftoa(str, etot / 1000.0);
    str[6] = 0;
    lcd.setCursor(13, 2);
    lcd.print(str);
    
    ftoa(str, itot / 1000.0);
    str[6] = 0;
    lcd.setCursor(2, 3);
    lcd.print(str);
    
    signed long used = gtot + itot - etot;
    
    if (used < 0) {
       used = 0;
    }
    
    if ((uold == 0) || (used > uold)) {
       uold = used;
       ftoa(str, used / 1000.0);
       str[6] = 0;
       lcd.setCursor(13, 3);
       lcd.print(str);
    }

  } else {
    
    noInterrupts();
    if ((gtim > mintim) && ((millis() - glast) > (gtim + tdelta))) {
      gtim += tdelta;
      gb = true;
    }
    
    if ((etim > mintim) && ((millis() - elast) > (etim + tdelta))) {
      etim += tdelta;
      eb = true;
    }
    
    if ((itim > mintim) && ((millis() - ilast) > (itim + tdelta))) {
      itim += tdelta;
      ib = true;
    }
    
    if ((ltim > mintim) && ((millis() - llast) > (ltim + tdelta))) {
      ltim += tdelta;
      lb = true;
    }
    
    interrupts();
  }
}

void initled(int no)
{
    seg7[no]->shutdown(0, false);
    seg7[no]->setIntensity(0, intensity);
    seg7[no]->clearDisplay(0);
    delay(led_delay);
}

void onemin()
{
static unsigned int hup = 0;
static unsigned int mup = 0;

char str[12];

  sprintf(str, "R %3ih %2im", hup, mup);
  lcd.setCursor(0, 1);
  lcd.print(str);
  
  if (++mup > 59) {
    mup = 0;
    ++hup;
  }
}

void sec5()
{
char str[10];
  
  noInterrupts();
    
  unsigned int ig = gdat;
  unsigned int ie = edat;
  unsigned int ii = idat;
  unsigned int il = ldat;
    
  gdat = 0;
  edat = 0;
  idat = 0;
  ldat = 0;
  
  interrupts();

  Serial.print(DATA);
  Serial.print(ig);
  Serial.print(',');
  Serial.print(ie);
  Serial.print(',');
  Serial.print(ii);
  Serial.print(',');
  Serial.print(il);
  Serial.print(',');
  Serial.print((long)(fg * 1000));
  Serial.print(',');
  Serial.print((long)(fe * 1000));
  Serial.print(',');
  Serial.print((long)(fi * 1000));
  Serial.print(',');
  Serial.println((long)(fl * 1000));
    
  checkout();  
}

void checkout()
{
char str[30];

static int tries = 0;

  if (putout == true) {
    if (Serial.available() > 0) {
      int s = 0;
      
      while (Serial.available() > 0)
        str[s++] = Serial.read();
        
      str[s] = 0;
      
      if (str[0] == TIME) {
        str[12] = 0;
          if (!RTC.isrunning()) {
            Serial.print(LOG);
            Serial.println("RTC is NOT running!");
          }
        RTC.adjust(DateTime(str + 1, str + 13));
      }
        
      //Serial.print(DISCON);
      //Serial.println(str);
      //Serial.println(" saved ok");
      putout = false;
      tries = 0;
      
      lcd.setCursor(19, 1);
      lcd.write(".");

    } else {
      if (++tries > 4) {
        putout = false;
        tries = 0;
      
        char *out = displayDateTime(str);
        *(out - 1) = 0;
        Serial.print(LOG);
        Serial.print(str);
        Serial.print(" Data NOT saved ");
        Serial.println(output);

        lcd.setCursor(19, 1);
        lcd.write("!");
      }
    }
  }
}

void min5()
{
char str[30];

  noInterrupts();
    
  unsigned int ig = gcnt;
  unsigned int ie = ecnt;
  unsigned int ii = icnt;
  unsigned int il = lcnt;
    
  gcnt = 0;
  ecnt = 0;
  icnt = 0;
  lcnt = 0;
    
  interrupts();
  
  //checkout();

  Serial.print(SAVE);
  char *out = displayDateTime(output);
  sprintf(out, "%i,%i,%i,%i", ig, ie, ii, il);
  Serial.println(output);
  putout = true;


DateTime rtc = RTC.now();

  printDec2(str, rtc.hour());
  str[2] = ':';
  printDec2(str + 3, rtc.minute());
  str[5] = ' ';
  str[6] = ' ';
  str[7] = 0;

  lcd.setCursor(10, 1);
  lcd.write(" S ");
//  lcd.setCursor(11, 1);
  lcd.write(str);
}

void blink()
{
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(2000);               // wait for a second
}

void gen_int()
{
 unsigned long g = millis() - glast;
 
  if (g > mintim) {
    glast = millis();
    gtim = g;
    ++gcnt;
    ++gdat;
    ++gtot;
    gb = true;
  }
}

void expt_int()
{
unsigned long e = millis() - elast;

  if (e > mintim) {
    elast = millis();
    etim = e;
    itim = 0;
    ++ecnt;
    ++edat;
    ++etot;
    eb = true;
  }
}

void imp_int()
{
unsigned long i = millis() - ilast;

  if (i > mintim) {
    ilast = millis();
    itim = i;
    etim = 0;
    ++icnt;
    ++idat;
    ++itot;
    ib = true;
  }
}

void land_int()
{
unsigned long l = millis() - llast;

  if (l > mintim) {
    llast = millis();
    ltim = l;
    ++lcnt;
    ++ldat;
    ++ltot;
    lb = true;
  }
}

char* printDec2(char *out, int value)
{
  *out = (char)('0' + (value / 10));
  *(out + 1) = (char)('0' + (value % 10));
  *(out + 2) = 0;
  
  return out + 2;
}

char* displayDateTime(char *out)
{
DateTime rtc = RTC.now();

  out = printDec2(out, rtc.day());
  *(out++) = '/';
  out = printDec2(out, rtc.month());
  *(out++) = '/';
  out = printDec2(out, rtc.year() / 100);
  out = printDec2(out, rtc.year() % 100);
  *(out++) = ',';

  out = printDec2(out, rtc.hour());
  *(out++) = ':';
  out = printDec2(out, rtc.minute());
  *(out++) = ',';
  *out = 0;
  
  return out;
}

char* ftoa(char *a, double f)
{
char *ret = a;
long heiltal = (long)f;
long desimal = abs((long)((f - heiltal) * 1000));

  a += sprintf(a, "%2i", heiltal);
  *a++ = '.';
  sprintf(a, "%03i", desimal);
  return ret;
}

void writeArduinoOn7Segment() {
  for (int l = 0; l < maxled; l++) {
    seg7[l]->setChar(0, 7, 'a', false);
    seg7[l]->setChar(0, 6, 'r', false);
    seg7[l]->setChar(0, 5, 'd', false);
    seg7[l]->setChar(0, 4, 'u', false);
    seg7[l]->setChar(0, 3, 'i', false);
    seg7[l]->setChar(0, 2, 'n', false);
    seg7[l]->setChar(0, 1, 'o', false);
    delay(led_delay);
  }
} 


void lednum(int seg, float f)
{
int n = f * 1000.0;
int d;
bool dp;

  //seg7[seg]->clearDisplay(0);
  initled(seg);
  
  seg7[seg]->setChar(0, 7, inind[seg], false);

  for (int p = 0; p < 5; p++) {
    dp = (p == 3);
    d = n % 10;
    n /= 10;
    
    seg7[seg]->setDigit(0, p + 1, d, dp);
  }
  
  delay(led_delay);  //allow time for the led to be updatd
}

I wasn't previously calling initled() every time I displayed I was just trying it to see if it made any difference which it doesn't.

Hi 2Kaud

firstly, when you post code , highlight it and click on the strange symbol between the " insert table " and "insert quote" the " code" symbol, it always used to be a # symbol, but everything changed last week - I suppose its a twitter thing :slight_smile:

Secondly, that seems a hell of a long way round controlling 4 7seg displays, are they small ones running from 5v ?

There are 4 banks of 8 digit 7seg 5v displays. See http://www.amazon.co.uk/gp/product/B00IHSE6V6/ref=wms_ohs_product?ie=UTF8&psc=1

I've changed the code to replace the global ledcontrol variables with local ones that are initialized each time the program changes the led display (in lednum()). The result is quite interesting. I'm still experiencing the problem with one of the 4 banks of 8 digit 7seg displays sometimes going blank as per my original post #1, but now after a display goes blank the next time the 8 digit display is written, it now shows the correct display - ie comes 'back on'.

Does anyone have any ideas please about what is causing this and how I can prevent a display going blank in the first place?

#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
#include "LedControl.h"
#include <stdio.h>

const int maxled = 4;

struct Ledctl {
  int DataIn;
  int Load;
  int Clk;
} ltl[maxled] = { {22, 23, 24},     //led 0
                  {26, 27, 28},     //led 1
                  {30, 31, 32},     //led 2
                  {34, 35, 36}};    //led 3

const char inind[] = "UGE1";

//Interrupt ports
const int gen = 2;      //int 0
const int expt = 3;     //int 1
const int impt = 19;    //int 4
const int land = 18;    //int 5

//Ports used
const int led = 13;

//LCD ports
const int RS = 4;
const int EN = 5;
const int D4 = 6;
const int D5 = 7;
const int D6 = 8;
const int D7 = 9;

//Constants
const unsigned int   baud = 57600;             //Baud rate
const unsigned long  interval = 5 * 60000;     //5 minute
const unsigned long  omin = 60000;             //1 minute
const unsigned long  daint = 5000;             //5 seconds
const unsigned int   mintim = 300;             //minimum interval between pulses eqv 12kw
const unsigned int   tdelta = 2500;            //time interval to update usage if no pulse received
const unsigned long  maxint = 4000000;         //max time interval for 0
const unsigned int   intensity = 1;
const unsigned int   led_delay = 2;

//Commands
const char DISCON  = 'c';    //c - display on console
const char SAVE    = 'f';    //f - save data to file
const char DATA    = 'd';    //d - data to Data buff
const char LOG     = 'l';    //l - log output
const char TIME    = 't';    //t - set date/time

//Global devices
LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
RTC_DS1307 RTC;

//usage
float fg = 0.0;
float fe = 0.0;
float fi = 0.0;
float fl = 0.0;
float fu = 0.0;

//Used by interrupt so need volatile

//5 minute counts
volatile unsigned int gcnt = 0;
volatile unsigned int ecnt = 0;
volatile unsigned int icnt = 0;
volatile unsigned int lcnt = 0;

//5 second counts
volatile unsigned int gdat = 0;
volatile unsigned int edat = 0;
volatile unsigned int idat = 0;
volatile unsigned int ldat = 0;

//Time between pulses
volatile unsigned long gtim = 0;
volatile unsigned long etim = 0;
volatile unsigned long itim = 0;
volatile unsigned long ltim = 0;

//Last pulse time
volatile unsigned long glast = 0;
volatile unsigned long elast = 0;
volatile unsigned long ilast = 0;
volatile unsigned long llast = 0;

//Set when pulse received
volatile boolean gb = false;
volatile boolean eb = false;
volatile boolean ib = false;
volatile boolean lb = false;

volatile unsigned long gtot = 0;
volatile unsigned long etot = 0;
volatile unsigned long itot = 0;
volatile unsigned long ltot = 0;

volatile int ledstat = LOW;

//For 5 min file log
char output[50];
volatile boolean putout = false;

// the setup routine runs once when you press reset:
void setup()
{
char str[20];

char *out;
  
  Serial.begin(baud);
  Wire.begin();
  RTC.begin();
  lcd.begin(20, 4);
  
  if (!RTC.isrunning()) {
    Serial.print(LOG);
    Serial.println("RTC is NOT running!");
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  
  Serial.print(LOG);
  Serial.print("Reset at ");
  out = displayDateTime(str);
  *(out - 1) = 0;    //Remove trailing ,
  Serial.println(str);
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.write("rst");
  str[10] = ' ';
  lcd.setCursor(4, 0);
  lcd.write(str);
  
  onemin();
  
  //Set constant display chars  
  lcd.setCursor(0, 2);
  lcd.write('G');
  lcd.setCursor(11, 2);
  lcd.write ('E');
  lcd.setCursor(0, 3);
  lcd.write('I');
  lcd.setCursor(11, 3);
  lcd.write ('U');
  
  //Initialize pins used
  pinMode (led, OUTPUT);
  pinMode (gen, INPUT_PULLUP);
  pinMode (expt, INPUT_PULLUP);
  pinMode (impt, INPUT_PULLUP);
  pinMode (land, INPUT_PULLUP);
  
  //Set interrupts
  attachInterrupt(0, gen_int, RISING);
  attachInterrupt(1, expt_int, RISING);
  attachInterrupt(4, imp_int, RISING);
  attachInterrupt(5, land_int, RISING);
  
  digitalWrite(led, ledstat);
  
  glast = elast = ilast = llast = millis();

  writeArduinoOn7Segment();
  delay(500);
}

//......... same as previous code

void writeArduinoOn7Segment() {
  for (int l = 0; l < maxled; l++) {
    LedControl seg(ltl[l].DataIn, ltl[l].Clk, ltl[l].Load, 1);

    seg.shutdown(0, false);
    seg.setIntensity(0, intensity);
    seg.clearDisplay(0);
    
    seg.setChar(0, 7, 'a', false);
    seg.setChar(0, 6, 'r', false);
    seg.setChar(0, 5, 'd', false);
    seg.setChar(0, 4, 'u', false);
    seg.setChar(0, 3, 'i', false);
    seg.setChar(0, 2, 'n', false);
    seg.setChar(0, 1, 'o', false);
  }
} 


void lednum(int segno, float f)
{
int n = f * 1000.0;
int d;
bool dp;

LedControl seg(ltl[segno].DataIn, ltl[segno].Clk, ltl[segno].Load, 1);

  seg.shutdown(0, false);
  seg.setIntensity(0, intensity);
  seg.clearDisplay(0);
  
  seg.setChar(0, 7, inind[segno], false);

  for (int p = 0; p < 5; p++) {
    dp = (p == 3);
    d = n % 10;
    n /= 10;
    
    seg.setDigit(0, p + 1, d, dp);
  }
}

Anyone - please. This is driving me insane!