4 Seven Segment LED Displays to Display Temperature

Hello, all. This is my first post for this forum.

I’ve been learning how to use my new LED displays and had the idea to use them to display temperatures using a OneWire DS18B20 module. I’ve got it working but each time I request temperatures from the module, the LED display goes dark for about a second until the new temperature has been received, resulting in constant or periodic blinking if I use a certain time interval. Any advice on how to have the LED refresh constantly without being disrupted as the current temperature is being requested?

Here is my code:

#include <OneWire.h>
#include <DallasTemperature.h>
#include <SevSeg.h>

#define ONE_WIRE_BUS 19
// OneWire in port 19
OneWire oneWire(ONE_WIRE_BUS);
// Set up OneWire communication
DallasTemperature sensors(&oneWire);
// Reference OneWire readings in DallasTemperature library
SevSeg sevseg;
// Create seven segment object
unsigned long temp;
// Variable for temp.
unsigned long time, lastTime = 0;

void setup() {
  byte numDigits = 4;
  byte digitPins[] = {2, 3, 4, 5};
  byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
  sensors.begin();
  sevseg.begin(COMMON_CATHODE, numDigits, digitPins, segmentPins);
  sevseg.setBrightness(90);
  // Program seven segment display
  sensors.requestTemperatures();
  temp = sensors.getTempFByIndex(0) * 100;
  sevseg.setNumber(temp, 2);
}

void loop() {
  time = millis();
  if (time - lastTime > 2000) {
    sensors.requestTemperatures();
    temp = sensors.getTempFByIndex(0) * 100;
    sevseg.setNumber(temp, 2);
    lastTime = millis();
  }
  // Check time every two seconds
  sevseg.refreshDisplay();
}

ds18b20_display.ino (1.03 KB)

Untested: Maybe move sevseg.refreshDisplay(); inside the if statement? Its probably staying blank for the remaining time on your timer check.

Elryk:
Untested: Maybe move sevseg.refreshDisplay(); inside the if statement? Its probably staying blank for the remaining time on your timer check.

I’ve tried having the refresh command before the timer check, after the timer check, and in the timer check. When I remove the timer check entirely, the display will repeatedly blink, remaining off for about a second and remaining on for around 300 milliseconds. When I remove the sensors.requestTemperatures() command, the temperature will not update, but the constant un-updated temperature will remain displayed with much shorter blinks (on for 2 seconds, off for under 100 milliseconds), leading me to believe the sensors.requestTemperatures() command is pausing the program while the Arduino reads input from the DS18B20 sensor.

While researching the sensors.requestTemperatures() function, I discovered something of a workaround solution at this forum post. By #defining a digital pin for the sensor to receive its power from, digitalWriting it to HIGH, AND setting a 1.000 second delay the line before the pinMode is set to HIGH and another after sensors.requestTemperatures() is initially called, I've reduced the blink's downtime to under 100 milliseconds. However, if there is any way to have the display refresh independently of sensors.requestTemperatures(), I would be interested to hear about it.

#define ONE_WIRE_PWR 22

void setup() {
  byte numDigits = 4;
  byte digitPins[] = {2, 3, 4, 5};
  byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
  sevseg.begin(COMMON_CATHODE, numDigits, digitPins, segmentPins);
  sevseg.setBrightness(90);
  // Program seven segment display
  delay(1000);
  pinMode(ONE_WIRE_PWR, OUTPUT);
  digitalWrite(ONE_WIRE_PWR, HIGH);
  sensors.begin();
  sensors.requestTemperatures();
  delay(1000);
  temp = sensors.getTempFByIndex(0) * 100;
  sevseg.setNumber(temp, 2);
}

There is actually a very easy way to check that theory. Setup some serial.print() to print the action happening and the time it started (placing the print just before the action). Look for large gaps in the times, when the 7seg is blinking, to see what is causing the delay.

After a little looking into that library, this is happening because of what ever is causing the delay:

sevseg.refreshDisplay(); // Must run repeatedly; don't use blocking code (ex: delay()) in the loop() function or this won't work right

I see 2 options, find and minimize the delay, and/or add more sevseg.refreshDisplay() in various places (id start with the places you've already tried, all at once)

This seems to be a limitation of that library. You also have other options still, they are just inconvenient: Find a different library that doesn't have this limitation or build/buy a 7seg driver circuit and do it with hardware rather than software (the better, but most inconvenient solution)

Elryk:
There is actually a very easy way to check that theory. Setup some serial.print() to print the action happening and the time it started (placing the print just before the action). Look for large gaps in the times, when the 7seg is blinking, to see what is causing the delay.

After a little looking into that library, this is happening because of what ever is causing the delay:

sevseg.refreshDisplay(); // Must run repeatedly; don't use blocking code (ex: delay()) in the loop() function or this won't work right

I see 2 options, find and minimize the delay, and/or add more sevseg.refreshDisplay() in various places (id start with the places you've already tried, all at once)

This seems to be a limitation of that library. You also have other options still, they are just inconvenient: Find a different library that doesn't have this limitation or build/buy a 7seg driver circuit and do it with hardware rather than software (the better, but most inconvenient solution)

I modified the code to test the delays in the sensors.requestTemperatures() function by defining a new variable timeDiff and recording it's millis() after sensors.requestTemperatures() finishes in the if statement. I printed timeDiff - time to the Serial Monitor and found that without the workaround code, the delay is approximately 752 milliseconds while with the workaround it is 97 milliseconds.