7 segment bubble display problems

Hi,
I am using a 7 segment bubble display as shown HERE but I am using a thermistor to read temperature. The thermistor side of things works fine, its the display update I’m having some confusion with.

I followed the code at that link and wanted to change the updateDisp() method as it would sit in the while loop waiting for the display time to elapse (which is basically the same as using a delay() call) so that the code could do other things while it checked to see if the update time had elapsed.

So basically I have changed the printDisp() method to what I have attached below at line 113 and from lines 123-127.
However the display updates extremely quickly, so much so that its flickering, even though the method call on line 105 tells it that it should update every 1000ms.

Here’s my code:

/*
* created by Rui Santos, http://randomnerdtutorials.com
* modified by: Raphango
* Still more changes by: rccursach 2014
* Temperature Sensor Displayed on 4 Digit 7 segment common CATHODE
* 2013
* A Small portion from SparkFun's SevSeg Libray https://github.com/sparkfun/SevSeg
* SparkFun, Nathan Seidle, 2012 (Beerware license). Based on http://arduino.cc/playground/Main/SevenSegmentLibrary Dean Reading, 2012.
*/

#include <Thermistor4.h>

const int digitPins[4] = {9,10,11,12}; //4 common CATHODE pins of the display.
const int clockPin = 2;    //74HC595 Pin 2
const int latchPin = 3;    //74HC595 Pin 3
const int dataPin = 4;     //74HC595 Pin 44
const int tempPin = 3;     //thermistor temperature sensor pin

unsigned long ti = 0;
unsigned long tf = 0;

//As seen on SparkFun's SevSeg Library
const byte digit[10] =      //seven segment digits
{
  0b11111100, // 0
  0b01100000, // 1
  0b11011010, // 2
  0b11110010, // 3
  0b01100110, // 4
  0b10110110, // 5
  0b10111110, // 6
  0b11100000, // 7
  0b11111110, // 8
  0b11110110  // 9
};

#define THERMISTORPin 3

double tempRead;  

//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
double Kp = 100, Ki = 0.15, Kd = 1;

// instance of Thermistor Object
Thermistor4 Thermistor;
//various temp variables for testing.
unsigned int i, ADCAverage;

/////////////////////// used for measuring Vcc
long sum;
double average;
///////////////////

int digitBuffer[4] = {0};
int digitScan = 0;
float tempC;

void setup(){       
  Serial.begin(9600);        
  for(int i=0;i<4;i++)
  {
    pinMode(digitPins[i],OUTPUT);
  }
  pinMode(tempPin, INPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT); 
  Serial.begin(9600);

  float vccValue = readVcc(); //measureVcc();
  
  printDisp(vccValue, 1000);

  Thermistor.Pin = THERMISTORPin; //Set the pin number.

  Thermistor.SetUp(); //Sets up the analog read pin for internal AVR.

  //pow() is used elsewhere so might as well be used here.
  Thermistor.BitResolution = pow(2, 10) - 1; //ATmega's have a 10bit ADC (2^10-1).

  //Thermistor.VoltageSupply = average;   //4.885;   //4.4481;  // Metered supply across voltage divider
  Thermistor.VoltageSupply = vccValue;   //4.885;   //4.4481;  // Metered supply across voltage divider
  
  Thermistor.ResistanceFixed = 8250;   ///Fixed resistor in the divider. Measured in ohms. Meter this for accuracy.

  Thermistor.Offset = 0.0; //adjust temperature in Kelvin up or down a little to account for unforseen variations.

  // Steinhart-Hart coefficients. Taken from datasheet provided from manufacturer
  Thermistor.SteinhartA1 = 5.99357907117746e-004;   // First Steinhart-Hart coefficient.
  Thermistor.SteinhartA2 = 2.31247850239102e-004;   // Second Steinhart-Hart coefficient.
  Thermistor.SteinhartA3 = 5.61924102167737e-008;   // Third Steinhart-Hart coefficient.
  Thermistor.SteinhartA4 = 3.23406799250025e-011;   // Fourth Steinhart-Hart coefficient.

}


void loop(){
  Thermistor.ReadCalculate(3);
  
  Thermistor.ReadADC(analogRead (Thermistor.Pin));
  tempRead = Thermistor.GetFarenheit();

  printDisp(tempRead, 1000);
  Thermistor.VoltageSupply = readVcc();
}




void printDisp(float value, int msec) {
  tf = millis();
  clearDisp();
  //int digitThree, digitTwo, digitOne, digitZero;
  digitBuffer[3] = int(value / 100); // return hundreds value
  digitBuffer[2] = int(((value - (digitBuffer[3] * 100))) / 10);  // return tens value
  digitBuffer[1] = int ((value - (digitBuffer[3] * 100) - (digitBuffer[2] * 10))); // return units value
  digitBuffer[0] = int ((value - (digitBuffer[3] * 100) - (digitBuffer[2] * 10) - (digitBuffer[1])) * 10);  // return first decimal place value

  
  //Get it displayed until msec Milliseconds passed
  //unsigned long ti = millis();
  ti = millis();
  if(tf-ti > msec){
    tf = ti;
    updateDisp();
  }
}

//writes the temperature on display
void updateDisp() {
  for (int i = 0; i < 4; i++) {
    clearDisp();
    digitalWrite(digitPins[i], LOW); //Changed to LOW for turning the leds on.

    if (i == 1) //Add decimal dot
      shiftOut(dataPin, clockPin, LSBFIRST, digit[digitBuffer[i]] | 0b00000001);
    else
      shiftOut(dataPin, clockPin, LSBFIRST, digit[digitBuffer[i]]);

    digitalWrite(latchPin, HIGH);
    digitalWrite(latchPin, LOW);

    delay(5); //If not delayed, digits are seen brurry, if the value is 8 you migth see the display frickering.
  }
}

void clearDisp() {
  for (byte j = 0; j < 4; j++) {
    digitalWrite(digitPins[j], HIGH); // Turns the display off. Changed to HIGH
  }
}


long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA, ADSC));
  result = ADCL;
  result |= ADCH << 8;
  result = 1125300L / result; // Back-calculate AVcc in mV
  return result;
}

I’ve made some progress. It updates the display once per second now, but it quickly flashes then goes dark for the rest of the second.
Heres the current code:

/*
* created by Rui Santos, http://randomnerdtutorials.com
* modified by: Raphango
* Still more changes by: rccursach 2014
* Temperature Sensor Displayed on 4 Digit 7 segment common CATHODE
* 2013
* A Small portion from SparkFun's SevSeg Libray https://github.com/sparkfun/SevSeg
* SparkFun, Nathan Seidle, 2012 (Beerware license). Based on http://arduino.cc/playground/Main/SevenSegmentLibrary Dean Reading, 2012.
*/

#include <Thermistor4.h>

const int digitPins[4] = {9,10,11,12}; //4 common CATHODE pins of the display.
const int clockPin = 2;    //74HC595 Pin 2
const int latchPin = 3;    //74HC595 Pin 3
const int dataPin = 4;     //74HC595 Pin 44
const int tempPin = 3;     //thermistor temperature sensor pin

long ti = 0;
long tf = 0;

//As seen on SparkFun's SevSeg Library
const byte digit[10] =      //seven segment digits
{
  0b11111100, // 0
  0b01100000, // 1
  0b11011010, // 2
  0b11110010, // 3
  0b01100110, // 4
  0b10110110, // 5
  0b10111110, // 6
  0b11100000, // 7
  0b11111110, // 8
  0b11110110  // 9
};

#define THERMISTORPin 3

double tempRead;  
long tempTimeNow = 0;
long tempTimeLast = 0;

//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
double Kp = 100, Ki = 0.15, Kd = 1;

// instance of Thermistor Object
Thermistor4 Thermistor;
//various temp variables for testing.
unsigned int i, ADCAverage;

/////////////////////// used for measuring Vcc
long sum;
double average;
///////////////////

int digitBuffer[4] = {0};
int digitScan = 0;
float tempC;

void setup(){       
  Serial.begin(9600);        
  for(int i=0;i<4;i++)
  {
    pinMode(digitPins[i],OUTPUT);
  }
  pinMode(tempPin, INPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT); 
  Serial.begin(9600);

  float vccValue = readVcc(); //measureVcc();
  
  printDisp(vccValue, 1000);

  Thermistor.Pin = THERMISTORPin; //Set the pin number.

  Thermistor.SetUp(); //Sets up the analog read pin for internal AVR.

  //pow() is used elsewhere so might as well be used here.
  Thermistor.BitResolution = pow(2, 10) - 1; //ATmega's have a 10bit ADC (2^10-1).

  //Thermistor.VoltageSupply = average;   //4.885;   //4.4481;  // Metered supply across voltage divider
  Thermistor.VoltageSupply = vccValue;   //4.885;   //4.4481;  // Metered supply across voltage divider
  
  Thermistor.ResistanceFixed = 8250;   ///Fixed resistor in the divider. Measured in ohms. Meter this for accuracy.

  Thermistor.Offset = 0.0; //adjust temperature in Kelvin up or down a little to account for unforseen variations.

  // Steinhart-Hart coefficients. Taken from datasheet provided from manufacturer
  Thermistor.SteinhartA1 = 5.99357907117746e-004;   // First Steinhart-Hart coefficient.
  Thermistor.SteinhartA2 = 2.31247850239102e-004;   // Second Steinhart-Hart coefficient.
  Thermistor.SteinhartA3 = 5.61924102167737e-008;   // Third Steinhart-Hart coefficient.
  Thermistor.SteinhartA4 = 3.23406799250025e-011;   // Fourth Steinhart-Hart coefficient.

}


void loop(){
  Thermistor.ReadCalculate(3);
  
  Thermistor.ReadADC(analogRead (Thermistor.Pin));
  tempRead = Thermistor.GetFarenheit();
  tempTimeNow = millis();
  
  printDisp(tempRead, 1000);
  if(tempTimeNow - tempTimeLast > 1000){
    Serial.println("Gets to here");
    updateDisp();
    tempTimeLast = tempTimeNow;
  }

  
  Thermistor.VoltageSupply = readVcc();
  
}




void printDisp(float value, int msec) {
  //tf = millis();
  clearDisp();
  //int digitThree, digitTwo, digitOne, digitZero;
  digitBuffer[3] = int(value / 100); // return hundreds value
  digitBuffer[2] = int(((value - (digitBuffer[3] * 100))) / 10);  // return tens value
  digitBuffer[1] = int ((value - (digitBuffer[3] * 100) - (digitBuffer[2] * 10))); // return units value
  digitBuffer[0] = int ((value - (digitBuffer[3] * 100) - (digitBuffer[2] * 10) - (digitBuffer[1])) * 10);  // return first decimal place value

}

//writes the temperature on display
void updateDisp() {
  for (int i = 0; i < 4; i++) {
    clearDisp();
    digitalWrite(digitPins[i], LOW); //Changed to LOW for turning the leds on.

    if (i == 1) //Add decimal dot
      shiftOut(dataPin, clockPin, LSBFIRST, digit[digitBuffer[i]] | 0b00000001);
    else
      shiftOut(dataPin, clockPin, LSBFIRST, digit[digitBuffer[i]]);

    digitalWrite(latchPin, HIGH);
    digitalWrite(latchPin, LOW);

    delay(5); //If not delayed, digits are seen brurry, if the value is 8 you migth see the display frickering.
  }
}

void clearDisp() {
  for (byte j = 0; j < 4; j++) {
    digitalWrite(digitPins[j], HIGH); // Turns the display off. Changed to HIGH
  }
}


long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA, ADSC));
  result = ADCL;
  result |= ADCH << 8;
  result = 1125300L / result; // Back-calculate AVcc in mV
  return result;
}

The code has to multiplex drive the display, so must run all the time.

It shifts out one digit and turns on that digit for a few milliseconds, then does the next digit and so on. So it is rapidly showing digits 1,2,3,4,1,2,3,4,1,2,3,4.... hopefully quickly enough so you see all the digits at the same time.

Assuming the rest of the code does what it should, you can just add a call to updateDisp(); in loop()
e.g.

  printDisp(tempRead, 1000);
  if(tempTimeNow - tempTimeLast > 1000){
    Serial.println("Gets to here");
    tempTimeLast = tempTimeNow;
  }
  updateDisp();

Yours,
TonyWilk

TonyWilk:
Assuming the rest of the code does what it should, you can just add a call to updateDisp(); in loop()

That was it! I knew it was something simple but couldn't see it.
Thank you Tony!