The floor heating system in the living room of my home operates with four loops of tubing embedded in the floor slab. The temperature of the water inside these loops is monitored in the manifold cabinet by Dallas DS18B20 sensors. There are eight of these sensors: a sensor is attached to each loop where the tube enters the floor or resurfaces from the floor. Two additional sensors monitor the manifold itself: the temperature of the water arriving via the central heating pipes and the temperature of the return manifold water. All sensor wires converge into a junction box that contains a miniboard with the necessary connectors. Mounted on the miniboard are two DHT11 relative humidity sensors. From the junction box a d-sub cable runs to an Arduino Nano mounted on a display board (figure 1) equipped with a 3.5 inch color TFT display. After three years of service it was time for a software update. This paper describes the differences between the original sketch and the updated sketch. Hardware was cleaned and serviced but otherwise remained unchanged.
Figure 1: The display board: left: after software update, right: before – three years of service.
An earlier paper* describes the wiring and the physical construction of a floor heating loop monitoring system. The floor heating loops and the manifold from which the loops emerge are shown in figure 2. The monitoring of loop water temperatures is governed by an Arduino Nano that receives data from ten Dallas DS18B20 temperature sensors plus two DHT11 relative humidity sensors. The DS18B20 sensors are attached to the loop tubes where these enter the floor slab (‘loop in’) or resurface (‘return’). Central heating water entering and leaving the manifold is also monitored by DS18B20 sensors (‘SUPPLY’ and ‘RETURN’). In total there are 10 DS18B20 sensors involved. Display of the parameters is on a 3.5 inch color TFT screen. The display is shown at a larger format in figure 3.
Figure 2: Manifold and tubing belonging to the floor heating system before the cement floor slab was poured.
Figure 3. Left: the original sketch: no-nonsense display of all the relevant temperatures. Right: The software update highlights the manifold in- and output temperatures, and it introduces a visually attractive, easy to read graphical display.
The monitoring system has been in service for three years. After three winters of experience with data presented in the way illustrated in the left panel of figure 3 it was decided to put higher emphasis on the input- and output temperatures of the manifold. Main argument for this was that the floor-in and return temperatures of the loops remain remarkably stable during the heating season, hovering between 23 centigrade loop in temperature and 21 centigrade loop return temperature. More interesting is the manifold input- and output temperature especially since a new central heating unit was installed last summer. In the mean time I became aware of an exciting graphical temperature representation for a 2.8 inch TFT screen published in 2016 on Instructables and on Arduinoforum.nl by Danny van den Brande**. Preceding this publication with one year is an article by Bodmer*** on Instructables describing a graphical power meter built on the same main graphical subroutines as in van den Brande’s temperature display. In the introduction of his article Bodmer writes: “The meter drawing function has been ‘parameterised’ so the meter size, position, range, units and colour scheme can be easily configured to suit your own needs…… the display is a 2.2″ 320 x 240 pixel TFT colour display with the ILI9341 driver chip, this is driven by an Arduino UNO.”
These remarks by Bodmer, the appealing illustrations in his web article, and also Danny van den Brande’s successful design formed a strong stimulus to update my floor loop temperature sketch by implementing Bodmer’s subroutines. This meant that Bodmer’s subroutines had to be adapted to the 3.5 inch portrait oriented 320×480 TFT display mounted on the display board. This screen is controlled by an ILI9481 chip.
Arduino compatible color TFT displays
A range of manufacturers markets for the Arduino Uno family color LCD TFT displays with dimensions up to 320×480 pixels and 3.5 inch screen diagonal. Occasionally a 4 inch 320×480 pixel display is available. On the upper side of the market are the versatile and robust 320×480 Adafruit 3.5 inch (www.adafruit.com) and Waveshare 4 inch displays (www.waveshare.com) capable of displaying 18-bit color. On the lower side of the market a range of cheap Chinese-brand 2.2 – 3.5 inch, 240×320 or 320×480 TFT displays dominate the scene. These screens are available via trade platforms like Aliexpress, Banggood and the like. Driver chips vary. My favorite display is the 3.5 inch, 320×480 pixel color TFT driven by an ILI9481 controller chip. The main attractiveness of this display lie in its relatively large size and that it produces readable characters in nice colors: it has enough pixels on board to get decent numbers, text and graphics. Not unimportant is that the controller chip is fully supported by Adafruit’s Adafruit_GFX library and David Prentice’s MCUFRIEND_kbv library.
Graphical capabilities of a 3.5 inch 320×480 pixel TFT display
The above mentioned libraries support drawing lines, rectangles, fills, triangles and circles. Each individual pixel of the total of 153,600 pixels can be controlled. The display supports 16-bit color which renders 65,536 colors available for use in the application. It is the combination of graphics, colors and imagination that make things work. In this sense it should be noted that Bodmer’s subroutines make exclusively use of the ‘triangle’ function and proceed with color fills that do not need additional graphic libraries beyond the two mentioned above.
Sketch with handy subroutines borrowed from Bodmer’s sketch
The complete updated sketch for the floor loop temperature acquisition is supplied at the end of this document. The sketch contains a lot of routine definitions, variables, DS18B20 and HDT11 management, and the necessary TFT bookkeeping. These instructions are responsible for running the show, with most of them present in the original sketch. The real interesting in the updated sketch are the instructions that produce and control the ring scales and its segmentation. In Bodmer’s sketch these instructions can be found in subroutines named ‘ringMeter’ and ‘rainbow’. Controlling graphical items such as gauges in one or more subroutines has several advantages. First, it makes it possible to devote the ‘loop’ section entirely to the instructions that monitor the sensors. A ‘loop’ should be as clean and orderly as possible. Once in the ‘loop’ section the sensor reading has been executed the content of the variables that hold the various data is transferred to the subroutines to update the display. This is very handy for instance for debugging. Second, because the subroutines contain all the instructions and variables that make the scales tick one can manipulate the subroutine specific variables to find out what they stand for, without disturbing the ‘loop’ itself with its sensor readings. Finally, embedding display handling in a subroutine makes it very easy to copy these subroutines into other projects, e.g. speed gauges, rpm gauges, fuel levels and the like, and get them to work. In this respect, Bodmer’s subroutines deserve respect and admiration.
Ring scale construction
Let’s peek inside Bodmer’s subroutines. The one responsible for the construction of a segmented ring scale is named ‘ringMeter’. ‘RingMeter’ is called in the ‘loop’ section after the appropriate variables have been filled with sensor readings. A very handy feature of ‘ringMeter’ is that the call contains a series of primary parameters that govern the position of the scale on the screen and scale size. By repeating the ‘ringMeter’ call (with changed primary parameters) additional ring scales can be added at the snap of a finger.
In the updated sketch there are two segmented ring scales in the left column of the display. Each of these scales is created in the ‘loop’ section by a call to ‘ringMeter’. Each call contains several variables that are transferred to the subroutine to create the responsive temperature display on the ring scales (as can be seen in figure 3B).
In the ‘loop section’:
//= properties of the first (upper) ring =
int xpos = 20, ypos = 20, radius = 85; // position of ring and proportion
ringMeter (reading,0,100, xpos,ypos,radius,”Celsius”,GREEN2RED); // Draw analogue meter
reading = temp_01; // important: here ring is seeded with value
// = properties of the second (lower) ring =
xpos = 280, ypos = 20, radius = 85; // position of ring and proportion
ringMeter (reading,0,100, xpos,ypos,radius,”Celsius”,GREEN2RED); // Draw analogue meter
tesmod = 1;
On screen position and size of a ring scale
Draw an imaginary square around the segmented ring scale. The values of the variables ‘xpos’ and ‘ypos’ determine the position of the upper left corner of that imaginary square relative to the left upper corner of the display. ‘Radius’ (dimension: pixels) is half the diameter of the ring scale. By simply changing the value of ‘radius’ the sketch yields a smaller or larger ring scale! This easy scalability is a very attractive feature of this subroutine.
In addition to ‘xpos’ and ‘ypos’ the call to ‘ringMeter’ contains additional parameters, ‘reading’, “Celsius” and a color coding, here ‘GREEN2RED’. ‘Reading’ is the variable containing the value for the temperature to be displayed; the value is acquired in the loop just before calling ‘ringMeter’, “Celsius” is a string that is displayed below the scale, indicating that the temperature scale is in degrees Celsius. ‘GREEN2RED’ is a value used by another subroutine, named ‘rainbow’ that embellishes the scale. The central “Celsius” string changes in color from green to red if a particular temperature is exceeded.
One segment is constructed by drawing two triangles
If we peek into the subroutine ‘ringMeter’ itself we learn that this series of instructions is responsible for the construction of a segmented ring scale. The mathematical basics of scale segment buildup is shown in figure 4.
Each scale segment consists of two filled triangles. One of these triangles, named SCALE0, has its base on an outer circle and is pointing inward. The second triangle (SCALE1) has its base on an inner circle while its apex is pointing outward. The base of triangle SCALE1 is defined by coordinates x0,y0,x1,y1, and its apex is defined by x2,y2. The base of triangle SCALE0 is defined by x2,y2,x3,y3 and its apex by x1,y1. The coordinates x0,x1,y0 and y1 lie on an inner circle while x2,x3 and y2,y3 lie on the outer circle of the ring scale.
Interesting parameters in ‘ringMeter’ are the following:
int w = r / 3; // width of outer ring is 1/4 of radius
int angle = 150; // half the sweep angle of meter (300 degrees)
int v = map(value, vmin, vmax, -angle, angle); // map the value to an angle v
byte seg = 3; // segments are 3 degrees wide = 100 segments for 300 degrees
byte inc = 6; // draw segments every 3 degrees, increase to 6 for segmented ring
Wherein ‘w’ determines the distance between the outer and inner circle of the scale, ‘angle’ the sweep angle, ‘seg’ the number of segments contained by the segmented ring scale and ‘inc’ the space between segments. ‘inc’ = 1 produces an uninterrupted circular scale. If ‘inc’ is set to zero the sketch crashes.
Figure 4. Ring scale segments. The values of six variables plus two colors define each arc segment. Each segment is built up from two triangles, one pointing inward and another one pointing outward. Each triangle can be filled with a color of choice; the outward pointing triangle with the color #define SCALE1 and the inward pointing triangle with #define SCALE0. The bases and tops of the triangles are incrementally positioned on an inner and outer circle whose radiuses can, in turn, be adapted to the particular screen resolution.
It is interesting to play with the color definitions for SCALE0 and SCALE1. In my sketch I wanted the unused segments of the scale visible but at the same time unobtrusive. As 16-bit color definitions for this TFT screen are in RGB 585 format a color picker on the internet was very helpful. One of these color pickers can be found at https://htmlcolorcodes.com/color-picker/. For instance, if SCALE0 is black (#000000) and SCALE1 is dark blue (#656B87) a nice ‘ray’ effect is produced. In the updated sketch, SCALE0 is defined as 0xC655 and SCALE1 as 0x5DEE.
Figure 5. Playing with colors. Selection of the fill color of the inward and outward pointing triangles that compose the segments in the (unused portion of the) ring scale is a matter of defining SCALE0 and SCALE1. Here we have chosen to use standardized colors. A: inward triangle = red, outward triangle = yellow; B, inward triangle = yellow, outward triangle = red.
Rainbow color scale
Another very attractive feature of Bodmer’s ring scale subroutines is the ‘rainbow color’ feature, that is the lower end of the scale is indicated with green colored segments while when the scale runs up the color gradually changes to red. ‘rainbow’ is called within ‘ringMeter’ with transfer of a variable called ‘value’ where the latter is an integer in the range of 0 to 127. ‘rainbow’ returns a 16-bit hexadecimal color definition that is used to fill triangles SCALE0 and SCALE1 that compose scale segments such that a rainbow effect is created (green at the beginning of the arc, red at the end of the arc).
The results of the transfer and adaptation of Bodmer’s subroutines into the original floor temperature monitoring sketch were impressive. Visibility is markedly improved. With one single one-second glance the inlet and return temperatures of the manifold can be read on the display. The rainbow scale is attractive and thanks to its ingenious design it is easily adaptable to a number of graphically oriented Arduino projects.
* Floris Wouterlood: Monitoring temperatures in floor heating loops with an Arduino, with data display on a 3.5’ TFT screen. https://thesolaruniverse.wordpress.com – November 21, 2016
** Danny van den Brande: ARDUINO – SPFD5408 TFT LCD 2.4 TEMP and HUMIDiTY Monitor. Fahrenheit & Celsius! http://www.instructables.com. September 15, 2016.
** Danny van den Brande: SPFD5408 TFT LCD 2.4 TEMP and HUMIDiTY Monitor. Een project met de SPFD5408 TFT 2.4 LCD. http://www.arduinoforum.nl. October 20, 2016.
*** Bodmer: Arduino Analogue ‘ring’ Meter on Colour TFT Display – http://www.instructables.com – section: Circuits – Arduino. March 17, 2015.
The zip file contains two sketches: the original sketch (the display shows only text and values) and the updated sketch (segmented ring scales, text and values).
Note that the sketches are functional demo sketches: they are fully functional, however because no DS18B20’s and DHT11’s are attached the displayed values are supplied by a temporary parameter block. Remove or comment that block and fill in the ID’s of your own DS18B20 sensors.