Category Archives: Linux

Monitoring Temperature With Raspberry Pi


The Problem:

I recently remodeled my home office and I now have a dedicated closet for my electronics (Server, NAS, AV Receiver, etc.) During the build I planned for heat remediation by installing an exhaust fan that dumps air from the closet into my adjoining office. However, the temperature in the closet hovers around 90°F (32°C), even with the fan on. Although this temperature is within hardware thresholds, it’s a bit warmer than I would prefer. To get a better understanding of my heat dissipation needs, I decided to monitor and record temperature fluctuations over several days to see what temperature ranges I was experiencing.

Monitoring temperature levels is a perfect project for the Raspberry Pi. I have used an analog TMP36GZ low voltage temperature sensor before in an Arduino project but this would be my first attempt at using the Raspberry Pi’s GPIO pins. Unfortunately, after a bit of research, I discovered that my analog temperature sensor wouldn’t work with the Raspberry Pi’s “digital only” IO pins. While I could have prototyped a solution using an ADC and some spare components, I really wanted a simple build so I could just start coding on the Pi.

The solution to my problem was a DS18B20 Digital Temperature Sensor IC which I found on The DS18B20 uses the 1-Wire communication bus which is perfect for the BCM GPIO4 pin (PIN 7) on the Raspberry Pi. Other caveats, you can work with the DS18B20 from the Linux terminal, and you can connect multiple 1-Wire devices, in series, to PIN 7.

The Build:

I had some spare CAT5e cable so I stripped and soldered 3 wires to the three pins on the sensor – orange for +3.3v, brown for ground, and green for data. Also, the DS18B20 requires a pull-up resistor between the power and data leads.

DS18B20 CAT5e connection

Then, I used electrical tape to insulate the exposed areas and I shrink-wrapped everything to protect the connections.

DS18B20 Shrink-wrapped

To the other end of the CAT5e cable I attached three female jumper wire cable housing connectors. These will principally be used for quick connections to a splitter rather than connecting directly to the Pi because I need to connect several devices to a single pin (specifically PIN7 for 1-wire).

DS18B20 Female Connectors

Next, I manufactured three tiny Y-splitters (2 male to 1 female) to join the VDD, DQ, and GND lines from 2 sensors before connecting to the Pi.

DS18B20 Y-Splitter

Finally, I made a second sensor and attached both to the Raspberry Pi using the following arrangement.
DS18B20 Schematic

Here is the finished build. Note the three splitters are plugged into PIN1 (orange/3.3v), PIN6 (brown/GND), and PIN7 (green/data).


The Code:

After connecting the DS18B20’s to the Raspberry Pi, you can interact with the devices using the below terminal commands. Note, your device IDs will be specific to your 1-Wire devices. In my case, my devices are 28-0000055f311a and 28-0000055f327d.

Here is what my terminal window looks like after running the above.

Click for larger image

In the terminal window above, the interesting information from reading from the device is the first line ending with “YES” – which means no errors – and the second line ending with “t=” followed by the temperature in thousandths of degrees Celsius (°C * 1000). Using this information, we can divide the temperature by 1000 to get Celsius and convert to Fahrenheit using…
°F = °C * (9/5) + 32.

Once we verify that the DS18B20 is operating correctly using terminal commands, we can construct a python script to read from the devices and write the temperature to a CSV file. Later we will plot the temperature readings to see how much they fluctuate over time.

Once created, you can run the above Python script from the terminal by using the following command.

Running the above terminal command a few times produces output, like the below, in a CSV file. Note that I have 2 Temperature sensors connected to the Pi. One is hanging in the center of the top of the closet, measuring ambient temperature, and the other is attached to the hottest exterior surface on my server.

Device TimeStamp Temp °F
28-0000055f311a 2014-05-21 22:21:02.585486 80.9366
28-0000055f327d 2014-05-21 22:21:02.585486 119.3
28-0000055f311a 2014-05-21 22:21:09.331944 81.05
28-0000055f327d 2014-05-21 22:21:09.331944 119.4116
28-0000055f311a 2014-05-21 22:21:13.082604 81.05
28-0000055f327d 2014-05-21 22:21:13.082604 119.3
The Schedule:

Now that we have a script to collect temperature data and save it to a CSV file, we need to schedule it to run periodically. In my case, I wanted to run the script every minute of every day for several days. To schedule the python script, we can use crontab from the terminal.

While in edit mode, add a crontab job using the following syntax. Note that this command should be all on one line in crontab.

The five asterisks (*) mean to run the job every minute, every hour, every day of month, every month, and every day of the week. The part about “> /dev/null 2>&1″ just means don’t save the output or errors in a log and don’t show anything on any screens (i.e. run silently even if errors occur).

The Results:

After a few days of collecting data, I can plot the results to see how effective I am at dissipating heat from my closet. Below is a chart of the output after running the Python script, via crontab, for several days.


Now that I have a baseline, I can experiment with different heat dissipating methods to find what works best to keep my electronics cool. When I’m done monitoring my electronics closet, I can see myself redeploying the rig to other projects such as attics, crawl spaces, automotive projects, and mini-fridge hacking. Let me know in the comments if you come up with your own temperature monitoring projects.

Running Linux Commands from PowerShell.

In my lab, I occasionally need to automate maintenance tasks that involve Windows and Linux systems. For example, I need to backup Windows directories to a Linux-based NAS device, compress and decompress files, delete old backups, etc. Sometimes, what I need to do is run SSH commands from PowerShell in a dynamic way. I found some examples online but they only ran one command at a time. For me, it would be better if I could dynamically create a set of commands; then have those all run consecutively in one SSH call.

To do this, first you need to define the statements you want to run in an array. In my case, I wanted something dynamic so I came up with the following.

Basically, the above commands will display the Linux distribution release info, change the working directory, print the working directory, unzip a file, and then remove the zip file. Note the “;” after each command is required. Alternatively, you can use “and list” (&&) or “or list” (||) instead of “;” if you understand how they work.

Now that I have the SSH commands that I want to run, how do I pass them to Linux? Manually, when I want to remotely connect to Linux in an interactive way, I use PuTTY. However, by itself, PuTTY doesn’t have a Windows command-line interface. Thankfully, the makers of PuTTY released Plink, aka “PuTTY Link”, which is a command-line connection tool for PuTTY. Armed with this new information, I downloaded Plink to the same directory as PuTTY and added an alias to my PowerShell script.

Now that I have an alias for Plink, I can pass my array of SSH commands directly to my Linux machine in one line of code.

One thing that is nice about this approach, the output of the SSH commands are displayed in the PowerShell console. That way, you can see if any Linux-based warnings or errors occur.

In the above example, I’ve added my user name and password as parameters in the command-line. Obviously, in a production environment this is not desirable. You can get around this by using public keys for SSH authentication. For more information, check out PuTTY’s help documentation. At the time of this writing, Chapter 8 covered how to set up public keys for SSH authentication.

Here is the finished script.

Some notes worth sharing… Initially, my instinct told me that zipping a large directory locally on the NAS device would be faster than trying to remotely zip the files from my Windows PC. I assumed the network overhead of downloading the files and then uploading the compressed archive back to the NAS would be a bottleneck. In fact, in my case, it was faster to do it remotely from Windows. This is because the limited RAM and CPU for my consumer grade NAS device were quickly overwhelmed by the compression task. My Windows box, with a dual core CPU, 4GB RAM, a Gigabit NIC, and an SSD could compress the files faster than the NAS device despite having to send the data over the network both ways. Some tasks, such as deleting large directories were significantly faster when ran locally on the NAS. Therefore, you will have to experiment to find out what works best for you.