03 mar

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.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *