Stuck on display value not updating

i made a thermometer based on 3 digit 7 segment common anode display, it uses DHT11 sensor, shows the temperature value which it read at starting but not updating in any condition....

#include <dht_nonblocking.h>

#define DHT_PIN A4
#define DHT_TYPE DHT_TYPE_11

DHT_nonblocking dht_sensor(DHT_PIN, DHT_TYPE);

const int segmentPins[8] = {0, 1, 2, 3, 4, 5, 6, 7};
const int digitPins[3] = {8, 9, 10};

const byte digits[10] = {
  B1111110, // 0
  B0110000, // 1
  B1101101, // 2
  B1111001, // 3
  B0110011, // 4
  B1011011, // 5
  B1011111, // 6
  B1110000, // 7
  B1111111, // 8
  B1111011  // 9
};

unsigned long lastRead = 0;
const unsigned long readInterval = 2000; // 2-second update interval
float temperature = 0.0;
bool firstReading = true;

void setup() {
  // Initialize pins
  for (int i = 0; i < 8; i++) pinMode(segmentPins[i], OUTPUT);
  for (int i = 0; i < 3; i++) pinMode(digitPins[i], OUTPUT);

  // Slower startup animation (10 seconds)
  const byte animationFrames[] = {
    B1000000, // A
    B0100000, // B
    B0010000, // C
    B0001000, // D
    B0000100, // E
    B0000010, // F
    B0000001  // G
  };

  unsigned long animationStart = millis();
  unsigned long frameStart = animationStart;
  int currentFrame = 0;
  const int frameDuration = 500; // 
  while (millis() - animationStart < 10000) { // 10-second animation
    // Update animation frame
    if (millis() - frameStart >= frameDuration) {
      frameStart = millis();
      currentFrame = (currentFrame + 1) % 7;
    }

    // Try to read sensor during animation
    float temp;
    if (dht_sensor.measure(&temp, NULL)) {
      temperature = temp; // Store as float
      firstReading = false;
    }

    // Display current animation frame
    displayAnimationFrame(animationFrames[currentFrame]);
  }
}



void loop() {
  float temp;
  
  // Continuously attempt to read the sensor
  if (dht_sensor.measure(&temp, NULL)) {
    // Update temperature every 10 seconds
    if (millis() - lastRead >= readInterval) {
      lastRead = millis();
      temperature = temp;
      firstReading = false;
    }
  }
  
  // Display current temperature
  displayNumber(firstReading ? 0.0f : temperature);
}

void clearDisplay() {
  for (int digit = 0; digit < 3; digit++) {
    digitalWrite(digitPins[digit], HIGH); // Turn off all digits
  }

  for (int segment = 0; segment < 8; segment++) {
    digitalWrite(segmentPins[segment], HIGH); // Turn off all segments
  }
}

void displayNumber(float temp) {
  // Clear old digits before updating
  clearDisplay();

  int number = round(temp * 10);  // Convert temp to 1 decimal place (e.g., 24.7 → 247)
  int digitsArray[3] = { (number / 100) % 10, (number / 10) % 10, number % 10 };

  for (int digit = 0; digit < 3; digit++) {
    digitalWrite(digitPins[digit], LOW);

    if (digit == 0 && temp < 10) {
      displayDigit(-1);  // Blank leading digit for temps under 10°C
    } else {
      displayDigit(digitsArray[digit]);
    }

    digitalWrite(segmentPins[7], (digit == 1) ? LOW : HIGH);  // Decimal point on middle digit
    delay(5);
    digitalWrite(digitPins[digit], HIGH);
  }
}

void displayDigit(int number) {
  // Clear previous segments
  for (int segment = 0; segment < 7; segment++) {
    digitalWrite(segmentPins[segment], HIGH);
  }

  // Display number if valid
  if (number != -1) {
    for (int segment = 0; segment < 7; segment++) {
      digitalWrite(segmentPins[segment], !(digits[number] & (1 << (6 - segment))));
    }
  }
}


void displayAnimationFrame(byte pattern) {
  for (int digit = 0; digit < 3; digit++) {
    digitalWrite(digitPins[digit], LOW);
    displayPattern(pattern);
    delay(5);
    digitalWrite(digitPins[digit], HIGH);
  }
}

void displayPattern(byte pattern) {
  for (int segment = 0; segment < 7; segment++) {
    digitalWrite(segmentPins[segment], !((pattern >> (6 - segment)) & 1));
  }
  digitalWrite(segmentPins[7], HIGH);
}       

You are using pins 0 and 1 to seven segment.
These pins are for serial and should not be used for other purposes.
Use another pins and move pins 0 and 1 there.
May be 2 to 12 ,

Who wrote the code?

Post a link to where you found it.

a7

Which Arduino board are you using?
If you do free up the pins for the Serial functions then you can add debug statements to see on the serial console if/how the value of temperature changes.
I'd have probably used a hardware timer to multiplex the display so the stability of the display is unaffected by any potentially blocking activities in the loop(). Every four or so milliseconds, the timer calls a routine (an ISR) which displays the next digit in the cycle.

Arduino uno. i already tested with altering pin without 0and 1 but same result. there is some thing blocking to update display value, i cannot find it. i am using dht non-blocking library but got same result... here i am using 3 digit common anode display...dht 11 is working fine when tested with serial monitor...

Have you tried adding a debug statement in your code having freed pins 0 and 1, also with a corresponding Serial.begin statement in setup(), such as:

if (millis() - lastRead >= readInterval) { 
   lastRead = millis(); 
   temperature = temp; 
   firstReading = false; 
   Serial.println( temperature) ;  // debug statement 
}

I'd also be curious to know the source of the code example you used as a basis for your own program. If you wrote it yourself from scratch, or with AI support, then start with something simpler to handle the display multiplexing.

tl;dr: digits are turned on by HIGH and segments are turned on by LOW.

@subhrodeep had a variety of mistakes confusing and compounding the process of finding errors and issues.

This code below is the original logic, unmolested except to fix those pesky "got it wrong" things.

I am off to the beach, we have a perfect day, it will be just too hot enough, only a gentle breeze and last night's rain has cleansed the air. So no time for further comment or making this pretty. Run the simulation and most of what I had to do should be marked by my signature commetn

//...

The temperature is artificial. I added printing and some helpful manifest constants. The sketch freezes at a point a needed it to do in order to sort the stupid mistakes. You can try it here:

The code now

//...
// https://wokwi.com/projects/426225551245381633

const int segmentPins[8] = {11, 12, 2, 3, 4, 5, 6, 7};
const int digitPins[3] = {8, 9, 10};

//... common anode
# define OND HIGH
# define OFFD LOW

# define ONS LOW
# define OFFS HIGH

const byte digits[10] = {
  B1111110, // 0
  B0110000, // 1
  B1101101, // 2
  B1111001, // 3
  B0110011, // 4
  B1011011, // 5
  B1011111, // 6
  B1110000, // 7
  B1111111, // 8
  B1111011  // 9
};

unsigned long lastRead = 0;
const unsigned long readInterval = 2000; // 2-second update interval
float temperature = 42.0;
bool firstReading = true;

void setup() {
  Serial.begin(115200);
  Serial.println("\nJefferson Airplane!\n");

  // Initialize pins
  for (int i = 0; i < 8; i++) pinMode(segmentPins[i], OUTPUT);
  for (int i = 0; i < 3; i++) pinMode(digitPins[i], OUTPUT);

return;  // skip animation life too short.

  // Slower startup animation (10 seconds)
  const byte animationFrames[] = {
    B1000000, // A
    B0100000, // B
    B0010000, // C
    B0001000, // D
    B0000100, // E
    B0000010, // F
    B0000001  // G
  };

  unsigned long animationStart = millis();
  unsigned long frameStart = animationStart;
  int currentFrame = 0;
  const int frameDuration = 500; // 
  while (millis() - animationStart < 10000) { // 10-second animation
    // Update animation frame
    if (millis() - frameStart >= frameDuration) {
      frameStart = millis();
      currentFrame = (currentFrame + 1) % 7;
    }

    // Try to read sensor during animation. why.

    // Display current animation frame
    displayAnimationFrame(animationFrames[currentFrame]);
  }
}

void loop() {
  float temp;
  
  // Continuously attempt to read the sensor
  if (1) {
    // Update temperature every 10 seconds
    if (millis() - lastRead >= readInterval) {
      lastRead = millis();
      temperature += 0.77;   // just getting hotter
      Serial.println(temperature);
      firstReading = false;
    }
  }
  
  // Display current temperature
  displayNumber(firstReading ? 0.0f : temperature);
}

void clearDisplay() {
  for (int digit = 0; digit < 3; digit++) {
    digitalWrite(digitPins[digit], OFFD); // Turn off all digits
  }

  for (int segment = 0; segment < 8; segment++) {
    digitalWrite(segmentPins[segment], OFFS); // Turn off all segments
  }
}

void displayNumber(float temp) {
  // Clear old digits before updating
  clearDisplay();

  int number = round(temp * 10);  // Convert temp to 1 decimal place (e.g., 24.7 → 247)
  int digitsArray[3] = { (number / 100) % 10, (number / 10) % 10, number % 10 };

if (0) {
  Serial.print("   "); Serial.println(digitsArray[0]);
  Serial.print("      "); Serial.println(digitsArray[1]);
  Serial.print("         "); Serial.println(digitsArray[2]);
} // plausible

  for (int digit = 0; digit < 3; digit++) {

/*    if (digit == 0 && temp < 10) {
      displayDigit(-1);  // Blank leading digit for temps under 10°C
    } else {
      displayDigit(digitsArray[digit]);
    }
*/

//...  just
    displayDigit(digitsArray[digit]);
    digitalWrite(segmentPins[7], (digit == 1) ? ONS : OFFS);  // Decimal point on middle digit

//... don't until all segments are ready to go

    digitalWrite(digitPins[digit], OND);

//...
    if (1) // just stop it when it should be shwoing one 7:
      if (digitsArray[digit] == 7) {
        Serial.println("s e v e n");
        for (; ; );
      }

    delay(5);
    digitalWrite(digitPins[digit], OFFD);
  }
}

void displayDigit(int number) {

//...
    if (number == -1) return;

// Clear previous segments

if (0) // the logic writes every segment
  for (int segment = 0; segment < 7; segment++) {
    digitalWrite(segmentPins[segment], HIGH);
  }

//... turn on digit segments
  for (int segment = 0; segment < 7; segment++) {
    digitalWrite(segmentPins[segment],      (digits[number] & (1 << (6 - segment))) ? ONS : OFFS);
  }
}


void displayAnimationFrame(byte pattern) {
}

void displayPattern(byte pattern) {
  for (int segment = 0; segment < 7; segment++) {
    digitalWrite(segmentPins[segment], !((pattern >> (6 - segment)) & 1));
  }
  digitalWrite(segmentPins[7], HIGH);
}

HTH

a7

i wrote this code in 2021, but i want to add some animation effect on 7 segment display because i use to update temperature value once in 15 second to reduce flickering, so that after powering it the display turn only after 15 seconds. i want to use this 15 seconds to shoe some animation so that i want to modify this code now with the help of Deep seek AI. Here is my original code....

#include <SevSeg.h>

#include <dht_nonblocking.h>
/* Uncomment according to your sensortype. */
#define DHT_SENSOR_TYPE DHT_TYPE_11
//#define DHT_SENSOR_TYPE DHT_TYPE_21
//#define DHT_SENSOR_TYPE DHT_TYPE_22

static const int DHT_SENSOR_PIN = A4;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );
SevSeg sevseg; //Instantiate a seven segment controller object
void setup() {
  byte numDigits = 4;
  byte digitPins[] = {8, 9, 10};
  byte segmentPins[] = {0, 1, 2, 3, 4, 5, 6, 7}; //2,3,4,5,6,11,12,13
  bool resistorsOnSegments = true; // 'false' means resistors are on digit pins
  byte hardwareConfig = P_TRANSISTORS; // See README.md for options
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist or isn't connected
 
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
  updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(90);
}
static bool measure_environment( float *temperature, float *humidity )

{
  static unsigned long measurement_timestamp = millis( );

  /* Measure once every four seconds. */
  if( millis( ) - measurement_timestamp > 15000ul )
  {
    if( dht_sensor.measure( temperature, humidity ) == true )
    {
      measurement_timestamp = millis( );
      return( true );
    }
  }

  return( false );
}


void loop() {
 float temperature;
 float humidity;

  //float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  
  // Read temperature as Fahrenheit (isFahrenheit = true)
  //float f = dht.readTemperature(true);
   if( measure_environment( &temperature, &humidity ) == true )
  {
    sevseg.setNumber(temperature*100,2);
  }
  sevseg.refreshDisplay();
}

Good luck with that. Maybe tell it retain use of the SevSeg library… as much fun as you've been having trying to do without.

a7

OK. So your primary goal is to reduce the flickering and the animations were intended as some sort of distraction from this flickering. If that is correct, then you can eliminate the flickering altogether by driving the display multiplexing using a hardware timer (as I said earlier). It could possibly be as simple as calling sevseg.refreshDisplay(); from a timer ISR but I'd have to look at the library to be sure. Maybe DeepSeek can suggest something.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.