DS18B20 temperature sensor with a 4 Digit, 7 Segment LED display

HI All,

I hope someone here can be of assistance.
I have complied a sketch to use a DS18B20 and a 4 digit 7 segment LCD display, everything seems to work OK except for the LCD display. I can get the 1st digit and the last digit to display but the the middle two digits do not display anything when I try to display the reading from the DS18B20. If there is an error getting the reading from the sensor I display EEEE, this works fine.

Here is my code:

/*
ds18b20 temperature sensor with 7 Segment LED display
 */
// Include Libraries

#include <LedControl.h>		// For the 7 Segment LED display driven by MAX7219
#include <OneWire.h>		// For the one wire functions
#include <DallasTemperature.h>	// For the DS18B20

#define ONE_WIRE_BUS 3                                                        // Data wire is plugged into pin 3 on the Arduino
OneWire oneWire(ONE_WIRE_BUS);                                                // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);                                          // Pass oneWire reference to Dallas Temperature.
DeviceAddress TempSens = { 
  0x28, 0x01, 0xC0, 0xB8, 0x00, 0x00, 0x00, 0x86 };  // Assign the address for the 1-Wire temp sensor.
LedControl lc=LedControl(12,11,10,0);                                         // Pin 12 to Data In, 11 to Clk, 10 to LOAD

void setup(void)
{
  Serial.begin(9600);                    // Start Serial Port
  sensors.begin();                       // Start up the Sensor library
  sensors.setResolution(TempSens, 12);   // Set DS18B20 Resolution
  lc.shutdown(0,false);			 // Turn off power saving, enables display
  lc.setIntensity(0,10);		 // Sets brightness (0~15 possible values)
  lc.clearDisplay(0);			 // Clear screen
}

//Used for testing on a serial terminal
/*
void printTemperature(DeviceAddress deviceAddress)
 {
 float tempC = sensors.getTempC(deviceAddress);
 if (tempC == -127.00)
 {
 Serial.print("Error getting temperature");
 } 
 else
 {
 Serial.print("C: ");
 Serial.print(tempC,1);
 Serial.print("0");
 }
 }
 */
void displayDigit(DeviceAddress deviceAddress)
{
  float temp = sensors.getTempC(deviceAddress);
  int MyTemp = temp*100;
  if (temp == -127.00)
  {
    for (int a=0; a<4;a++) 
    {
      lc.setDigit(0,a,14,false); // Displays EEEE on 7 Segment if temp is -127.00
      delay (5000);              // Wait 5 seconds
      lc.clearDisplay(0);	 // Clear the display
    }
  }
  else   
  {
    lc.setDigit(0,0,(MyTemp%10000)/1000,false);	// Print 10s
    lc.setDigit(0,1,(MyTemp%1000)/100,true);	// Print 1s with decimal point
    lc.setDigit(0,2,(MyTemp%100)/10,false);	// Print 10th digit
    lc.setDigit(0,3,0,false);			// Ignore 100th digit and print "0" instead
  }
}	   
void loop(void)
{
  sensors.requestTemperatures(); // Request temps from DS18B20
  displayDigit(TempSens);	 // Display temp for DS18B20 called TempSens
  // This section is for testing only, it will display the temp for DS18B20 called TempSens on Serial Terminal
  /*
  delay(1000);
   sensors.requestTemperatures();
   Serial.print("TempSens temperature is: ");
   printTemperature(TempSens);
   Serial.print("\n\r");
   */
}

I'm a noob when it comes to coding :roll_eyes:

Thank you

You shouldn't be trying to drive the display with temp info unless you have previously tested the display as a standalone device using test values that mimic temps. Have you done this ?

I have tested the display with this sketch, it displays as expected.

#include <LedControl.h> //For the 7 Segment LED display driven by MAX7219

LedControl lc=LedControl(12,11,10,0); // Pin 12 to Data In, 11 to Clk, 10 to LOAD

void setup(void)
{
 lc.shutdown(0,false);	// Turn off power saving, enables display
 lc.setIntensity(0,10);	// Sets brightness (0~15 possible values)
 lc.clearDisplay(0);	// Clear screen
}
	   
void loop(void)
{
 lc.setDigit(0,0,4,false); //print 10s
 lc.setDigit(0,1,2,true);  //print 1s with decimal point
 lc.setDigit(0,2,5,false); //print 10th digit
 lc.setDigit(0,3,0,false); //ignore 100th digit and print "0" instead
}

Thanks

So I think I figured it out, the float value needs to be converted to an int, then the int needs to be broken into an array, the array characters then need to be reconverted to int, and then the display works. Very Very confusing...

Here is the "working" code, if anyone has a better way of doing this please let me know.

/*
ds18b20 temperature sensor with 7 Segment LED display
 */
// Include Libraries

#include <LedControl.h>		// For the 7 Segment LED display driven by MAX7219
#include <OneWire.h>		// For the one wire functions
#include <DallasTemperature.h>	// For the DS18B20

#define ONE_WIRE_BUS 3                                                        // Data wire is plugged into pin 3 on the Arduino
OneWire oneWire(ONE_WIRE_BUS);                                                // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);                                          // Pass oneWire reference to Dallas Temperature.
DeviceAddress TempSens = {0x28, 0x01, 0xC0, 0xB8, 0x00, 0x00, 0x00, 0x86};    // Assign the address for the 1-Wire temp sensor.
LedControl lc=LedControl(12,11,10,0);                                         // Pin 12 to Data In, 11 to Clk, 10 to LOAD

void setup(void)
{
  Serial.begin(9600);                    // Start Serial Port
  sensors.begin();                       // Start up the Sensor library
  sensors.setResolution(TempSens, 12);   // Set DS18B20 Resolution
  lc.shutdown(0,false);			 // Turn off power saving, enables display
  lc.setIntensity(0,10);		 // Sets brightness (0~15 possible values)
  lc.clearDisplay(0);			 // Clear screen
}

//Used for testing on a serial terminal
/*
void printTemperature(DeviceAddress deviceAddress)
 {
 float tempC = sensors.getTempC(deviceAddress);
 if (tempC == -127.00)
 {
 Serial.print("Error getting temperature");
 } 
 else
 {
 Serial.print("C: ");
 Serial.print(tempC,1);
 Serial.print("0");
 }
 }
*/
void displayDigit(DeviceAddress deviceAddress)
{
  float temp = sensors.getTempC(deviceAddress);
  int MyTemp = temp*100; // *100 to remove the decimal point
    if (temp == -127.00)
  {
    for (int a=0; a<4;a++) 
    {
      lc.setDigit(0,a,14,false); // Displays EEEE on 7 Segment if temp is -127.00
      delay (5000);              // Wait 5 seconds
      lc.clearDisplay(0);	     // Clear the display
    }
  }
  else   
  {
    char dig[4]; //lose the last digit, DS18B20 is not this accurate
    String Digits;
    Digits=String(MyTemp);
    Digits.toCharArray(dig,4);
	int dig1;
	dig1=dig[0]-'0';
	int dig2;
	dig2=dig[1]-'0';
	int dig3;
	dig3=dig[2]-'0';
	lc.setDigit(0,0,dig1,false);
    lc.setDigit(0,1,dig2,true);
    lc.setDigit(0,2,dig3,false);
    lc.setDigit(0,3,0,false);
  }
}	   
void loop(void)
{
  sensors.requestTemperatures(); // Request temps from DS18B20
  displayDigit(TempSens);	 // Display temp for DS18B20 called TempSens
// This section is for testing only, it will display the temp for DS18B20 called TempSens on Serial Terminal
/*  
  delay(1000);
   sensors.requestTemperatures();
   Serial.print("TempSens temperature is: ");
   printTemperature(TempSens);
   Serial.print("\n\r");
*/
}

sakkieg:
Very Very confusing...

It shouldn't be confusing. You need to format your number as four decimal integers, that's all.

It can be done by scaling your float value up to get the integer value you want to display, and then using div and mod operators to extract each digit. Alternatively use snprintf to format it as a decimal string and then subtract '0' from each decimal character to get the corresponding integer value, as you have done. I wouldn't use the String class at any point, and I'd use a FOR loop to process all the digits instead of replicating the code.

O so instead of converting to a string and back to an integer again I now implemented this piece of code:

int split = MyTemp, digits[3], i;
	for (i=0;i<3;i++)
	  {
	   digits[i]=split%10; split=split/10;

The terminal output on this is:
1
12
123

where MyTemp = 123

The 1st digit (1 in this case) displays correct but the rest of the display is blank

the code for displaying the number is:

lc.setDigit(0,0,digits[2],false);
    lc.setDigit(0,1,digits[1],true);
    lc.setDigit(0,2,digits[0],false);
    lc.setDigit(0,3,0,false);

Dear Mr

Did you solve all problems ?

I also interested in this subject

Can you send me the code is working?

Regards