Computing stuff tied to the physical world

Reducing the packet rate

In Software on Nov 22, 2012 at 00:01

One last optimisation, now that the OpenTherm relay sends nice and small 3-byte packets, is to reduce the number of packets sent.

The most obvious reduction would be to only send changed values:

Screen Shot 2012 11 11 at 14 40 15

This is a trivial change, but it has a major flaw: if packets are lost – which they will, once in a while – then the receiving node will never find out the new value until it changes again.

There are several ways to solve this. I opted for a very simple mechanism: in addition to sending all changes, also send out unchanged values every few minutes anyway. That way, if a packet gets lost, at least it will be resent within a few minutes later, allowing the receiver to resynchronise its state to the sender.

Here’s the main code, which was rewritten a bit to better match this new algorithm:

Screen Shot 2012 11 11 at 14 35 52

This still keeps the last value for each id in a “history” array, but now also adds a “resend” counter. The reason for this is that I only want to re-send id’s which have been set at least once, and not all 256 of them (of which many are never used). Also, I don’t really want to keep sending id’s for which nothing has been received for a long time. So I’m setting the re-send counter to 10 every time a new value is stored, and then counting them down for each actual re-send.

The final piece of the puzzle is to periodically perform those re-sends:

Screen Shot 2012 11 11 at 14 36 10

And in the main loop, we add this:

Screen Shot 2012 11 11 at 14 36 24

Here’s how it works: every second, we go to the next ID slot. Since there are 256 of them, this will repeat roughly every 4 minutes before starting over (resendCursor is 8 bits, so it’ll wrap from 255 back to 0).

When examining the id, we check whether its resend counter is non-zero, meaning it has to be sent (or re-sent). Then the counter is decremented, and the value is sent out. This means that each id value will be sent out at most 10 times, over a period of about 42 minutes. But only if it was ever set.

To summarise, as long as id values are coming in:

  • if the value changed, it will be sent out immediately
  • if it didn’t, it’ll be re-sent anyway, once every 4 minutes or so
  • … but not more than 10 times, if it’s never received again

And indeed, this reduces the packet rate, yet sends and re-sends everything as intended:

  L 13:48:48.073 usb-A40117UK OK 14 24 18 197
  L 13:48:49.080 usb-A40117UK OK 14 25 51 0
  L 13:48:50.072 usb-A40117UK OK 14 26 43 0
  L 13:48:52.072 usb-A40117UK OK 14 28 51 0
  L 13:49:20.075 usb-A40117UK OK 14 56 60 0
  L 13:49:36.548 usb-A40117UK OK 14 20 238 51
  L 13:50:37.549 usb-A40117UK OK 14 20 238 52
  L 13:51:33.532 usb-A40117UK OK 14 24 18 186
  L 13:51:37.563 usb-A40117UK OK 14 20 238 53
  L 13:52:34.537 usb-A40117UK OK 14 24 18 188
  L 13:52:38.553 usb-A40117UK OK 14 20 238 54
  L 13:52:40.088 usb-A40117UK OK 14 0 2 0
  L 13:52:41.096 usb-A40117UK OK 14 1 10 0
  L 13:52:46.087 usb-A40117UK OK 14 6 3 1
  L 13:52:54.101 usb-A40117UK OK 14 14 100 0
  L 13:52:56.101 usb-A40117UK OK 14 16 18 0
  L 13:53:00.100 usb-A40117UK OK 14 20 238 54
  L 13:53:04.099 usb-A40117UK OK 14 24 18 188
  L 13:53:05.090 usb-A40117UK OK 14 25 51 0
  L 13:53:06.098 usb-A40117UK OK 14 26 43 0
  L 13:53:08.098 usb-A40117UK OK 14 28 51 0
  L 13:53:34.538 usb-A40117UK OK 14 24 18 192

Time to close that OpenTherm Gateway box and move it next to the heater. Onwards!