1

I'm using the following library to drive a 4 digit, 7 segment LED display:

http://playground.arduino.cc/Main/SevenSegmentLibrary

The display is showing the temperature which it gets from a DS18B20 temperature sensor. Since the LED display constantly needs to be refreshed, when the code runs to get the current temperature, the display temporarily turns off because the LEDs are not being refreshed. The code I am using is below. Is there anyway to prevent the LED display from turning off while the temperature request code runs?

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

SevSeg sevseg;

unsigned long timer; // the timer
unsigned long INTERVAL = 30000; // the repeat interval (30 seconds)

#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup() {
  byte numDigits = 4;
  byte digitPins[] = {A2, A3, A4, A5};
  byte segmentPins[] = {8, 10, 6, 4, 3, 9, 7, 5};

  sevseg.begin(COMMON_CATHODE, numDigits, digitPins, segmentPins);
  sevseg.setBrightness(90);

  // Get the initial temperature and show it on the LED display
  sensors.begin();
  sensors.requestTemperatures();
  sevseg.setNumber(sensors.getTempCByIndex(0), 1);
  timer = millis(); // start timer
}

void loop() {
  if ((millis()-timer) > INTERVAL) {
    // Reset the timer and get/display the current temperature
    timer += INTERVAL;    
    sensors.requestTemperatures();
    sevseg.setNumber(sensors.getTempCByIndex(0), 1);
  }

  sevseg.refreshDisplay(); // Must run repeatedly to refresh the LED display
}

1 Answer 1

1

The problem here is that the display is driven using a timer interrupt. The temperature sensor, being a one-wire device, has to have very careful timing to communicate with it. As a result it disables interrupt so it has exclusive use of the CPU and can properly predict its timing while it's communicating. And so the display can't refresh at the same time.

So what can you do? Well, nothing really. You can't have perfect timing for the temperature sensor while at the same time interrupting it for displaying the value.

So there's really two main options:

  1. Change the temperature sensor. Use an SPI or I2C temperature sensor that has a real hardware interface to communicate with it so you don't have to use big-banging.

  2. Change the display. A non-multiplexed display or a display with its own built in driver (most often with some serial protocol like I2C or UART) would mean you don't have to use interrupts to update the display.

Basically you have two technologies that won't sit together well on the same chip.


Update:

I missed the sevseg.refreshDisplay() function call since the website had scrolled it off the bottom of the code block. Bah!

Ok, so it's not using an interrupt. That could be a good thing, or it may be meaningless. It takes time to do the temperature reading, and it's that getting in the way of the refreshing.

There's a chance you may be able to push the update "into the background" by attaching it to a timer interrupt, but if the OneWire communication does disable interrupts then the problem will still persist (I don't have OneWire to hand to look at the code right now).

2
  • I don't think that library uses a timer interrupt. See sevseg.refreshDisplay(). Communication between the arduino and one-wire device will only take a few milliseconds. Not enough to be noticeable. The big problem is that the Arduino wait a while between requesting a measurement, and retrieving the measured value.
    – Gerben
    Commented Oct 15, 2015 at 13:04
  • 1
    @Gerben Oops - that line was scrolled off the bottom of the code area - I completely missed that.
    – Majenko
    Commented Oct 15, 2015 at 13:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.