Raspberry Pi

Monitoring Temperature in Raspberry Pi


 
Monitoring temperatures may be a requirement in many of your Raspberry Pi projects. It is relatively easy to do in Raspberry Pi and the components required for this project are not too costly.This article shows you how to use the DS18B20 digital thermometer module to monitor temperature using Raspberry Pi. The article also demonstrates how to create a web app to display the temperature.

Things You Will Need:

To try out the examples in this article, you will need the following:

  1. A Raspberry Pi single-board computer
  2. A power adapter for the Raspberry Pi device
  3. A microSD card with Raspberry Pi OS installed
  4. Network connectivity on the Raspberry Pi device
  5. A Breadboard
  6. 3 pcs of female-to-female connecting wires
  7. Some male-to-male connecting wires
  8. A 10k resistor
  9. A DS18B20 Digital Thermometer module

DS18B20 Digital Thermometer Pinouts

If you hold the DS18B20 digital thermometer as shown in the image below, the first pin will be ground (GND), the second pin will be DATA, and the third pin will be VCC.

DS18B20 Digital Thermometer Pinouts

Circuit Diagram

The circuit diagram of the temperature monitor is shown in the image below.
Circuit Diagram

Here, the PIN2/5V of the Raspberry Pi device should be connected to the PIN3/VCC of the digital thermometer module.

The PIN7/GPIO4 of the Raspberry Pi device should be connected to the PIN2/DATA of the digital thermometer module.

The PIN9/GND of the Raspberry Pi device should be connected to the PIN1/GND of the digital thermometer module.

A 10kΩ resistor should be connected between PIN2 and PIN3 of the digital thermometer module.

You should hold your Raspberry Pi as shown in the image below. Then, the top-left pin will be PIN1. The pin right next to PIN1 will be PIN2. Then, if you move forward one row, the left one will be PIN3 and the right one will be PIN4, and so on.

raspberry pin1-4

Once you have connected all the components to your Raspberry Pi device, it should look something like this:

raspberry pin 279

Take a closer look at how I placed the components on the breadboard.

breadboard raspberry zoom

Once you have connected all the components to your Raspberry Pi device, power on the Raspberry Pi device. Then, connect to your Raspberry Pi device via VNC or SSH.

Reading Temperature Data from DS18B20 Digital Thermometer

The DS18B20 thermometer module uses the 1-wire communication protocol to send data to the Raspberry Pi. By default, the 1-wire interface is not enabled. You can easily enable the interface from the Raspberry Pi configuration tool.

To enable the 1-wire interface, run raspi-config with the following command:

$ sudo raspi-config

sudo raspbery

Select Interfacing Options and press <Enter>.

pi at raspberry interfacing options

Select 1-Wire and press <Enter>.

select 1 wire enter

Select <Yes> and press <Enter>.

yes and enter

Press <Enter>.

one wire interface is enabled

To exit out of the raspi-config utility, press <Esc>.

raspi config

For the changes to take effect, reboot your Raspberry Pi as follows:

$ sudo reboot

sudo reboot

To check whether the w1_gpio and w1_therm kernel modules are loaded, run the following command:

$ sudo lsmod | grep w1

sudo lsmed grep

If for some reason, the w1_therm module is not loaded, then you can manually load it with the following command:

$ sudo modprobe w1_therm

sudo modprobe

Once you have enabled 1-wire communication and loaded the w1_therm module, a new device (28-00000ba693e9, in my case) should be listed in the /sys/bus/w1/devices directory, as you can see in the screenshot below.

$ ls /sys/bus/w1/devices/

1 wire communcation

Navigate to the new directory, as follows:

$ cd /sys/bus/w1/devices/28-00000ba693e9

cd sys bus

You should find a temperature file in the directory, as you can see in the screenshot below.

$ ls -lh

pi raspberry temperature file

The temperature file is a plain text file. You can read the temperature data using the cat command, as follows:

$ cat temperature

cat temperature

As you can see, the temperature data is printed on the console. Here, 30375 means 30.375°C.

temperature data 30375

You can use a programming language, such as Python or Node.js, to parse this temperature data and use it on your app. I will show you how to do that in the next section of this article.

To parse the temperature data using a programming language, you will need the absolute path to the temperature file. You can find this using the readlink command, as follows:

$ readlink -f temperature

readlink -f temperature

Create a Web App to Display Temperature Data:

In this section, you will learn how to parse the temperature data from the DS18B20 thermometer module and display it on a web app.

In this example, I will create an API, which will parse the temperature data from the DS18B20 thermometer module that can be accessed from the API. I will also create a web app that will fetch the temperature data from the API and display it nicely. I will use the Node.js programming language to do so. The codes are uploaded in my GitHub repository shovon8/ds18b20-raspberrypi-api. You may want to check it out if you are having difficulties copying-and-pasting codes from this article.

Node.js is not installed on Raspberry Pi OS by default. But, it is available in the official package repository of Raspberry Pi OS. You can easily install Node.js from the Raspberry Pi OS package repository.

First, update the APT package repository cache with the following command:

$ sudo apt update

sudo apt update

Next, install Node.js and NPM with the following command:

$ sudo apt install nodejs npm

sudo apt install nodejs npm

To confirm the installation, press Y and then press <Enter>.

confirm the installation

The APT package manager will download and install all the required packages. It may take a while to complete.

apt package manager

At this point, Node.js and NPM should be installed.

node js npm

Once Node.js and NPM are installed, check whether the node and npm commands are available, as follows:

$ node --version
$ npm --version

npm version

Upgrade NPM with the following command:

$ sudo npm install --global npm

sudo npm install

NPM should be upgraded.

npm should be upgraded

As you can see, NPM has been updated from version 5.8.0 to version 6.14.8.

$ node --version
$ npm --version

npm --version

Now that Node.js and NPM are installed, create the new project directory ~/ds18b20, as follows:

$ mkdir -v ~/ds18b20

mkdir -v

Navigate to the ~/ds18b20 directory, as follows:

$ cd ~/ds18b20

cd ds18b20

Create the empty package.json file with the following command:

$ npm init --y

npm init --y

Install the Express.js library for the project with the following command:

$ npm install --save express

npm install save express

The Express.js library should now be installed.

express js library

Create the new file server.js in the project directory, as follows:

$ nano server.js

nano serverjs

Enter the following lines of codes in the server.js file.

let express = require('express');
let fs = require('fs');
let server = express();
const PORT = 8080;
const WEBROOT = './public';
server.get('/', express.static(WEBROOT));
server.get('/temperature', (req, res) =&gt; {
   let tempDataPath = '/sys/bus/w1/devices/28-00000ba693e9/temperature';
   let temperature = fs.readFileSync(tempDataPath, {encoding: 'utf8', flag: 'r'}) / 1000;
   res.json({temperature, rangeStart: -55, rangeEnd: 125});
});
server.listen(PORT, () =&gt; {
   console.log(`server running on port ${PORT}`);
});

Once you are done, press <Ctrl> + X followed by Y and <Enter> to save the server.js file.

ctrl xy serverjs

Here, line 1 imports express, and line 2 imports the fs module.

express fs module

Line 4 initializes express.

line 4 initializes express

Line 6 and 7 define the PORT and WEBROOT constant variables, respectively. The API and webserver will run on PORT (which is 8080, in this article), and the webserver will serve static contents from the WEBROOT (which is the public/ directory inside the project directory in this article).

line 6 7 port webroot

Line 9 is used to configure express to serve static contents from the WEBROOT.

line 9 configure

Lines 11-15 define the API endpoint /temperature, which will be used to get the temperature data into JSON format.

In line 12, the tempDataPath variable holds the absolute path to the temperature file of the DS18B20 digital thermometer module, shown in an earlier section of this article.

In line 13, the temperature data is read from the temperature file using the Node.js fs module, and the temperature data is stored in the temperature variable.

In line 14, the temperature data is printed in JSON format. The DS18B20 digital thermometer module can measure between the temperatures -55°C to 125°C. I have added that in the JSON output using the rangeStart and rangeEnd properties.

line 14 range

Finally, line 17-19 runs the API and webserver on PORT (which is 8080, in this article).

line 17 19 port

Create a public/ directory in the project directory, as follows:

$ mkdir -v public

mkdir -v public

Run the server.js program with the following command:

$ node server.js

node serverjs

The server should be running on port 8080.

running port 8080

You can access the temperature data of the DS18B20 thermometer module from the /temperature endpoint of the API.

To test whether you can get the temperature data from the API, run curl, as follows:

$ curl -s http://localhost:8080/temperature | json_pp

As you can see, the temperature data is printed on the console in JSON format. So, the API is working.

temperature json

Press <Ctrl> + C to stop the server.

ctrl c stop server

Now, I will create a webpage that will request the API server for the temperature data and display it nicely on the page. The temperature data will be updated every 5 seconds.

Create a new index.html file in the public/ directory of the project, as follows:

$ nano public/index.html

nano public indexhtml

Enter the following lines of codes in the index.html file.

<!DOCTYPE html>
<html>
<head>
<title>Temperature Monitor</title>
<style type="text/css">
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');

body, * {
   margin: 0;
   padding: 0;
   font-family: 'Roboto', sans-serif;
   background: black;
}

.progress-container {
   display: fixed;
   width: 100%;
   height: 15px;
   top: 0;
   left: 0;
   background: black;
}

#progress {
   display: block;
   box-sizing: content-box;
   width: 0%;
   height: 100%;
   background: rgb(0,101,181);
   background: linear-gradient(90deg, rgba(0,101,181,1) 0%, rgba(59,255,226,1) 100%);
}

.content-container {
   display: block;
   background: black;
   text-align: center;
}

.content-container h1 {
   color: white;
   font-size: 10em;
}

.content-container span {
   display: block;
   color: #02dd2e;
   padding-bottom: 2em;
}

</style>
</head>
<body>

<div class="progress-container">
   <div id="progress"></div>
</div>

<div class="content-container">
<h1 id="tempContainer">00.00°C</h1>
<span>Temperature updates in every 5 seconds</span>
</div>

<script type="text/javascript">
window.addEventListener('load', main);

function main() {
   function getTemperature() {
      var http = new XMLHttpRequest();
      http.onreadystatechange = function() {
         if (this.readyState == 4 && this.status == 200) {
           updateTemperature(JSON.parse(this.responseText));
         }
   };
   http.open("GET", "/temperature", true);
   http.send();
   }

   function updateTemperature(data) {
      var element = document.getElementById("tempContainer");
      element.innerText = parseFloat(data.temperature).toFixed(2) + "°C"
      console.log(data.temperature);
   }

   function updateProgress(percentage) {
      var element = document.getElementById('progress');
      element.style.width = percentage + "%";
   }

   function app() {
      var percentage = 0;
      var id = window.setInterval(function() {
         updateProgress(percentage);
         if(percentage == 100) {
            getTemperature();
            percentage = 0;
            window.clearInterval(id);
      }
      percentage+=1;
   }, 50);
}

function start() {
   getTemperature();
   window.setInterval(app, 5000);
}

start();
}
</script>
</body>
</html>

Once you are done, press <Ctrl> + X followed by Y and <Enter> to save the index.html file.

ctrl x y index html

The HTML file index.html is easy to understand. It is the format in which the temperature data will be displayed in the web app.

Here, lines 53-55 are used to display a progress bar, and lines 57-60 are used to display the temperature.

line 53-55 progress bar

Lines 5-49 are used to decorate the web app nicely using CSS (Cascading Style Sheet).

line 5-49 css

Lines 62-109 are used to make the web app functional. The JavaScript codes are used to animate the progress bar, fetch the temperature data from the API, and display the information.

Line 63 runs the main function once the web app is loaded in the browser.

line 63 main function

The main function is very long. It spans from line 65 to line 108. Inside the main function, we have some other functions, such as getTemperature, updateTemperature, updateProgress, app, and start.

The updateProgress function, in lines 83-86, takes the percentage of progress as the input and updates the progress bar.

updateProgress

The updateTemperature function in lines 77-81 takes the temperature data as the input and updates the web app with the temperature data.

updateTemperature

The getTemperature function in lines 66-75 makes a request to the /temperature endpoint of the API and gets the temperature data. Once the data is received, it calls the updateTemperature function with the data. The updateTemperature function then updates the web app with the new temperature data.

getTemperature

The app function, in lines 88-99, animates the progress bar and requests the temperature data from the API every 5 seconds.

appfunction

The start function, in lines 101-104, starts the web app.

startfunction

Open the package.json file with the nano text editor as follows:

$ nano package.json

nano package json

Change main to server.js and add the new script serve in the scripts section, as marked in the screenshot below.

Once you are done, press <Ctrl> + X followed by Y and <Enter> to save the package.json file.

ctrl xy packagejson

Now that everything is ready, run the web app and the API with the following command:

$ npm run serve

npm run serve

The server should be running on port 8080.

server should be running port 8080

Now, open a web browser on your Raspberry Pi device and visit http://localhost:8080. The temperature data from the DS18B20 digital thermometer module should be displayed on your web browser, as you can see in the screenshot below.

Temperature Monitor Chromium

The temperature data should be updated every 5 seconds.

Temperature Monitor every 5 seconds

As you can see, the temperature is changing every 5 seconds.

Temperature Monitor as you can see

If you want to access the web app from another computer on your network, you will need to know the IP address of your Raspberry Pi device.

You can find the IP address of your Raspberry Pi device with the following command:

$ hostname -I

As you can see, the IP address of my Raspberry Pi device is 192.168.0.107. This will be different for you. So, make sure to replace the IP address from now on.

Raspberry Pi IP Address

Once you know the IP address of your Raspberry Pi device, you should be able to access the web app from any computer on your network using a web browser. Just visit http://192.168.0.107:8080, and the web app should show the temperature data from the DS18B20 digital thermometer module.

Conclusion

In this article, you learned how to use the DS18B20 digital thermometer module in Raspberry Pi to measure the temperature. You also learned how to create a Node.js API for showing the temperature data in a web app, which accesses the temperature data from the API and displays it. This article should help you get started with Raspberry Pi temperature monitoring with the DS18B20 digital thermometer module and IoT with Raspberry Pi.

About the author

Shahriar Shovon

Freelancer & Linux System Administrator. Also loves Web API development with Node.js and JavaScript. I was born in Bangladesh. I am currently studying Electronics and Communication Engineering at Khulna University of Engineering & Technology (KUET), one of the demanding public engineering universities of Bangladesh.