PCB milling

My first attempt as the RFID reader version of my "scales" system meant a lot of enamelled wire...

It was a tad messy, and time consuming. But worked well.

I decided a small PCB would be a better solution, and the answer for one-off PCBs is, of course, a milling machine.

Nearly 30 years ago I used such a machine when working at Nokia. It was very useful, and expensive. These days you can get a small CNC machine for under £200!

I purchased one from Amazon (duh!).

It took some assembly, to say the least, but plenty of good videos on line.

It has an arduino, which allows moving the head and running code (.nc) files from a micro SD card. It looks like the main machine talks serial / USB, but not got that playing just yet.

Making PCBs

I designed the PCB on inkscape, which is fine for a small PCB like this. The challenge, as always, is a small single sided PCB with minimal links. My first design assumed I could run tracks between the pins on a 0.1" header (which I could do 30 years ago). It seems this is tricky, to say the least. Maybe we can managed 1/20th" pitch devices like an SO8, just, but tracks between 0.1" headers are not so easy.

So I redesigned with "chunky" tracks. This meant one small link. A 1206 0Ω resistor would be ideal, and Amazon prime do them, but out of stock, so a wire will have to do.

In inscape it is easy to make tracks and pads. You then just stroke-to-path, and union the paths and tracks to make an SVG cut path. Of course this cuts on the track edge which makes the tracks smaller. You can make that a path and stroke-to-path again and union first stage, but that is faff. Simpler to design with chunky tracks and pads that almost touch when designing, knowing the cut path will be thicker. If that makes sense. Obvious I needed a layer for drilling, and cutting around the edge of the PCB, and the tracks.

Making GCODE

This is a lot harder than I expected - there seem to be several solutions, and FlatCAM looked promising, but I cannot get to work on my Mac. There is an svg2gcode tool, but did not work well. I ended up just making my own code to convert EPS to GCODE with options for speed and cut depth and so on. The GCODE goes on the SD card, and simple.

Stupid UI

The UI on the arduino is daft - it has a mode to control portion, but then uses all 8 buttons and has no way to escape back to the main menu as far as I can see - so I set origin and have to power cycle to then run the file. Maybe I am being thick.

The result...

Ok I cut too deep and cut in to the bed, idiot. I'll either cut less or add a sacrificial layer below.

That worked

Final PCB

It is not that good, but the design with chunky tracks means it works!

And time to try it out for real...

It only bloody works!!!

P.S. I have open sourced the eps2gcode.

P.P.S. Make sure the screws are tight on the screw ends - else you get drunk tracks on your PCBs.

P.P.P.S. bCNC is the tool for sending GCODE to the CNC machine directly - works a treat on a Mac.


Upgrading the scales to WiFi and RFID

I have now taken things a bit further with my scales upgrade. Not just WiFi, but RFID as well.

This means that instead of pressing send, you tap a card or key fob on the scales.

The scales then send the weight and card ID over HTTPS to a server that puts the details in a database. My previous video showed that I connected a wire to the SEND key for this reason. As it happens it needs a small diode in line so the processor does not get upset at power on, but other than that it works as planned, and was pretty simple.

This is great when the scales are used by everyone in the family, and the next step is some nice graphs and so on. James is working on that.

Of course, whilst this is fun, this suddenly starts to have GDPR implications. For "personal" use we are probably fine, but the second you extend it (e.g. taking to Slimming World to show off, as James is planning) you create fun an games with GDPR. I  can see the "SEND" button being re-labelled "CONSENT" and the privacy policy being labelled on the scales as well.

None the less, a good proof of concept and a fun tech project. I wonder if Slimming World, or Weight Watchers, and Marsden, are interested in teaming up with us and making a complete package. Saves taking laptops to meetings, and the cards are easy to brand :-)

This is how it is done...


Upgrading my Marsden M-125 scales to WiFi

I have some nice scales from Marsden, their M-125 column scales. I know they are not cheap (£235+VAT) but they are very good. If you are ordering for home you can ask them to allow stone/pounds as well as kg, which they seem happy to do. They work at 100g steps and can weight up to 250kg. What is nice is how consistent they are - none of this "best of three" effort on cheap bathroom scales.

But I wanted to get data out of them, and like proper scales they have a serial port (though it is a USB port). I was going to connect to a Raspberry Pi, and even have a Pi and a case, but I now realise I can WiFi connect them easily.

Using an ESP8266 in an ESP-01 package, I can receive the serial data and send over MQTT over WiFi, simple as that! It actually works out about half the cost of the USB cable alone - with the ESP-01 costing a whopping £2.75 from Amazon (more like 50p if you order from China).

It does involve adding a header to the main PCB, sadly (no doubt voiding any warranty). It would be nice if Marsden had a header on the board and did WiFi as an option. I am sure we (A&A) would be happy to provide some consultancy and custom firmware for such a project, just ask...

As for the software, well, I was actually able to use the Tasmota software as it will serial bridge to MQTT, but I then wrote my own (on GitHub). It sends via MQTT and/or via HTTP(s). It is a bit of a work in progress at the moment, but works well even so.

Here is how it is done...


Arduino / ESP8266 / ESP-01 / ESP-12F

I never really got in to Arduino, which is kind of surprising given my history. I have been playing around with micro processors for a long time. 30 years ago I had a door entry system running on a home made wire-wrapped 6502. I have coded things from tote betting ticket machines to mobile phones, and much more. I did loads on the PIC16C84 which was amazing when it came out, but somehow the Arduino passed me by.

Of course, these days, there are the Raspberry Pi boards, which are similar in size and price to Arduino but powerful enough to run linux. I have used a lot of those. At the office we have loads running display screens, and doing things like network printers, and even the door entry and alarm system. Very powerful, but used generally as small network computers rather than hobby electronics with I/O. Even the alarm system uses the Galaxy RIO boards to do the I/O.

Arduino is stupidly easy

The Arduino eco system - the desktop environment - is really very simple and quite impressive. So much so that someone like my friend Simon, who knows bugger all about coding in C, is able to create working Arduino applications. It is impressive. The standard "Hello world" program is: (a) plug in the board, (b) click on arduino app, (c) type Serial.println("Hello World"); in the on screen setup() function, (d) click the arrow to flash... Done. In a few seconds you have a computer sending Hello World via a serial port. Making I/O pins do things is similarly simple.

The coding is actually C++, which I have never been that happy with - but I am coping :-)

What is very impressive is the community of hobbyists that has built up. There are libraries for everything, so if you want, say, to use a Dallas DS18B20 temperature sensor, you will find a library to do that and examples, and instructions how to wire it up. Indeed, even the Tasmota code I am using on my light switches has that built in so I can literally solder a temperature sensor on the the pads and click a few config settings on the web page to set it up.

The libraries and examples mean that even Simon has been doing some impressive things, but he is not really a programmer, and so thought I might like a break(!) and spend a long weekend at his place.

In some ways this is actually a slight problem - I found there are many competing libraries for lots of things and it is not always obvious which you should pick. Of course, I am making some apps and libraries to add to that!

Hobby hardware

Back in the days of a PIC16C84 you could get chips with actual legs on and solder wires to them! These days that is impossible - the chips and components are just too small. What is interesting is that there are now common "modules" that have such chips, with extra passive components, all in place on tiny PCBs with headers. As always the headers are 0.1" (2.54mm) pitch so you can use molex style pins and plugs (or even wire-wrap).

I would always have bought parts from RS or Farnell but I was shocked at what you can get from Amazon. I mean, seriously, it is mental. And unlike RS I can get stuff same day or on a Sunday (which was handy during this long weekend). Seriously, it is like finding your corner shop sells electronic components next to the sweets counter, I can't get over it!

Sensors everywhere! What is impressive is the hobby electronic devices you can get, on PCBs with 0.1" headers, it is mental. If I was asked to list possible types of sensor, I would not come up with nearly as many as you can get, and get on Amazon Prime even! Here are just a few.

3.3V and 5V

One of the things that takes some getting used to is that everything is 3.3V now. When I were a lad it was all TTL (5V). But even now it is not that simple as some things are 5V still, so you need level convertors. That said, some things are 5V only and will not work on 3.3V, some are 3.3V only and are damaged by 5V, and some things are designed to work at 3.3V or 5V.

Interestingly the ESP8266 (see below) is 3.3V, but rumours are that the input pins tolerate 5V. Apparently the CEO of the company that makes them said so on facebook, and people say it works. What does not work is powering the ESP-01, or similar, from 5V as the flash chip gets fried. The right thing to do is read the data sheet and use level convertors as necessary. The good news is that 5V to 3.3V and 3.3V to 5V power regulators are now small and cheap and so are level convertors, so easy enough to do it right.


Another issue is powering things - I have always had to use a power supply in the past, a plug-top and lead of some sort. But of course there are USB 5V connectors everywhere now. That said, the regulators for such things are tiny now. The Sonoff devices work of mains with a simple on-PCB power supply so for many things you could use one of those as the processor! Powering off 12V, or 5V, is simple and a small PCB with regulator. Even powering off 1.5V or 3V is simple as well. It never used to be this easy, cheap or tiny! Apparently you can make apps that will run off a battery for years if you try hard.


The breakthrough for me really is the ESP8266 processor. It turns a small(ish) Arduino board with Ethernet and a plug top power supply in to some thing truly tiny, cheap, and interesting. The ESP8266 is a small processor which includes WiFi (albeit only 2.4GHz). This is amazing. It is sold in various packages, but the interesting ones seem to be the ESP-01 and ESP-12F. It is this processor that is in the Sonoff light switches. There seems to be good support for them under the Arduino IDE.


The ESP-01 is the basic entry level package for the ESP8266. It seems some were sold with ½MB flash but now they are 1MB flash (there are two chips on the module, the ESP8266 and the flash).

They are tiny, and have an 8 pin header. There are a whole load of boards designed just to work with the ESP-01, such as relay boards which have an 8 pin socket on the board (and come with an ESP-01). They cost 50p or so if buying from China, but are around £2.75 on Amazon. So easy to use.

For programming there is a nice UART / USB board you can get, which has the 8 ping socket for an ESP-01. The trick is to modify it to have a button on GPIO0, which has to be pulled low as you reset to put in programming mode. Simply hold the button as you plug it in...


There are a range of modules from ESP-01, ESP-02, and so on. The ESP-12 series is interesting, and they have taken a different approach in some of these later modules - instead of 0.1" headers they have solder tags on the edge so the module can be soldered on to a parent board.

The ESP-12E and ESP-12F are the same apart from the antennae, and include 4MB of flash (which is nice). The ESP-12S is quite new it seems and slightly smaller and does not have some otherwise useless pins on the end (used for external flash). They also have a metal can for EMC, and claim FCC and CE approvals, which is nice too. There are, of course, nice breakout boards that provide the 0.1" headers. The main advantage (apart from CE marking, and 4MB flash) are that more of the ESP8266 pins are available, including the ADC input.

For programming you just need to connect the pins from the small UART board (GND, 3.3V, RX, TX, and the GND via a button for GPIO0).

I'll blog on some of the projects I am making later in the week.


Inveo Nano

The temperature sensors I am using are the Inveo Nano PoE sensors. They are quite industrial and cost around £100. In hindsight I realise I could now make a wifi connected temperature sensor for around £2.50 or add a temperature sensor module to my new light switches for a pence, but possibly not as good.

Update: It looks like I could connect a DS18B20 (the sensor the Nano uses) to any of my new Sonoff light switches with incredible ease. So yes, for the cost of the sensor (under £3) I could have put temperature sensor attached to the new light switches and saved £100. Arrrg!

They work quite well. Slight hassle setting up as on a fixed IP not DHCP, but documented well enough, and they will do DHCP. They have several ways of working including SNMP.

I set one up in the bedroom, and this is what I have been testing with for a while now. A cron every minute got the temperature by SNMP and fed in to my air-con control stuff using MQTT.

However, the other two that I had ordered finally arrived yesterday, and they don't work. Arrrg! The SNMP simply does not respond. Yes, I check the manual and the config (it is one tick box to enable SNMP), but nothing. Only difference is new ones are version 1.18 and old one is version 1.17. I was pulling my hair out.

Then I spotted another option: MQTT. When I first installed one I had not looked at MQTT at all, but now I am using it, and in fact feeding the SNMP result in by MQTT. So I tried that.

What is odd is that it allows MQTT to be turned on, but it connects to a pre-set cloud service :-

This is a bit odd, as it seems to mean I could poke temperatures in to their MQTT cloud service for any sensors if I know the MAC. Anyway, the DNS provided on the FireBrick on the VLAN on which I have these things changed the IP for their MQTT server to mine, and now it reports to me. All I had to do was allow my air-con control code to be configurable as to the topic on which it listens for temperature. Sorted! Shame about the SNMP but I don't care now :-)

It is quite nice - it sends temperature every minute, and if it changes (e.g. 0.1 degree change). This had a rather unexpected side effect of making my air-con control too good. It reacted instantly, turning off the compressor when temperature hit the target so the code. It was also trying to keep the average temperature at target and could never win as it never went over target! As a result my room was within 0.2℃ total variation all night which is amazing!

I also noticed that the air-con seems to not try the compressor again for 5 minutes, which probably makes sense, and ensures I am not wearing anything out. As a result, every 5 minutes, it runs the compressor for 20 to 30 seconds or so - whatever needed to reach target temp, and stops. It does work rather well.

I have since tweaked it so it is not trying to set ever hotter temperatures to move that on to the target temperature :-)


This is cool

Finally (I think) I have my daikinac app working as I want it. It is on GitHub (here). Apart from simple control via MQTT, it proves me with much better temperature control. It has taken days to do this, coding and testing over night typically. One day was wasted as the temperature sensor had fallen on the floor and my algorithm was trying very hard to change the temperature of the carpet under my bed (arrrg!).

Why do this?

  • Fun, and interest, as always
  • Comfort - air-con controls are annoying, they allow temperature to be out by well over 1℃ and I notice that.
  • They are also crap at an "auto" mode and don't change from heat to cool sensibly (e.g. can be 2 or 3℃ out before they do it), hence I have to change manually in spring/autumn during the day.
  • Saving money by better controlling when they are on and off as part of home automation.

The result:

±0.2℃ of target. (Red line is measured temperature) Mostly ±0.1℃. Measured using a device with only 0.1℃ precision.

How it is done...

Basic logic is checking the settings and info from the air-con every minute using http, and collecting temperature from a separate thermometer via SNMP. This is place by the bed (i.e. where I want the temperature set).

The basic algorithm involves having an offset from the target temperature, and sending that to the air-con as its target.

Initially, and after any change of mode or fan rate control or my target temperature I allow 15 minutes for that to settle and then start collecting measured temperature. Once I have 10 minutes of data I consider changes to the offset. I collect up to an hour to track a moving average.

If the data shows a minimum above the target or a maximum below it, i.e. "way out" I make a step change in the offset to bring that in line, and flush the data and wait 15 minutes to settle again.

If the min/max cover the target, then I adjust the offset by a small amount (0.01℃) based on the average being higher/lower than target.

This all keeps the temperature averaged at the target and allows for any temperature difference from air-con unit to where I am measuring. Normally this is very low (with windows closed), e.g. well under 1℃. However, with a window ajar to allow fresh air this an be several degrees (I now have a nice heat exchange fan in the room instead, so windows closed).


Unfortunately the air-con is not quite as good as I would like. It does lower power as it gets closer to the target, which is good, but ultimately when the temperature drops passed the target it will engage the fan and compressor and push the temperature 2℃ beyond the target and then allow it to settle. This cycle can mean a compressor on for maybe 5 to 10 minutes and repeat every hour.

What I have done now is recognise when it is doing this and kill the compressor. Once the compressor is on and the temperature crosses back past the target I turn it off by setting a target 3℃ before the target. This means we "overshoot" by only 0.1℃ to 0.2℃ if at all.

The result is the compressor on for up to a minute maybe every few minutes (depending on how har it is having to work to maintain temperature). I don't know if this change in duty cycle is detrimental or not. It probably means less usage overall as we are not overshooting the target temperature by 2℃.


One concern was noise, but even in night mode I can hear a ticking clock over the fan - the compressor and fan going on/off happens anyway, just more often now. Works well.

Other bits

If the offset to be applied is getting too high and not working, we switch from quiet mode to normal auto fan mode as clearly it needs more oomph.

If the offset to be applied is getting too low and not working, we switch between heating and cooling.


The thermometer may well have a level of error, obviously, but I am not trying to do a physics experiment here. I don't really care as long as it is consistent and precise as ultimately the target temperature depends on comfort. It can be impacted by lots of things like being unwell, or just coming in from hot or cold outside. However, I now have a reliable way to set a temperature and then make any relative adjustment for comfort.


Tasmota / Sonoff - two way light switch controls

One small thing I wanted to do is make one Sonoff light switch work another - a simple two may light switch arrangement, such as top and bottom of stairs, etc.

Obviously, one can use a home automation server like home-assistant, but I am trying to keep it a bit simpler at the moment. I have an MQTT broker (actually on a Pi) and that allows any of the MQTT devices I have to talk to each other. Some devices, like my door entry, and alarm system have a means to send a series of MQTT messages on various events already.

It seems Tasmota / Sonoff can do what I want, but there were a couple of challenges, and reading some blogs I see I am not alone. So here is what I found and what is a gotcha or two.

The set up

What I was trying to do was have a light switch that controlled another - a simple two-way light switch arrangement (which is what it used to be). Either light switch ("button") when pressed would toggle the light, simple. I had another case where I wanted one button to control 4 lights, but we'll come to that later.


The simple answer is to set the ButtonTopic on the extra switch and tell it that the topic to use is the first switches. This should just work. But...
  • You cannot set the ButtonTopic if you are sending a group message, which it thinks you are if the name of the GroupTopic is a substring of the Topic of the device, which is just silly. The result is a status saying ButtonTopic is still "0". No error, just confusing. I had to read the code to find this. I had Bed1LS as a GroupTopic and Bed1LS3 as the device Topic. As a result I could not set the ButtonTopic to anything!
  • I don't think you can use the ButtonTopic if it is set to the same as the device GroupTopic (from looking at the code). So even changing GroupTopic and changing back to set ButtonTopic would not work in the above case. I am not totally sure why, unless it creates some sort of loop, but I cannot see why it would and it would be better to fix that than to silently ignore it.
  • You can only set a system wide ButtonTopic, not a topic for each button if you have several buttons. This is OK on a simple button switch, obviously.
  • You set the ButtonTopic just to the name, without the cmnd/ prefix or /Power suffix. It adds those - which was not obvious.
  • Note, ButtonTopic replaces the normal relay operation unless MQTT is not available.
Request: Please can we have a ButtonTopic1/2/etc for each button?
Request: Can we please avoid the loop or whatever stops use of the GroupTopic as ButtonTopic?
Request: Why is grpflg set using strstr hence meaning it is set when talking to a device where group is subset of device topic. I can see group being subset of device as quite common?


Rules are another good way to do things and are mode flexible. You can make a rule so that pressing the button publishes on MQTT. You can have more than one sequence on a rule.

You simply send something like :-

 cmnd/Bed1LS3/Rule1 on Button1#state do publish cmnd/Bed1LS/Power1 TOGGLE endon

And you can add a second part to the rule, e.g.

 cmnd/Bed1LS3/Rule1 +on Button1#state do publish cmnd/Bed1LS/Power2 TOGGLE endon

I had to add two parts because the lights switches where double, and so needs Power1 and Power2 set.
  • It looks like the Rule and ButtonTopic do not work together which is odd.
  • I could not publish a command with spaces in it, such as Backlog (to change both Power1 and Power2 together). Maybe there is a trick to that. Hence I had two parts to the rule.
  • Note, a rule on ButtonX replaces normal relay operation. A rule on PowerX happens when power changes which could be because of normal button control of power. You can test Power1#state=0 and Power1#state=1 if you don't want to use TOGGLE.
Request: Can we have it so Power (rather than Power1 or Power2) applies to all power controls so that one message could toggle or control all lights on a multiple button light switch?
Request: Can we publish something with spaces in somehow?

However, end result is good :-)

P.S. You cannot turn off the relay/button LEDs on the T1 (light switches) sadly.

Update: You can use Backlog in the command, which works well. E.g.
cmnd/GardenLS0/Rule1 on Button1#state do Backlog Publish cmnd/GardenLS1/Power 2;Delay 2;Publish cmnd/GardenLS2/Power 2;Delay 2;Publish cmnd/GardenLS3/Power 2;Delay 2;Publish cmnd/GardenLS4/Power 2;Delay 2;Publish cmnd/GardenLS5/Power 2;Delay 2;Publish cmnd/GardenLS6/Power 2; endon

Update: Be careful with now code and settings. I turned on Home Assistant Discovery and it changed the topics. I turned on WiFi signal scanning and somehow managed to put most of the sonoffs in a mode where they could not connect to the WiFi so went in to an AP mode for 3 minutes and tried again. It meant all my devices vanished and did not come back for quite a while. Several devices even somehow went in to a mode where they acted like the original SonOff code. I had to actually unscrew 4 of them and refresh, and two of those I had to erase the flash with a separate binary. The other two I had to sent a command over serial to Reset the config. So top tip: Always have one separate unit on which to test any changes first.


Setting the temperature

I have upgraded the aircon in my bedroom as the old one broke, and have a nice new Daikin one (as I blogged). I can control over wifi, which is good.

Even though this is way better than the old unit I had, it still suffers from a couple of problems.

Firstly, the good thing it does is finely control the power and fan so that as it gets close to target temperature it lowers the power a bit, and ends up staying on target pretty closely without oscillations. Excellent.

One problem it cannot solve though is the there will be a temperature gradient in the room, not just top to bottom, but also potentially quite a lot if you have a window open a bit to let in some fresh air and ensure the CO2 levels are sensible. Outside was actually below 0 this morning!

The other small problem is that the "auto" mode is not good at some times of year when it will wait until several degrees over target before switching.

To solve the first problem I have an SNMP thermometer with a sensor on the side of my bed where I sleep. This allows me to nicely graph the temperature for a start.

This also lets me take control of the air-con.

First attempts

The first attempt involved doing the job for the aircon - setting the power based on the temperature. However, I cannot do that directly, I have to set the target temperature relative to current temperature to force it to work out a power setting. This took several iterations to get reasonably right.

At one point I was in fact oscillating so much I even had it switching to cooling after it overshot on heating, and then back again later.

But finally after a lot of testing (mostly leaving it for an hour or so on latest algorithm while I did other stuff) I got it oscillating within around ±0.5℃ or so. I was pleased, and slept on it (in a nice temperature controlled room).

On this graph, y-axis is temp in ℃ intervals, x-axis is time in hours, black is target, red is measured temp, light red is setting temp on aircon. The green is reported temp from aircon which I suspect is a separate sensor and way off. So mostly the measured temp was within around ±0.5℃ once it had settled a bit at the start.

Then I had a brainwave..

Finally working (well, so far)

The aircon itself does a better job, holding a much more stable temperature without much oscillation. So use that! I decided to keep a moving average of how far out the setting temperature was from the measured temperature, and use that to add an offset to the target set on the aircon. It only allows settings to 0.5℃ so I added error dither as well.

This works a treat, and allows me to set the aircon allowing for the temperature gradient in the room automatically. The only minor change I made was to offset the averages by a few minutes to allow for the fact that the set temperature does not immediately change the room temperature - so as to better track the actual temperature difference. I was somewhat fooled by how much it changed during the day when sun light hit the room, etc, but I should have expected that.

Here, by using the aircon to control the level we have a smoother temperature. This was in the evening as the outside temperature dropped and so the level to which the aircon had to be set was gradually increased to maintain the measured temperature. Again, within 0.5℃.

The result is all on GitHub (here). It includes MQTT daemon as well (which is how I tell it the air temp from SNMP).

Update: This worked well when the aircon is fighting a window that is ajar. Now I have my new fans installed and windows slows it is oscillating ±1℃, because it is effectively turning on and off at a low level. So I am working on the older method if I find we are doing that. We'll see how it goes. Github updated as I go.

Hot tubs are expensive (again)

Yes, my hot tub is expensive. Our whole house total power consumption was, typically, 55 to 60 kWh per day. Which is a lot. I have some excu...