Blog 30th Oct 2019 – The MicroLAN or 1-Wire bus My recent fix for the ST9400C boiler timer (blogged below) got me thinking about temperature regulation with a mind to minimising our energy bill as much as possible. The relatively new boiler system is fitted with thermostatic radiator valves (TRV) on every radiator but no room thermostat to monitor the main living space temperature. By the autumn when we started using heat (after resolving the boiler timer fault) we found that the main living space would tend to overheat unless all the TRV's were throttled back, suggesting that the boiler was working hard, for no real gain. Current UK building regulations require that every radiator in a new build or where the system is being replaced should be fitted with a TRV, except for the radiator(s) fitted in the same room as a wall mounted thermostat. All well and good unless for some reason, someone decides not to actually fit a room thermostat. Ok - so just fit one! A simple mechanical thermostat could be fitted, or something smarter which will often have a WiFi capability permitting App control. Some of these are IFTTT compatible and so provide interesting script interfaces for control. In terms of fitting, some must be hardwired using a cable from the 10 way DP (see notes below) while others split the problem into two parts, a mains operated switch unit mounted close to the DP and one or more battery operated wireless remote temperature sensing units. Some of these systems permit more than one temperature sensor to be hooked up as a network and I understand they usually fire the boiler based on an average of the different temperatures. Good examples are the tado° or Hive products, which look lovely and are fairly easy to install even if cabling is required... but Hive entry level thermostats cost around £100 while a tado° kit controlling just one radiator remotely will set you back around £120. The costs spiral up fast if you want to dot multiple thermostats round the house and even faster if you want to pair thermostat(s) to individually control every radiator in the house. It also doesn't take long to spot other potential running problems with this type of distributed control. What happens if the LAN goes down and what kind of reliability can you expect from numerous wireless thermostats coupled to umpteen motorised radiator valves... all using battery power. The other issue to consider is how well such a system can monitor all the decisions being made. As you'll no doubt appreciate, a running boiler might not be overly keen on a bunch of independent control systems closing off every radiator valve in the house unless the system was fitted with an automatic bypass valve (ABV)... our system isn't. Then there is the thorny issue of cost and when batteries are taken into account, long term running costs. It seems to me that unless these types of systems are very carefully calibrated to the spaces they control, they may well end up working against each other, especially if controlling joined spaces. A simpler system, taking full advantage of fixed TRV's may work better, but where you'd want to avoid making the system so dumb it misses the really obvious stuff. I remember during a boiler service at my parents old place being surprised to find their wall thermostat (which was set to 15°C) quite happily telling the boiler to fire, in the middle of a very hot 25°C summer day, all because the thermostat happened to be in a well shaded room sitting at around 13°C. Come to think of it, our old place used a mechanical thermostat in the hallway through which the main living area could be reached after passing through a closed door. The boiler might have been old but it was wonderfully efficient and worked really well. The problem was that we'd often get home after a night out to find a nicely comfortable hallway but a very hot living space. The thermostat and boiler were both doing their jobs, but as the living space contained more radiators, that area was prone to overheating and the thermostat was simply unable to monitor. A better system might usefully monitor the temperature in four areas: the boiler outflow pipe to see what was being delivered into the system, the main living space, the upstairs space and the exterior of the house. Armed with this information it may be possible to balance the boiler against the radiator TRV's and even detect obvious fault conditions such as when a boiler is working hard but the radiators are cooler than they should be (i.e. badly adjusted TRV's or gummed up pipe work). It also permits the detection of extremes of external temperature high or low. Not liking the cost for off the shelf systems and remaining unconvinced of their advantage, I began researching accurate temperature sensing solutions to interface to a PIC micro controller so I could build our own control system. A basic system consisting of a CPU and touch screen colour display would be easy to build, but the question was how best to measure temperature in multiple locations (including outside) without having to gut the house to lay a load of sensor wiring. It didn't take long to stumble onto the rather interesting 1-Wire bus system originally designed by Dallas Semiconductor Corp and quite often referred to as a MicroLAN. It isn't a system I've used before but after reading more about it I found it was a little like the I2C bus, albeit slower but capable of longer range. The bus requires compatible devices but there are all sorts out there, everything from ADC's to battery monitors, time chips, digital potentiometers, fuel gauges, moisture detectors and memory devices. There's even an SHA1 authenticator and unsurprisingly temperature sensors such as the DS18B20-PAR, packaged in a TO-92 three pin case (only two legs are used). This sensor boasts good accuracy with user selectable precision of 9,10,11 or 12 bits. Within the temperature range we're likely to expect the accuracy would be around ±0.1°C. Leaving aside the sensing quality, the really important advantage of a 1-Wire system is that it only requires a 2 wire bus to fully implement and you can hang as many devices as you like on those 2 wires. One is ground while the other is a two way data wire but which doubles as a source of power (and for some power hungry commands - a low Z power boost) for the 1-Wire device(s). Faced with monitoring temperature with something like 4 sensors, it is ideal and cheap given the sensors only cost around £4 each and the wiring could be be done with 4 core alarm cable. As I happen to have a roll of ancient 8 core screened cable lying around, I used that instead. I bought ten DS18B20-PAR's devices from Farnell, just to figure out the software I'd need to get them ticking. I already had a Mini-32 PCB based on the PIC32MX534F064H chip lying around spare and I coupled that with a Digole colour touch screen LCD to form a basic system. I then wrote sufficient code to configure the CPU at 80Mhz, the peripheral bus at the same speed, a UART to drive the colour display and Timer1 generating 1mS interrupts for housekeeping chores.
The 1-Wire bus spec is well written and very easy to use. First steps involve building a small number of primitives using the single I/O pin selected for the bus (reset bus, set bus low, read bus bit, set bus to a power state) and using a scope to then verify the signal operations on the bus and the timings. For development I used a 0.1µF disc capacitor from the bus line to ground to simulate a long length of cable. The second step was to write an accurate µS time delay algorithm... I used nop's to fine tune this. The 1-Wire bus imposes fairly strict timing requirements for all of its operations and so interrupts have to be killed off during execution and an accurate means of delaying for n µS is mandatory. Long before talking to the devices, a scope was used to check the signal timing was working as expected.
1-Wire low level functions
After 3 hours or so I began work on the higher level functions such as write byte, read byte, write 64 bit address after which came the more complex tree search / discovery algorithm based heavily on freely available application notes and really good code examples in C. By the end of the day I could discover the 64 bit addresses for every device on the bus and could quite happily select one, initiate a temperature measurement and then read the result which uses a 16 bit 2's compliment notation. For 12 bit precision (the default) you multiply by 0.0625 to deduce the temperature and for example right now the external sensor holds the value 0xAE, which is 10.875°C. Later on in the winter that value might read 0xFFF8 which would be a rather chilly -0.5°C. 1-Wire devices are assigned a unique 64 bit address during manufacture. 8 of those bits are used to hold a family code (for example - the temperature sensor family code of the DS18B20-PAR happens to be 28h) while another 8 bits are used to hold a cyclic redundancy check (CRC) byte (useful when transmitting data and making sure it is legit). The rest is a unique code for the device. You might for example fit 2 sensors, one in the main living space and another on the outside of the house - both connected to the same two wire bus connected using cheap alarm cable. At the CPU end, one wire is grounded while the other is connected to a general data I/O pin of the CPU and with the all important pull up resistor to (in my case) a rail of 3.3v. I used a 2.4K pull up given the length of my cable but generally this will need to lie somewhere between 1 and 5K and is best judged by looking at the rise time when the full length bus cable is connected. 1-Wire devices draw power from the pull up using a parasitic design, but there are likely to be a number of power hungry operations by devices (for example when a device is told to write to internal E2PROM) where the CPU will be required to provide a low impedance power supply (between 3 and 5v) on the bus covering the full execution of the command. In fact, the CPU data I/O pins are perfectly adequate to source sufficient current for this requirement, meaning that the CPU simply has to output a high on the I/O pin to act as a power source for the bus. By contrast, whenever data is transferred, an important characteristic to grasp is that both the bus master and any slave device(s) will transfer a high by tristating their respective data pin and allowing time for the pull up resistor to do the rest. This has a useful side effect because if n devices were to send a data bit value all at the same time, the result will be a logical AND of the n separate bits. If for example a single address bit was sent by multiple devices at the same time, first as raw data and then complimented, the CPU would be able to deduce from the ANDed result which devices may be excluded from a search, thereby reducing the size of the search space and gradually narrowing down to a particular device. It is a feature used extensively during the process of discovering all the devices sitting on the 1-Wire bus, given when the Farnell delivery pops through your post box, there won't be any individual device address information included in the package. Code has to be written to discover those device addresses. Although the C code I've written is subject to change, it definitely works and may be useful for someone starting from scratch. If you were interested, you could download the three files here knowing that two are header files and there's one C file. If you do try to get these working, you'll need accurate delay_uS( t ) and delay_mS( t) functions and make sure you kill off interrupts while the code runs. While it's early days yet for this hopefully smart boiler thermostat, the test bench hardware has now clocked up around 100,000 individual temperature measurements from two sensors without any failures or glitches over a 30 hour period using a 40 foot long 2 wire bus. The next step will be to plan an algorithm and then simulate how well that algorithm works. I can start looking at building a more permanent hardware solution, once we get that nailed down and working well. Comment | Back to Quick Links...