The sensor

It gets very hot in my office. A few of us joked that we should build a temperature monitor to gather temperature data just to see how hot it gets over a period of time.

I started investigating to see what options there were, ideally it would be good to have the data logged so that we can perform manipulations and graphing at a later date.

Luckily my local electronics store (Jaycar Electronics) sells a multitude of sensors that can be connected to Arduino’s and other such microcontrollers. Looking on their website I found the Digital Temperature Sensor Module (XC3700). This small chip encapsulates the far more popular DS18B20 temperature sensor however this sensor requires a number of extra little bits of electronics such as resistors to stabilise the power input whereas the XC3700 includes all the required components to be connected to 5V power.

RaspberryPi
RaspberryPi with temperature sensor connected

Connecting the XC3700 to the RaspberryPi entails connecting to the 5V pin, Ground pin, and Data pin. A useful resource is the following: https://pinout.xyz/pinout/1_wire which contains information about connecting devices to the RaspberryPi which use the One-Wire protocol that this chip uses. It talks about pull-up resistors however this can be ignored thanks to this already being included on the XC3700.

Once the device is connected and the kernel module loaded the device should present itself as a file which can be read from to initiate a temperature read. This file should be under the /sys/bus/w1/devices root.

pi@ceres:/sys/bus/w1/devices $ ls
28-0417525b02ff  w1_bus_master1

As you can see here 28-0417525b02ff is a folder (actually a symlink to a folder) which represents things to do with our temperature sensor.

pi@ceres:/sys/bus/w1/devices/28-0417525b02ff $ ls
driver  hwmon  id  name  power  subsystem  uevent  w1_slave

w1_slave is the file that if we read it will initiate a temperature read.

pi@ceres:/sys/bus/w1/devices/28-0417525b02ff $ cat w1_slave 
6c 01 4b 46 7f ff 0c 10 2b : crc=2b YES
6c 01 4b 46 7f ff 0c 10 2b t=22750

t=22750 is the current temperature in degrees celcius when divided by 1000.

The code

Great, so we’re able to detect the current temperature, but this isn’t overly ergonomic, for starters we want to be able to get the current temperature at time intervals and do something with the data.

I’ve been very interested in Rust lately and this afforded me the opportunity to write something less contrived, so I wrote a small little command line tool to read from the temperature sensor and then submit that information to an Influx database.

The code is available here: https://gitlab.com/stewartmalik/temperature

I do warn you though, it’s not pretty.

Now however you can perform the following:

pi@ceres:~ $ ./temperature.bin /sys/bus/w1/devices/28-0417525b02ff/w1_slave
Temperature: 22.437 ℃

This reads the current temperature from the device, prints it to the screen and also submits it via HTTP to an Influx database on the same device. This command has then been cron’d to run every 1 minute.

Now that we can store the data we can graph it via Grafana as in the header image and can measure the temperature and complain even more it’s too hot.

I should note that the temperatures in the header image are from a room that is upstairs and receives full sunlight and not my office.

From here I want to improve the code of the little Rust program to see if I can make it a bit more efficient. I initially used clap as I thought I was going to need more command line options than I ended up needing. This is likely adding a significant amount of bloat into the final binary.