One Wire Sensor reading delay

I have a DS18B20 sensor and a LED 7 segment display acting as a thermometer (will be more complex soon, but trying to get one peice working at a time). The problem I am having is that when the ATmega reads the temp the display blanks out for a noticeable period of time (about a second), giving the display a distracting strobe effect. I am looking for a way to increase the read speed from the one wire bus. I only have one device connected and have no plans to add additional devices if that lets me cut a corner someplace.

Thanks in advance for any help!

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

//setup display
SevSeg Display;
int displayType = COMMON_ANODE; //Your display is either common cathode or common anode
int numberOfDigits = 4; //Do you have a 1, 2 or 4 digit display?
//Declare what pins are connected to the digits (anode)
int digit1 = 9; //Pin 12 on my 4 digit display
int digit2 = 11; //Pin 9 on my 4 digit display
int digit3 = 17; //Pin 8 on my 4 digit display
int digit4 = 15; //Pin 6 on my 4 digit display
//Declare what pins are connected to the segments
int segA = 13; //Pin 11 on my 4 digit display
int segB = 7; //Pin 7 on my 4 digit display
int segC = 10; //Pin 4 on my 4 digit display
int segD = 12; //Pin 2 on my 4 digit display
int segE = 14; //Pin 1 on my 4 digit display
int segF = 18; //Pin 10 on my 4 digit display
int segG = 8; //Pin 5 on my 4 digit display
int segDP= 16; //Pin 3 on my 4 digit display
float tempF;

int counter=0;

//setup one wire sensor
#define ONE_WIRE_BUS A5

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// arrays to hold device address
DeviceAddress DSAddress;

void setup(){
  //setup display
  Display.Begin(displayType, numberOfDigits, digit1, digit2, digit3, digit4, segA, segB, segC, segD, segE, segF, segG, segDP);
  Display.SetBrightness(50); //Set the display brightness level
  //setup one wire
  sensors.begin();
  sensors.getAddress(DSAddress, 0);
  

}

void loop(){
  char dispStr[5];
  if (counter==100){
    counter=0;
  }
  if (counter==0){
  //get temp
  sensors.requestTemperatures(); // Send the command to get temperatures
  tempF=sensors.getTempF(DSAddress);
  
  //display temp
  float tempdisp=tempF*10;
  int tempInt=int(tempdisp);
  String tempStr = String(tempInt);
  tempStr="+"+tempStr;
  
  tempStr.toCharArray(dispStr,5);
  }
  Display.DisplayString(dispStr, 3);
  counter=counter+1;
}

I’m not sure why your display should go blank, then again I have no idea what you’re using. My 1’st suggestion is that the reading of the temp is “disturbing” the data sent to the display so why not offset them (reading vs display) in time. Read the temp on counter == 0 and update the temp data to the display only when counter == 50. (since 100 counts is your cycle)

From a quick glance at the temp sensor library, it looks like you can prevent the system from waiting on a conversion. This is an untested idea (I don’t have this temp sensor or the display you have) but hopefully gets things started in the right direction.

// sets the value of the waitForConversion flag
// TRUE : function requestTemperature() etc returns when conversion is ready
// FALSE: function requestTemperature() etc returns immediately (USE WITH CARE!!)
// (1) programmer has to check if the needed delay has passed
// (2) but the application can do meaningful things in that time
void DallasTemperature::setWaitForConversion(bool flag)

and

bool DallasTemperature::isConversionAvailable(uint8_t* deviceAddress)

Rough program flow could look like:

Setup:

-Everything you’re doing already

-Set the wait for conversion flag to false so you don’t block on conversions

-start the first conversion

Execution Loop:

-check to see if the conversion is ready

-----if it is: read it, update your display buffer and request the next conversion

-refresh your display

The display is just a bunch of LEDs driven by the ATmega. Each digit gets flashed on briefly each time the display is updated. The counter was just to get the display on long enough so I could check that the data was right (if I don’t use it I can’t read the display).

I will look into using the conversion flag when I get home it looks promising.

Well it worked, so it is available to anyone in the future the updated code is:

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

//setup display
SevSeg Display;
int displayType = COMMON_ANODE; //Your display is either common cathode or common anode
int numberOfDigits = 4; //Do you have a 1, 2 or 4 digit display?
//Declare what pins are connected to the digits (anode)
int digit1 = 9; //Pin 12 on my 4 digit display
int digit2 = 11; //Pin 9 on my 4 digit display
int digit3 = 17; //Pin 8 on my 4 digit display
int digit4 = 15; //Pin 6 on my 4 digit display
//Declare what pins are connected to the segments
int segA = 13; //Pin 11 on my 4 digit display
int segB = 7; //Pin 7 on my 4 digit display
int segC = 10; //Pin 4 on my 4 digit display
int segD = 12; //Pin 2 on my 4 digit display
int segE = 14; //Pin 1 on my 4 digit display
int segF = 18; //Pin 10 on my 4 digit display
int segG = 8; //Pin 5 on my 4 digit display
int segDP= 16; //Pin 3 on my 4 digit display
float tempF;

int counter=0;

//setup one wire sensor
#define ONE_WIRE_BUS A5

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// arrays to hold device address
DeviceAddress DSAddress;

void setup(){
  //setup display
  Display.Begin(displayType, numberOfDigits, digit1, digit2, digit3, digit4, segA, segB, segC, segD, segE, segF, segG, segDP);
  Display.SetBrightness(50); //Set the display brightness level
  //setup one wire
  sensors.begin();
  sensors.getAddress(DSAddress, 0);
  sensors.setWaitForConversion(false);
  sensors.requestTemperatures(); // Send the command to get temperatures
  while (sensors.isConversionAvailable(DSAddress)==false){
    //wait for first temp to prevent false reading at startup
    delay(1);
  }
  tempF=sensors.getTempF(DSAddress); //get first temp
  sensors.requestTemperatures(); // Send the command to get temperatures

}

void loop(){
  char dispStr[5];
  if (counter==100){
    counter=0;
  }
  
  //get temp-if temp is ready, set tempF to temp, and request new temp, otherwise continue
  
  if (sensors.isConversionAvailable(DSAddress)){
   tempF=sensors.getTempF(DSAddress); 
   sensors.requestTemperatures(); // Send the command to get temperatures
  }
  
  //display temp
  float tempdisp=tempF*10;
  int tempInt=int(tempdisp);
  String tempStr = String(tempInt);
  tempStr="+"+tempStr;
  
  tempStr.toCharArray(dispStr,5);
  
  Display.DisplayString(dispStr, 3);
  counter=counter+1;
}

Glad it worked for you, and thanks for posting your code.