Digital thermometer based on Arduino with 4 digit 7 segment display

DSC01199

1 x Arduino (in my case it was Arduino Mega 2560 rev2)
1 x PCF8574 expander
1 x 4 digit display with common anode (my was FJ-5461BH)
1 x temperature sensor MCP9700AE
8 x 220 Ohm resistors
some connectors

If you want to build your own simple digital thermometer just for fun, this tutorial is for you. All the “ingredients” you can buy on ebay, aliexpress or in your local electronic shop. The temperature sensor can be replaced with other one, but you need to discover聽how to connect it to the rest (especially check the operating voltage and pins). Different will be also way to calculate temperature basing on the output voltage.

For my sensor MCP9700AE it is:

float getTemp() {
float temp = 0.0;
temp = analogRead(A0) * 5 / 1024.0;
temp = temp - 0.5;
temp = temp / 0.01;
return temp;
}

Our simple thermometer display the temperature on 7 segment display. There are many displays on the market, but after you bought any you need to ensure how it works (it means: what pins you should use to control digit and which controls the segments).

FJ5461BH

Why I used the expander? The expander simplified process of communication with display and reduced number of connectors. To control PCF8574 you should use very useful library PCF8574.h (you can download it here and after that you should import the library to your Arduino IDE)

PCF8574

Connect your segments to pins P0-P7 (remember about resistors – red LED should be powered with 2-2.3 V)
A0-A2 to GND
VCC – 5V
GND to GND in your Arduino on somewhere where you have GND 馃檪
SDA, SCL we will use to control segments, but only one thing we need to do is to connect to good pins on your Arduino (marked SDA, SCL).

Output of the temperature sensor I connected to A0 port.

Below you will find a short YouTube clip and whole code with comments.

P.S. My first digit is damaged – 聽that’s why I used only three digit to show temperature 馃槈

#include <PCF8574.h>
#include <Wire.h>

PCF8574 expander;
int digit1 = 2; //ports on Arduino
int digit2 = 3;
int digit3 = 4;
int digit4 = 5;

const int first = 1;
const int second = 2;
const int third = 3;
const int fourth = 4;

float mainTemperature = 0.0; // value to show on 7 segment display
long interval = 1000; // interval at which to measure temp (milliseconds)
long previousMillis = 0; // will store last time temp was updated

int segA = 0;
int segB = 1;
int segC = 2;
int segD = 3;
int segE = 4;
int segF = 5;
int segG = 6;
int DOT = 7;
void setup() {

pinMode(digit1, OUTPUT); //configuring ports as outputs (digits)
pinMode(digit2, OUTPUT);
pinMode(digit3, OUTPUT);
pinMode(digit4, OUTPUT);

expander.begin(0x38); //choose addressing scheme for PCF8574A

expander.pinMode(segA, OUTPUT); //configuring ports as outputs (segments)
expander.pinMode(segB, OUTPUT);
expander.pinMode(segC, OUTPUT);
expander.pinMode(segD, OUTPUT);
expander.pinMode(segE, OUTPUT);
expander.pinMode(segF, OUTPUT);
expander.pinMode(segG, OUTPUT);
expander.pinMode(DOT, OUTPUT);

}

float getTemp() {
float temp = 0.0;
temp = analogRead(A0) * 5 / 1024.0;
temp = temp - 0.5;
temp = temp / 0.01;
return temp;
}

// the loop function runs over and over again forever
void loop() {
unsigned long currentMillis = millis();

if(currentMillis - previousMillis > interval) { //updating temperature only after an interval
previousMillis = currentMillis;
mainTemperature = (mainTemperature + getTemp()) /2 ;
}
updateDisplay(mainTemperature);
}

void updateDisplay(float temp) {
int intTemp = temp * 10;
for (int i = 2; i <= 4 ; i++) { //first digit is damaged in my display ;/
selectDigit(i);
if (i == 3) {
lightNumber(intTemp % 10, true);
}
else {
lightNumber(intTemp % 10, false);
}
intTemp = intTemp / 10;

delayMicroseconds(10);
lightNumber(10, false);
digitalWrite(digit1, LOW);
digitalWrite(digit2, LOW);
digitalWrite(digit3, LOW);
digitalWrite(digit4, LOW);
}
}

void selectDigit(int number) {
switch (number) {
case first:
digitalWrite(digit1, HIGH);
digitalWrite(digit2, LOW);
digitalWrite(digit3, LOW);
digitalWrite(digit4, LOW);
break;
case second:
digitalWrite(digit1, LOW);
digitalWrite(digit2, HIGH);
digitalWrite(digit3, LOW);
digitalWrite(digit4, LOW);
break;
case third:
digitalWrite(digit1, LOW);
digitalWrite(digit2, LOW);
digitalWrite(digit3, HIGH);
digitalWrite(digit4, LOW);
break;
case fourth:
digitalWrite(digit1, LOW);
digitalWrite(digit2, LOW);
digitalWrite(digit3, LOW);
digitalWrite(digit4, HIGH);
break;
}
}

//Given a number, turns on those segments
//If number == 10, then turn off number
void lightNumber(int numberToDisplay, boolean dot) {

#define SEGMENT_ON LOW
#define SEGMENT_OFF HIGH
if (dot) {
expander.digitalWrite(DOT, SEGMENT_ON);
}
else {
expander.digitalWrite(DOT, SEGMENT_OFF);
}
switch (numberToDisplay) {

case 0:
expander.digitalWrite(segA, SEGMENT_ON);
expander.digitalWrite(segB, SEGMENT_ON);
expander.digitalWrite(segC, SEGMENT_ON);
expander.digitalWrite(segD, SEGMENT_ON);
expander.digitalWrite(segE, SEGMENT_ON);
expander.digitalWrite(segF, SEGMENT_ON);
expander.digitalWrite(segG, SEGMENT_OFF);
break;

case 1:
expander.digitalWrite(segA, SEGMENT_OFF);
expander.digitalWrite(segB, SEGMENT_ON);
expander.digitalWrite(segC, SEGMENT_ON);
expander.digitalWrite(segD, SEGMENT_OFF);
expander.digitalWrite(segE, SEGMENT_OFF);
expander.digitalWrite(segF, SEGMENT_OFF);
expander.digitalWrite(segG, SEGMENT_OFF);
break;

case 2:
expander.digitalWrite(segA, SEGMENT_ON);
expander.digitalWrite(segB, SEGMENT_ON);
expander.digitalWrite(segC, SEGMENT_OFF);
expander.digitalWrite(segD, SEGMENT_ON);
expander.digitalWrite(segE, SEGMENT_ON);
expander.digitalWrite(segF, SEGMENT_OFF);
expander.digitalWrite(segG, SEGMENT_ON);
break;

case 3:
expander.digitalWrite(segA, SEGMENT_ON);
expander.digitalWrite(segB, SEGMENT_ON);
expander.digitalWrite(segC, SEGMENT_ON);
expander.digitalWrite(segD, SEGMENT_ON);
expander.digitalWrite(segE, SEGMENT_OFF);
expander.digitalWrite(segF, SEGMENT_OFF);
expander.digitalWrite(segG, SEGMENT_ON);
break;

case 4:
expander.digitalWrite(segA, SEGMENT_OFF);
expander.digitalWrite(segB, SEGMENT_ON);
expander.digitalWrite(segC, SEGMENT_ON);
expander.digitalWrite(segD, SEGMENT_OFF);
expander.digitalWrite(segE, SEGMENT_OFF);
expander.digitalWrite(segF, SEGMENT_ON);
expander.digitalWrite(segG, SEGMENT_ON);
break;

case 5:
expander.digitalWrite(segA, SEGMENT_ON);
expander.digitalWrite(segB, SEGMENT_OFF);
expander.digitalWrite(segC, SEGMENT_ON);
expander.digitalWrite(segD, SEGMENT_ON);
expander.digitalWrite(segE, SEGMENT_OFF);
expander.digitalWrite(segF, SEGMENT_ON);
expander.digitalWrite(segG, SEGMENT_ON);
break;

case 6:
expander.digitalWrite(segA, SEGMENT_ON);
expander.digitalWrite(segB, SEGMENT_OFF);
expander.digitalWrite(segC, SEGMENT_ON);
expander.digitalWrite(segD, SEGMENT_ON);
expander.digitalWrite(segE, SEGMENT_ON);
expander.digitalWrite(segF, SEGMENT_ON);
expander.digitalWrite(segG, SEGMENT_ON);
break;

case 7:
expander.digitalWrite(segA, SEGMENT_ON);
expander.digitalWrite(segB, SEGMENT_ON);
expander.digitalWrite(segC, SEGMENT_ON);
expander.digitalWrite(segD, SEGMENT_OFF);
expander.digitalWrite(segE, SEGMENT_OFF);
expander.digitalWrite(segF, SEGMENT_OFF);
expander.digitalWrite(segG, SEGMENT_OFF);
break;

case 8:
expander.digitalWrite(segA, SEGMENT_ON);
expander.digitalWrite(segB, SEGMENT_ON);
expander.digitalWrite(segC, SEGMENT_ON);
expander.digitalWrite(segD, SEGMENT_ON);
expander.digitalWrite(segE, SEGMENT_ON);
expander.digitalWrite(segF, SEGMENT_ON);
expander.digitalWrite(segG, SEGMENT_ON);
break;

case 9:
expander.digitalWrite(segA, SEGMENT_ON);
expander.digitalWrite(segB, SEGMENT_ON);
expander.digitalWrite(segC, SEGMENT_ON);
expander.digitalWrite(segD, SEGMENT_ON);
expander.digitalWrite(segE, SEGMENT_OFF);
expander.digitalWrite(segF, SEGMENT_ON);
expander.digitalWrite(segG, SEGMENT_ON);
break;

case 10:
expander.digitalWrite(segA, SEGMENT_OFF);
expander.digitalWrite(segB, SEGMENT_OFF);
expander.digitalWrite(segC, SEGMENT_OFF);
expander.digitalWrite(segD, SEGMENT_OFF);
expander.digitalWrite(segE, SEGMENT_OFF);
expander.digitalWrite(segF, SEGMENT_OFF);
expander.digitalWrite(segG, SEGMENT_OFF);
break;
}
}

5 thoughts on “Digital thermometer based on Arduino with 4 digit 7 segment display”

  1. I had to look in the schematic because my arduino uno there are only the pin numbers that are A5 and A4. Another question: What changes do I need to use a display with common cathode?

  2. Cze艣膰 Micha艂.
    Czy w realu tak lekko mruga ten wy艣wietlacz jak na filmiku? Przy u偶yciu 74hc595 wychodzi mniej kodu ni偶 pcf. Og贸lnie fajnie 偶e si臋 pochwali艂e艣 projektem. Ostatnio przez pomy艂k臋 kupi艂em 5 max7219 – nadaje si臋 do wy艣wietlaczy, ale ze wsp贸ln膮 katod膮. A ja w rupieciach mam pe艂no starych 7 segment贸w z wsp贸ln膮 anod膮. I nie wiem co wymy艣li膰, 偶eby to wykorzysta膰 – 1) albo da膰 max7219 i po艂膮czy膰 wszystkie piny za pomoc膮 tranzystor贸w i rezystor贸w, czy 2) da膰 74hc595 i po艂膮czy膰 zgodnie ze sztuk膮 czyli, anody na tranzystorach z rezystorami i rezystory na segmenty, czy 3) kupi膰 pcf8574 i po艂膮czy膰 jak… no w艂a艣nie jak, tak samo jak przy 74hc595?
    Pozdrawiam.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top