# Project: Arduino temperature reading using a DS18B20 with 74HC595 / 4x Seven Segment displays

#### Remembermyname

Joined Sep 6, 2015
91
Greetings,
Recently, I had been trying to build an Arduino temperature reader using a DS18B20 and display the output on 4x Seven Segment Displays. With a lot of trial and error (mostly errors), this was completed. This project was set up using an Arduino Nano driving a single multiplexed 74HC595 to drive the displays. It is capable of reading the full range of the DS18B20 (-55°C to +125°C (-67°F to +257°F)). The code is currently set up to read Fahrenheit degrees but can easily be changed to read Celsius. It has been tested on its low end with an inverted can of keyboard duster to -48.0F to its high end with boiling water to ~210.0F. I had no intention of displaying an F or a C in the display since I knew which temperature it was being used for otherwise, I'd have to add a 5th digit.

This was built using a breadboard. Granted, it would have looked better with less wiring using a single 4 digit display. The 4 individual digits were wired for the same purpose as this is what I had on hand.

Below is the schematic:

The schematic was made with gSchem which is part of the gEDA suite

Below is the zip file containing the schematic including the custom symbols that need to be installed for the schematic:
This can be used later if a PCB is to be designed out of it.

*****

The following parts for this build are required:

Parts list:
1x Arduino Nano
1x 75HC595 8bit shift register - 16 pin DIP IC
1x 4.7k ohm 1/4 watt resistor
1x DS18B20 Maxim/Dallas temperature IC (can come in TO-92 case or prebuilt into a sealed cable assembly)
8x 330 ohm 1/8 watt resistors
4x 5011 Common Anode 7 segment LED display*

* You can also use a 4 digit 7 segment display module to connect to the 74HC595. It will save you a LOT of tedious breadboard wiring.

*****

I wanted to build this as a basic starting platform for other projects such as a deep freezer controller with LED readout. The use of the single 74HC595 rendered the Arduino with free pins to work with control relays, etc. The readout is formatted to display numbers without leading zeros and to the tenth's decimal place. The code involved was taken from http://www.pial.net/arduino-controlling-a-4-digit-seven-segment-display/ and modified. The code uses the DallasTemperature and OneWire libraries. This code uses 5054 bytes (16% of program storage space).

Compiled with Arduino IDE 1.6.7

The OneWire.h and DallasTemperature.h library files are required and need to be installed to your Arduino IDE

https://www.pjrc.com/teensy/td_libs_OneWire.html

Which will lead you to the OneWire GitHub page to retreive the latest version of the library at:
https://github.com/PaulStoffregen/OneWire

The OneWire library version used in this build is 2.3.3 and is pasted below:

View attachment OneWire-master.zip

https://milesburton.com/Dallas_Temperature_Control_Library (Down at the time of this posting)

The needed Dallas temperature control library can be found here:
https://github.com/milesburton/Arduino-Temperature-Control-Library

The DallasTemperature control library version used in this build is 3.7.7 and is pasted below:

View attachment Arduino-Temperature-Control-Library-master.zip

The code is pasted below:

C:
/*
* Modified with additions to original code 3/22/2017- Lawrence Hallman
*
* This code was taken and modified from the original code which can be found at:
* http://www.pial.net/arduino-controlling-a-4-digit-seven-segment-display/
*
*/
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
const int ledPin =  13;// LED connected to digital pin 13
const int latchPin = 8;// Pin connected to ST_CP of 74HC595
const int clockPin = 9;// Pin connected to SH_CP of 74HC595
const int dataPin = 10;// Pin connected to DS of 74HC595
const int digitPins[4] = {
3,4,5,6}; //pins to control the 4 common anode pins of the display
const byte digit[12] = //seven segment digit bits + blank + minus
{
B00111111, //0
B00000110, //1
B01011011, //2
B01001111, //3
B01100110, //4
B01101101, //5
B01111101, //6
B00000111, //7
B01111111, //8
B01101111, //9
B00000000, //Blank
B01000000  //-
};
int digitBuffer[4] = {
1};
int digitScan = 0;
int soft_scaler = 0;
float tempC, tempF;
int tmp;
boolean sign = false;
void setup()  {
TCCR2A = 0;
TCCR2B = (1<<CS21);
TIMSK2 = (1<<TOIE2);
TCNT2 = 0;
pinMode(ledPin, OUTPUT);
for(int i=0;i<4;i++)
{
pinMode(digitPins[i],OUTPUT);
}
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
sensors.begin();
}
ISR(TIMER2_OVF_vect) {
soft_scaler++;
if(soft_scaler==15)
{
refreshDisplay();
soft_scaler = 0;
}
};
void refreshDisplay()
{
for(byte k=0;k<4;k++)
{
digitalWrite(digitPins[k], LOW);
}
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
digitalWrite(latchPin, HIGH);
delayMicroseconds(50);
digitalWrite(digitPins[digitScan], HIGH);
digitalWrite(latchPin, LOW);
if(digitScan==1)
{
shiftOut(dataPin, clockPin, MSBFIRST, ~(digit[digitBuffer[digitScan]] | B10000000)); //inserting the dot
}
else
{
shiftOut(dataPin, clockPin, MSBFIRST, ~digit[digitBuffer[digitScan]]);
}
digitalWrite(latchPin, HIGH);
digitScan++;
if(digitScan>3) digitScan=0;
}
void loop()
{
digitalWrite(ledPin, HIGH);
sensors.requestTemperatures();
tempC = sensors.getTempC(insideThermometer);
tempF = DallasTemperature::toFahrenheit(tempC);
tmp = int(tempF*10);
if (tempF < 0){
sign = true;
tmp = abs(tmp);
}
else{
sign = false;
}
if (int(tmp)/1000 == 0){
digitBuffer[3] = 10;
if (sign){
digitBuffer[3] = 11;
}
}
else{
digitBuffer[3] = int(tmp)/1000;
}
if (int(tmp)/1000 == 0 && (int(tmp)%1000)/100 == 0) {
digitBuffer[2] = 10;
if (sign){
digitBuffer[2] = 11;
digitBuffer[3] = 10;
}
}
else{
digitBuffer[2] = (int(tmp)%1000)/100;
}
digitBuffer[1] = (int(tmp)%100)/10;
digitBuffer[0] = (int(tmp)%100)%10;
digitalWrite(ledPin, LOW);
delay(500);
}
The code along with the needed libraries is contained in the zip file below:

Many thanks to @ErnieM for your help in making this possible.

Last edited:

#### Remembermyname

Joined Sep 6, 2015
91
If you wish to build the circuit on a breadboard, the schematic is complete but I feel that it can appear confusing or overwhelming to some readers, especially in the 74HC595 to digits area. So, I've broken the schematic down into 12 assembly steps to hopefully help ease this process if you are using 4x single common anode displays. Please be aware that some common anode displays may differ in pinout designation. Please refer to your device's data sheet for the best information.

I've included the pinouts explanation for a generic 5011 Common Anode 7 segment LED display, the 74HC595 (16 pin DIP package) and the Arduino Nano for reference. These are pasted below:

The 5011 Common Anode 7 segment LED display

The 74HC595 Shift Register (16 pin DIP)

The Arduino Nano

#### Remembermyname

Joined Sep 6, 2015
91
Steps to building the diplay portion on the breadboard:

In my assembly, I used an 830 pin dual bus breadboard. I installed the digit modules first towards one end but I left three pins spacing from the end for the DS18B20.
You may notice that in the schematic, pins 3 and 8 (CA1 and CA2) are connected. I placed a jumper accross the breadboard gap for this under the display module. Most displays have the common anodes already connected internally so in most cases, this may not be necessary. I simply put it there just in case.

Picture the digits from left to right. Digit 4 will be placed towards the DS18B20 end of the breadboard. If you have a larger breadboard, you're in luck. The digits wiring was tight.

Step1
Connect the G segments of each digit.

Step 2
Connect the F segments of each digit.

Step 3

Connect the A segments of each digit.

Step 4
Connect the B segments of each digit.

The top half of the display assembly is finished. Now for the bottom half.

Step 5
Connect the E segments of each digit.

Step 6
Connect the D segments of each digit.

Step 7
Connect the C segments of each digit.

Step 8
Connect the Decimal Point segments of each digit.

The display assembly is complete. Each segment should be paralleled. Now, one resistor for each segment can be installed. The resistors together will take up 8 rows from the innermost digit. One end of each resistor connected to the paralleled segments, the other to the 74HC595

Last edited:

#### Remembermyname

Joined Sep 6, 2015
91
Step 9
Install the 74HC595. Each 330 ohm resistor represents a segment for each display as the output to all four digits is multiplexed.
Install the Arduino Nano on the other end of the breadboard and connect the power and ground to the 74HC595.

Step 10
Now, connect the Latch, Data, and Clock pins of the 74HC595 to the Arduino Nano.

Step 11
Now, connect the anodes of each display separately to the Arduino Nano.

Step 12
Install the DS18B20 and the 4.7k ohm resistor.
From step 1, 3 spaces are open on the digits end of the breadboard. You can actually place the DS18B20 anywhere on the board you see fit. I found convenient to place it on the digits end. Connect the Power, Ground and Data pins of the DS18B20. Install a 4.7k ohm resistor between the Power and Data pins. Then connect the data to the D2 pin on the Arduino Nano.

*Be certain to mind the pinouts of the DS18B20. It doesn't like being connected backwards to power and ground.*

Connect the Arduino Nano to a USB and your Arduino IDE, send in the sketch to the Arduino.

All images, schematics files and codes in this thread are included in the zip file below.

Last edited:

#### Remembermyname

Joined Sep 6, 2015
91
Awesome! Thank you!

#### MMcLaren

Joined Feb 14, 2010
845
I'm getting ready to try this out using a small multiplexed display from SparkFun and an ATMEGA328P-PU (Arduino "breadboard" configuration w/8-MHz internal oscillator). Just need to load your sketch and hook up a DS18B20. Once that is working I'll try to implement the PWM brightness control and pass along those results, if you're interested.

Cheerful regards, Mike

Last edited: