Category Archives: 802.15.4

Sniffing 802.15.4 with wireshark and MRF24J40 modules

Wireshark screenshot showing my test data

This is what I did the last two evenings or so. The data being sent is from my example app for my MRF24J40 module library, simrf.

The streaming into wireshark is all thanks to one of the Contiki devs, George Oikonomou’s sensniff project. The peripheral code is just another app using my library.

Neat! This should make some things a bit easier to understand as I move into getting the full networking stack working in Contiki. (You can ignore the warnings from wireshark about the packets being invalid 6LoWPAN frames, all the frames are just raw 802.15.4, with “abcd” being sent as the frame payload.

Further adventures with Contiki OS

I got the (very) basic things working with my port of Contiki OS to my stm32l discovery and stm32vl discovery boards. It was more painful than I expected, there were some unexpected things, but generally, nothing too complicated. Now, I’m at the point where I was hoping to be, starting to try and use the networking stacks in Contiki OS. I want to use the 6LoWPAN implementation, the RPL implementation, the TCP (v4 and v6) implementations.

And here things unravel very quickly. The docs had lead me to believe that I just needed to implement “rtimers” and it would all start working. Turned out the docs referred to an API 5 years out of date. rtimers only actually support a single timer, so you can’t really actually use them in your own apps, you’re really just providing them for the exclusive use of the radio duty cycling (RDC) code. Of which there are multiple styles.

So, yeah, you don’t need to implement them at all. Think of them as rdc_timer and it all makes a lot more sense. They were presumably only introduced at all as the existing timer code (etimer/ctimer) are based on co-operative multi tasking, and RDC algorithms need relatively hard timing to do the radio strobing.

So, what’s the status of Contiki then? The mailing list gives an interesting picture. You’ve got some very advanced topics being discussed about packet loss modelling and distance calculation methods and tweaking the latest draft of CoAP implementation. Then you’ve got posts about simple things that still aren’t fixed like examples simply not even compiling.

Oh yeah, that’s right, did I mention that? There’s examples that don’t compile. You can apply some “fixes” to make them compile, but they’re clearly not the way the makefiles and the project were intended to be, and no-one who might know is

Stepping out again, it starts to feel like Contiki OS isn’t really an OS project that you can use as is. It’s an OS that’s an incubator for other projects. TCP and UDP for both ipv4 and v6, with all of it configurable via an undocumented mix of makefile variables and C preprocessor defines. A windowing toolkit, because why wouldn’t I want to VNC to my battery powered wireless sensor node and click on things. (I’m serious, the current tree includes a graphical calculator app and a vnc server) Three different RDC algorithms. Two different CoAP implementations. A rather large and complex java modelling framework. Two different file systems. Two different webservers and a webbrowser. This is all in the same tree, along with support for ~20 platforms with ~6-7 different architectures.

It starts to make a bit more sense when you realise that it all started out as an operating system for a commodore 64, but that doesn’t really excuse it per se. Shit’s broken. Shit aint improving real fast. Back to the two different sorts of threads on the mailing list and it starts making more sense again. There’s the CS research types, using hardware the previous grad student used, with the magic incantations from the previous researcher, working on really interesting science, and Contiki OS is the base. Then there’s people who are looking around for some modern networking stacks to use on a device of their own. These other people currently have a pretty raw deal. It’s like the Contiki itself really, some really neat cutting edge science, with sharks and hot burning sun and no water nor a soul in sight to ask for help.

Fortunately, there does appear to be a few birds in the sky, hinting at land. Contiki OS’s now a github project, and getting actual pulls, rather than just being hidden inside a Swedish University. There’s a bunch of people who seem keen to try and clean up some of the accumulated cruft of ten years of grad projects being dumped into a repository somewhere. Now if only there was a little bit of direction and documentation from central leaders and we could really sail!

libopencm3 with Contiki on STM32L part 2 – it’s alive, and a stupid error

In a previous post I got to a compiling and linking build for the STM32L Discovery board, but it didn’t actually print anything. Turns out I’d made one of the classically common mistakes with STM32 development, and one of the weakpoints in libopencm3’s api for the RCC module.

rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB2ENR_USART1EN);

The API unfortunately needs both the register, and the bit, and if you can’t see the problem, don’t worry, you’re not alone. The problem is that I was turning on a feature in APB1 (ONE) with a bit definition designed for APB2 (TWO)

When I actually turned on the USART peripheral, everything started working as I expected. I can’t believe how often I’ve done something like this. Or how often I’ve simply not turned on what I needed. Later, I added code to support USART2 and USART3, but…. didn’t turn on those peripherals. Silly me.

But, that does mean that my Contiki port to the STM32L Discovery board is alive:

Much more to come! Radio drivers and more examples and onwards!

Revised MRF24J40 driver code for STM32 and AVR

I meant to post this a while ago, but oh well :) A long time ago I made a basic driver for AVR, then I hacked it up a bit to make it run on the STM32L discovery board. None of the code was common, and the STM32 code was some of my earliest steps in that world. Last summer I started trying to put this all together, but I got busy with other things, and more particularly, I ditched the ST Standard Peripheral Lib and started actively working on libopencm3. Anyway, I eventually got back into project mode, and decided it was time to tidy this all up.

So, here it is. The 3rd edition of my MRF24J40 code. This one should be somewhat more portable to other platforms, as it uses function pointers to set up all the spi and interrupts. (As if anyone else is using this stuff anyway!)

There’s still plenty of tidying up that could be done, there always is, but it’s more going to be a base for further work on Contiki, so it’s probably about as good as it’s getting for now.

802.15.4 export controls

Export controls. Woo, yeah! The USA classed various encryption as a weapon for a while, and tried to prevent it from being “exported” This was relaxed 10-15 years ago, when they realised how absurd it all was. Now, you can buy microelectronics with encryption built in, for instance, and what i’m talking about here, 802.15.4 transceivers have AES encryption built in. It’s a required part of 802.15.4 support after all. However, the way the export controls were relaxed required lots of paperwork, and there’s still some restrictions in place. And the big electronics distributors like digikey and mouser have interesting approaches to following these rules.

Here’s a quick roundup of what I tried to buy today on digikey. Note that all of these parts include AES encryption, as they are all 802.15.4 devices. In some cases, these aren’t even made in the US, they’re made in europe, shipped to distributers in the US, then not allowed out again because of these awesome “export controls”

Note: I live in Iceland, which seems to have fallen into a paperwork crack at some time, most of europe can buy these devices, but not me :(

Microchip’s MRF24J40 modules

Digikey will not sell the MRF24J40MA module by itself, DK partno: MRF24J40MA-I/RM-ND
Digikey will sell the ZENA usb dongle, which is a MRF24J40 radio + USB interface, DK partno: AC182015-1-ND

Mouser will sell the modules.

Farnell said they would sell the modules, then asked me to fill out export restrictions forms (from the UK, not the US!) and has since not replied. (This was about 6 months ago)

ST’s STM32W parts

Digikey will not sell me the STM32W-RFCKIT, DK partno: 497-11406-ND
Digikey will sell me the STEVAL-IDZ401V1, an STM32W based USB dongle. DK partno: 497-12887-ND

Mouser wouldn’t sell me the STM32W-RFCKIT either

TI’s CC2531 parts

Digikey will sell me the TI CC2531 usb dongle, DK partno: 296-28921-ND
Digikey will also sell me CC2531 chips themselves

Freescale’s MC1322x parts

Digikey will not sell me the usb dongle, DK partno: 1322XUSB-ND
I didn’t try buying the parts themselves

Atmel’s range

Digikey will sell me the Raven RZ USB stick, DK partno: ATAVRRZUSBSTICK-ND
Digikey will not sell me the development kit, DK partno: ATAVR128RFA1-EK1-ND

So, awesome job there. I can still buy “restricted” encryption hardware, but only some of it, and only in certain shapes. Fucking ballsup. I’ve spoken to Digikey, (though not with such a list of contradictions) and they brushed me off with, “we just follow the export restrictions guidance from the DOJ” They might bend a bit more if I was ordering 10k units of course, and actually go and check the paperwork, but that’s no help for me today.

Porting Contiki to the STM32L

WARNING – rambling diatribe that might help me….

This is mostly a notepad of what I did, why I think I did it, and what I couldn’t find documented anywhere obvious at the time of writing

Motivation: I am interested in low power wireless sensor nodes. Most of the commonly used MCU operating systems I had looked at treated power usage as a second class citizen at best (if at all) Contiki builds all that in, it’s a primary concern. I abhor the idea of custom wireless protocols (even though I hacked one up for the current nodes in my house) Contiki builds in IPv6 (amongst other protocols) and knows explicitly about 802.15.4 (what I like to use) IP all the way sounds like a pretty smart bet.

So, I want to use contiki on my devices.

Right, big blob of unknown new code. What do I need, where does it need to go…. There’s a rather ugly blob of code in the repository that supports the STM32W series (a rather awkward part to use. No reference manual, binary blobs of radio drivers, the complete inability to order them to Iceland thanks to arbitrary export encryptions, etc) so maybe it would be easy. The code makes no real sense, and seems to be completely abandoned. There’s meant to be ARM support though, so shouldn’t be too hard.

Hrmm. code is split between “cpu” and “platform” Hard to know what should be where.
Oh! Someone just added support for the stm32F1, a chip I know well, no radio driver yet, but that’s ok, I know the MRF24J40 radio well, and would be using that anyway.

Oh, that code got reverted due to (to me) a fairly arbitrary lpgl vs bsd arguments (despite the stm32w code having a binary blob radio driver, let’s not start in there)

Ok, so, nothing says I can’t have my own fork, at least while licensing is worked out. is the best reference I’ve found for getting started so far.

Now, I’ve got the hello world “app” copied into my tree as “foo” and I can do “make” and then ./foo.native and it works.

 karlp@tera:~/src/kcontiki (master *)$ ./foo.native 
Contiki 2.6 started
Rime started with address 2.1
MAC nullmac RDC nullrdc NETWORK Rime
Hello foo world

Excellent, now what? Now I start to leave the comfort of the directions. I decide to copy the reverted stm32f107_basic platform into my tree, still following the Out of Tree Development guide

I’ve added libopencm3 as a git submodule too now. I can do “make TARGET=stm32ldiscovery” and it sort of works, in that it finds platforms/stm32ldiscovery/Makefile.stm32ldiscovery. Now I just need to know what _else_ is needed to go into that makefile. What’s in it now? MCK=72000000, do I really need that? I’d like to not have to care in a makefile. Hrmm. I guess what is really next is sorting out what is part of cpu/arm/xxx and what goes into platform/stm32ldiscovery.

CONTIKI_TARGET_MAIN. What’s that for? why do I need that? grepping the source shows totally inconsistent usages of it. Let’s ignore that for now.

Ok, the libopencm3 based stm32f107basic tree has a uart driver and some newlib stubs. Let’s keep as much of that as possible, and just hack the uart driver to be L1 based rather than F1 based. (This is actually just a difference in gpio AF function settings, the uart code is all identical)

That seems to get a little further, but now we need to get the cpu/arm/stm32f1x_cl code to work out somehow. let’s see how much of that is really “platform” Ok clock.c is opencm3 specific, but not f1x specific. OH! Here’s the MCK setting being used. ok, we’ll set that. rtimer* and mtarch* are all stubs, so that’s ok for now too.

So, a bit more hacking on the cpu/arm/stm32f1x_cl makefile to make it a little more of a “stm32 libopencm3” makefile, and we have a build!

But… does it work? No. setvbuf goes straight into the blocking handler, and puts does too. I guess something didn’t get linked or built properly. But we’re getting somewhere. I’ll look at the backtrace a bit later on, but it’s late.

Code so far in

MRF24J40 driver for STM32

A while ago I put together a C driver for the MRF24J40 802.15.4 modules from microchip. I had been using them as a cheap alternative to xbees in some AVR projects. As I’ve been moving on to STM32 parts for hobby projects, (more power, cheaper) I started off porting my driver code from AVR over to cortex m3.

This has been quite an experience. The arm toolchain experience, and particularly the libc support and general documentation is completely different to, say, avr-libc (AVR-libc is a great project, reallly solid)

However, with lots of learning, and lots of mistakes, I’ve got it all working. It’s a first cut, but the basic features are there. There’s no magic for DMA, and you have to do a lot of the pin setup yourself, but this is Cortex M3, there’s so many pins you could be using for this! I’ve tried to reduce the required function calls as much as possible, but there’s still room for improvement.

    // Required by the user code
    extern void mrf_select(void);  // Chip select, if necessary
    extern void mrf_deselect(void);  // chip deselect, if necessary
    extern uint8_t spi_tx(uint8_t cData);
    extern void _delay_ms(int);  // only used at init time.

This still needs to move to a clear sub project, currently it’s a separate code base to the AVR code.

Get the code now!

More to come, as it gets tidied up and put into use!

Updated MRF24J40 arduino driver

Thanks to pkarck my changes to improve the C library for Microchip’s MRF24J40 802.15.4 modules has been ported to the Arduino library. I’d written an Arduino library some time ago, but hadn’t been maintaining it as I don’t really deal with Arduino much these days. However, it’s gotten some love :) It’s now easier to use, and has support for the power amplifier on the MRF24J40MB modules, if you’re using those. It also makes some quirks I was dealing with in a mixed xbee/mrf24j40 module environment optional. In general, this collects up some of the various reported issues over the last year or so, and I didn’t have to do anything at all!

This is, “teh awesome”.


Getting started with ARM Cortex-M3 (STM32L1xxx) programming

So yeah, we fixed the linux development and programming tools for the STM32 series of ARM cortex M3 chips. And I spent quite a few weeks getting distracted by the tools, and never got around to actually developing for the platform.

Today I sat down to try and wire up a Microchip MRF24J40MA 802.15.4 module to the STM32L discovery board. Seemed straight forward enough, “what pins are for SPI”

“…..” What the… These pins could be anywhere! The reference manual doesn’t say, it refers to the datasheet, which has a table, “Table 5, Alternate function input/output” on page 35 of the actual device datasheet, revision 4. That table says that there are two SPI ports, and they can be made available on a variety of pins. Apparently, SPI1 and SPI2 can be made available on two separate sets of pins each!

All well and good, but how? That’s for another day :)

Fridge Controller – temperature and motor run time, reporting over 802.15.4

One of my most finished projects, mostly because it’s simply much more important than having a battery powered thermometer sitting on a shelf. I brew beer, and serve beer in a converted fridge in my loungeroom. One day, the beer got slow, and what came out was suspicously cold. Turns out the thermostat was broken, so as long as the fridge had power, it was cooling, which resulted in deeply frozen kegs of beer.

It’s a pretty old fridge, that I got free, so I thought about simply getting a new (second hand) fridge and doing the conversion again. A newer fridge would probably be quieter, use less energy, all good things. But, not all fridges are the same shape, and finding one that fit three kegs, and doing all the work of the conversion again just felt like a lot of work. And goddamnit, I’ve been building sensor nodes, I always planned on having nodes that could control things too, so maybe I should just get down to business.

In the end there wasn’t much too it. I’m not doing any fancy PID control, just a set point, and a minimum motor run time, and minimum motor rest time. Initially, it didn’t even listen to any controls from my network, it reported temperature and motor status, but that was it. I had no beer! This was too important to have offline for weeks while I played around 24-480

I got a (massivly overspecced) 25A SSR on ebay, and after a bit of thought about how to keep the cost down, came up with the following schematic:

Full schematic for the fridge controller

The clever bit, if I can call it that, was to not even think about making my own power supply for the control logic. Big companies can make 10 gazillion CE marked, compact, safe switch mode power supplies, and consumers can throw them out by the gazillion. I was just going to have a normal euro 2 prong socket, and a surplus phone charger plug pack with the jack cut off and soldered to the board. Presto, cheap _and_ safe. Far far cheaper, faster and easier than I could have done myself. Of course, the extra socket and jacks take up space, but you can only have so much cake.

There’s really not an awful lot more to it than that. I tested this with a teensy board first, because I could use the nice friendly USB port for debugging, then switched to the ATtiny84, and after a bit of fiddling to get USI working for SPI, it all “just worked” I was suitably impressed when the fridge turned on and off at the right times :)

If you want to make this cheaper, you can just drop the 802.15.4 radio altogether. It worked well enough to keep my beer cold but not frozen before I finished the code to listen for new parameters over the air. But, being able to tweak it’s settings is a nice thing.

The TMP36, or similar, is wired up on a chopped up length of headphone cable. This is the bit that’s easiest to get wrong. Take care with the pinouts of whatever headphone socket you use, and the way you wire which lead to which part of the 3.5mm stereo plug. (If you get it wrong, you’ll read temperatures like 50, then 80, then 90 degrees Celsius, which will actually be _correct_ if you touch the sensor!)

Things I would have liked to have done:

  • Make the headphone socket mount flush on the wall of the box. Just takes more money and time to get the mounting perfect.
  • Use a panel mount socket for both input and output. It would be much tidier, but it takes yet more space, and yet again, more money

Other notes

The SSR I got really needs 3V+ to control. I was mistakenly feeding it with about 2V, from the wrong side of a resistor divider, early on in testing, and the red LED on the device would light up, so I expected it to properly be switching the live side. However, it seems 2V was enough for the LED, but not enough to actually switch. As soon as I gave it 3V, it behaved perfectly.

There’s no LCD display. Which might have been nice, but really, how often do you look at the temperature of your fridge? Besides, because it’s reporting every 10 seconds to “karlnet” it becomes just another node that the rest of my system stores in databases, graphs, or uploads to pachube

The software has a fairly nice way of working with saved state in EEPROM I learnt recently. I’m quite happy with it :) However, in general, the code is a little bit harder to read, because it contains all the debug for a teensy board, with #defines separating the live code from the test code. This is however a fully fledged real demo of my updated MRF24J40 library code


Parts list below.





25A SSR, 3-25V control, 24-480VAC output


7.99 US


grounded euro socket


195 ISK


grounded euro plug


195 ISK


Ungrounded euro socket


181 ISK


3 strand power cable


363 ISK


lunch box


499 ISK


Green LED









1 (optional)



3.5mm stereo socket, board mount




MCP1702, 3.3V regulator






1.58 US


1uF capacitors




5V DC plugpack/wallwart


500 ISK

Second hand store

2×3 pin header for AVR programming


sockets and header pins to comfort




The mouser parts should be available as Shared project 3411228a84 You can substitute something else for the TMP36, that’s just what I had wired up.

Because remember, Digikey are evil, and still refuse to recognise that the 802.15.4 encryption was removed from export restrictions years ago. Digikey, in their infinite wisdom REFUSE TO SHIP 802.15.4 modules to Iceland. We’re terrorists or something.