I’ve been playing with some sub-ghz radio modules. I’ve got some different modules laying around. And this time, I’ve decided to look at some Silicon Labs Si4432 based modules. These modules come from AliExpress are marked XL4332-SMT. I’ve seen a variant on LCSC marked AS4432-SMD. There is another variant RF4432PRO by G-NiceRF. The RFM2x series by HopeRF are also based on this chip. The Si4332 is marked as “Not Recommended for new Designs” by Silicon Labs, but that is the case for more popular boards on AliExpress.
When I ordered these, I ordered both a 433 MHz and a 868 MHz version, as those are the two Sub-GHz ISM bands available here in the EU. In the photo are the modules with an 433 MHz Helix-antenna mounted. I’ve looked through the datasheets, and wrote some code to set the frequency registers and data rate registers. I haven’t done the bandwidth filter registers yet. But hey, let’s try first to get some things working with the default settings, before I start customising things. The default frequency is at 915 MHz. This is an American frequency, it is not legal to use it here in Europe. But I confess, I have sinned. I have transmitted at 915 MHz.
I have set the modulation to GFSK and enabled packet mode. Other then that, I have enabled the packet transmitted, and packet received interrupts. Note that when not enabling the interrupt, the interrupt registers work as status registers that do not clear when read. When enabling the interrupts, reading the interrupt status registers will clear them.
I used an RTL2832 SDR to scan the spectrum, and see it is actually transmitting at 915 MHz. For this test, I have used my 868 modules. Then I tried my frequency setting code, and observed the frequency to change to the intended frequency of 868 MHz. Then I proceeded to swap the modules to the 433 MHz ones, and change the frequency accordingly. And again, the SDR confirmed I was at the right frequency. Note that, to test this with the SDR in a graphical way using gqrx, one must transmit packets continuously, a single packet is too short to get noticed.
Well… having confirmed we are transmitting, let’s have a look at receiving… well… I get a packet received interrupt, I read the received packet size. Until here, everything seems fine, but the next step, getting the packet content from the FIFO, something is off. The packet received consists on the last byte of the packet, repeated for the packet size. I am not sure if the problem exists on the sending or the receiving side, or both. I have peeked at some existing implementations for this chip on github, but I don’t see anything obviously different.
Looking at some existing implementations, I can also point out some missing parts, for example, they configure the frequency deviation but not the bandwidth filters. But that is all stuff to think about when I got the basics, receiving a simple packet, working. And that part, does not work (yet).
When all of this works, I wish to look at some other Sub-GHz modules. Looking at Silicon Labs, as they don’t recommend the Si4332 for new designs, they suggest the Si436x series as replacement. So, I might look at those as well. It seems G-NiceRF offers a module with the Si4463 in a module with the same footprint as this one. Other chips to look at are
Semtech SX1231 (eg. HopeRF RFM69 series), Semtech SX127x (HopeRF RFM9x series), ST Spirit1 and S2LP, Nordic nRF905, and Texas Instruments CC1101. Can these different brands communicate with each other? At first glance, they offer the same packet format, and all offer GFSK modulation. So, most of them, if not all, should be able to interoperate. But well… I hope the problems this one chip is giving me ain’t a prediction.
right now, i have almost the same issue with almost the same modules (rfm23b) on rp2-micropython board.I see that it transmit message in the air, but still could not get any received message back.
Could you please share yours register footprint in rx mode (except off course IRQ). This could save a lot of time.
The test code I used is at
I hope this helps,
For this code, run with debugger attached, breakpoint at line
if (dir), then set dir to select between receiver and transmitter.
test_recv()things run as expected up to line 145. I have the correct packet size in
val, but then I wish to
receive this number of bytes from the FIFO, which gives incorrect results.