Introduction: Thermoscope - 16x2 LCD Thermometer With S/M/H Graphs

About: Sucks at soldering, [hopefully] compensates with coding.

I've started playing with a temperature sensor and I've noticed its response time to changes (e.g. entering an air-conditioned room) was minutes, and it was hard to tell "are we there yet?".

This made me add a scope-like history graph to my digital thermometer, and it really helps see at a glance whether there's an up or down trend or just random fluctuations.

There's a button that toggles between Second/Minute/Hour modes. Current temperature (top left of display) is updated every second (regardless of mode). Graph shows average temperatures for last [up to] 8 H/M/S (depending on mode).

Values are normalized so that the lowest value is represented by a single-pixel bar and the highest one by a 7-pixel one.

The second line of the display shows minimum-maximum values for the normalized graph. This gives a sense of scale (e.g. if they're 0.1°C apart, what we see on the graph is noise).

This code (and the datalogger library that comes with it) can also be useful as a "poor people's scope" for other kinds of sensors.

Update: M/H modes now show a countdown in seconds/minutes until next update (see photo).

Another update: My wife decided to use this to control a rice-cooker with a relay in order to make yogurt (keep the temperature between 30-40°C). This is still a work in progress, but there's a photo with plenty of annotations on it in case you want to start making yogurt right away ;)

Step 1: Let's Make One

I did this using a Grove starter kit from Seedstudio. If you have one of those (even the old versions of the starter kit) and an Arduino (of course), you've got all you need.There are 3 ways of doing this:

  1. With the kit's Grove shield (see photo).
  2. With the Grove components, but with Grove breakout cables instead of the shield (see photos of a such a cable, and a breakout-cable-based Thermoscope implementation). [The could be many scenarios where you'd choose not to use the shield even if you have it].
  3. With non-Grove components.

The thing with the LCD display

If you're using any of the first 2 options and you have an old Arduino and the LCD display doesn't work (or works, but not if it's on battery power), take a look at Make Seedstudio's I2C LCD monitor work with an old Arduino.

If you're not using the display that came with the kit, you can simply use the library that comes with your 16x2 character LCD display instead of rgb_lcd and the code should work as is (it contains no setRGB() or other model-specific calls).


  • An Arduino.
  • A temperature sensor connected to A0. Note: if you're not using the one I used, analog2Celsius() might need recalibration (it uses "voodoo constants" that could be sensor-specific). Best is to use sample code that comes with your sensor.
  • A 16x2 character LCD display.
  • A button connected to D4 (if it's a simple momentary switch, you'll also need a pull-up/down resistor for it).


Here it is.

If you want a "poor people's scope" for any other kind of sensor, just change analog2Celsius() to something that makes sense for your sensor, and change degSymbol (the degree character) to something funky that best represents the measuring unit of your ghost/gold/IQ/debt sensor.

You may also find the datalogger.{cpp,h} library useful for handling and aggregating sensor samples.


Sensors Contest

Participated in the
Sensors Contest