Close

Decoding the Smoke Signals

A project log for Blanket: The Smoke Signal Gateway

An open source WiFi Gateway for the ThermoWorks Smoke thermometer.

skytoastarskytoastar 08/11/2018 at 14:261 Comment

It's surprising sometimes how much information a company hands over to the FCC. Our ID of interest is 2AI67-TX1300CH. If you look at the exhibits list you'll find internal photos (what's that I see? a NRF24L01+ radio?) and a handy test report (you say it broadcasts on Channels 10, 40, and 70?) and surprisingly even a "FREQUENCE AND HOPPING SYSTEM" report that describes how it broadcasts on those three channels (every ~16 seconds it broadcasts on each of the three channels). I didn't even have to take my device apart. There's also no report for the portable display that comes with the thermometer so we know the portable display doesn't transmit. Thanks FCC!

That being said, there are still a number of NRF24L01+ parameters we still don't know. It is using ShockBurst? CRC length? Address length? Address value? Payload length? Data rate? (Someone smarter than me would have figured out data rate from the FCC test report. Someone like me ends up using that info to make an incorrect judgement and going down a dead end for several days.)

I assumed the radio was using a 1 Mbps rate based on the test report. First I used an Arduino and NRF24L01+ to try to sniff for packets as described on Yveaux's blog and using an address of 0x0055 (the preamble). After many fruitless attempts I decided this was a good excuse to buy an ADALM-PLUTO SDR. (I thought about using a downconverter with an RTL-SDR but after considering the cost, an ADALM-PLUTO made more sense.)

An entire project log needs to be dedicated to just setting up the ADALM-PLUTO SDR. Analog Device's wiki is sufficient but lacking, in my opinion, if you're running Windows. But for now I'll cut to the chase and say it is actually using 250 kbps. Finding that out reminded my face what my palm feel like. (Using this data rate with Yveaux's software was much more successful, though not needed after decoding with the SDR.)

My Smoke was transmitting with an address of 0x36BD529F51. Does every Smoke use this address? I doubt it. BBQ competitions would be a problematic place to use a Smoke if that were the case. I don't have two Smoke thermometers to know for sure but if I had to guess they use the first three bytes (0x36BD52) for all units and then choose a random number for the last two bytes for each device. NRF24L01+ radios are designed to sync onto 3, 4, or 5 byte addresses. So a receiver sync process could be designed as follows:

  1. Listen always for a packet with: Address (0x36BD52)
  2. Take the first two "payload" bytes and append them to the base address.
  3. Sleep for ~16 seconds.
  4. Wake and listen for the next transmission, listening for the full 5 byte address.
  5. Repeat steps 3 and 4.

This is speculation. It could be just one byte of uniquely identifying information. Or maybe it's zero bytes and it relies on the long sleep times to avoid collisions. Or maybe it's actually much more complicated than that. Having more information from more Smoke units would help clarify this information.

Here's a brain teaser: With two bytes of uniquely identifying information, what's the likelihood of a collision? (Left as an exercise for the reader. Hint: birthday problem.)

Here are the full details of the transmission:

And the payload:

All two-byte temperatures are signed 16-bit integers and are in units of 0.1 degrees (divide the signed value by 10 to get the temperature).

I wonder if the "Probe X Inserted" bytes have different meanings for values of 1 or 2. Damaged probe, for example. That's speculation.

The 1-byte sync timing offset is just a guess. When you go through the procedure to sync the receiver with the thermometer, this byte gets set to a non-zero value. I haven't studied it enough but I think it provides some timing information to receivers that were already synced to the transmitter. Doing a sync operation causes the phase of the ~16 second transmissions to shift by several seconds. I think it has to do with this shift. But I'm not sure.

The final three bytes of 0x009600 seem to be constant regardless of anything else. Firmware version number? Not sure.

That's the 21 byte payload. Then it's followed by a 2-byte CRC that's calculated as described in the NRF24L01+ datasheet.

I'm glad decoding the payload was pretty straight forward. I was happy to see there's no encryption or even an attempt at any obfuscation. That makes it easier for the rest of the project.

Discussions

Jeff Stiles wrote 12/04/2019 at 17:48 point

Thanks for the write up. I was hoping to take a stab at this if I ever got some time, but you've already figured out the tricky bits. Did you ever build something with your research?

  Are you sure? yes | no