Making MicaZ motes work with Contiki - an open source operating system for Internet of Things

This blog post describes how to program MicaZ motes under the Contiki Open Source Operating System for Internet of Things (IoT) (http://www.contiki-os.org/).

I recently started putting together devices for an Internet of Robotic Things Lab.
The main idea is to use different sensor, communications and robotics platforms to create a flexible testing environment for various IoT style applications.

I do have Raspberry Pi and Arduino based devices, but I also own the older TelosB and MicaZ motes.  And, I am looking into buying other newer platforms.

The TelosB motes support Contiki well and I have tested them in a bunch of different scenarios (Contiki recognizes them as the sky platform).

However, with the MicaZ motes (http://www.memsic.com/wireless-sensor-networks/), I did not have immediate success. They are programmed the old fashioned way (through a programming board and through a USB interface).

Below  I list a number of issues I have run into and the solutions I put together based on various answers I found scattered over the Internet.   In the rest, I assume that you are familiar with Contiki make and upload commands  (otherwise see here: http://www.contiki-os.org/start.html and also here: https://github.com/contiki-os/contiki/wiki/Contiki-Build-System).


(1) I noticed this first when I was trying to run the hello-world application.  Compilation  (i.e., make TARGET=micaz hello-world) failed with: 
In file included from ../../cpu/avr/dev/flash.c:4:0:
/usr/lib/avr/include/avr/boot.h:112:16: error: attempt to use poisoned "SPMCR"
 #elif defined (SPMCR)

Solution:
This is a bug of avr-gcc, and is well reported. So it was easy to fix. You need to patch /usr/lib/avr/include/avr/boot.h as follows:

#if defined (SPMCSR)
#  define __SPM_REG SPMCSR
#else
 #if defined (SPMCR)
  #  define __SPM_REG SPMCR
#else
  #  error AVR processor does not provide bootloader support!
 #endif
#endif

 (2) Then when compiling blink, another make error:
sudo make TARGET=micaz blink
  CC     ../../platform/micaz/./init­net.c
../../platform/micaz/./init­net.c:64:28: fatal error: net/uip­fw­drv.h: No such file or directory
 #include "net/uip­fw­drv.h"

Solution:
This is again a simple bug to resolve. The path missed "ipv4" in the original file, and hence could not locate the file. Modify init­net.c so that the #include line points out to the right directory:

 #include "net/ipv4/uip­fw­drv.h"

(3)  Then the upload fails (i.e., make TARGET=micaz blink.upload fails) with a uisp error
uisp ­dprog=mib510 ­dserial=/dev/ttyS0 ­dpart=ATmega128 ­­wr_fuse_h=0xd1 ­­wr_fuse_e=ff ­ erase ­­upload if=blink.srec ­­verify
Direct Parallel Access not defined.

Solution:
After trying a few things, I thought the best way is to switch to avrdude instead. I chose to translate the original uisp command to a one that can be understood by avrdude.  At the end, I did the following after compilation to upload (replaces the make command with upload):

> avr­-objcopy -­O srec blink.micaz blink.srec
> sudo avrdude ­-cmib510 -­P/dev/ttyUSB0 ­-pm128 ­-U hfuse:w:0xd1:m ­-U efuse:w:0xff:m ­-e ­-v ­-U flash:w:blink.srec:a

After running this,avrdude verifies and writes to the flash.
When it is all done, you should see:
avrdude done.  Thank you.

Then you should see your Micaz mote blinking.

For more information on avrdude: http://www.nongnu.org/avrdude/user-manual/avrdude.html

Note 1: To run the command, you have to check first which USB port your programmer is connected first. Mine was with /dev/ttyUSB0.

Note2: If you see
avrdude: Yikes!  Invalid device signature.
This is just a poor programmer board and mote connection. Make sure the mote is firmly connected.

Finally, I also tried with the radio-test and two Micaz motes are able to send and hear from each other with this method. Below is a picture of these motes blinking their LEDs as they send, and receive from each other and confirm a bi-directional link.




Now, if you have a TelosB, you will notice that, running radio-test, it won't hear the MicaZ mote, and vice versa. Taking a quick look at the configuration files, there are differences but both types of devices  use IEEE 802.15.4 and are configured with the same PAN id and channel. Hence, this cross-platform communication part requires more investigation.
But, so far so good. 

Comments

Unknown said…
In step 1, you missed one line of "#else", so as in below:

#if defined (SPMCSR)
# define __SPM_REG SPMCSR
#else
#if defined (SPMCR)
# define __SPM_REG SPMCR
# error AVR processor does not provide bootloader support!
#endif
#endif
Unknown said…
As stated here: http://svn.savannah.nongnu.org/viewvc?view=rev&root=avr-libc&revision=2403

Step 1 final change:
/* Check for SPM Control Register in processor. */
#if defined (SPMCSR)
# define __SPM_REG SPMCSR
#else
# if defined (SPMCR)
# define __SPM_REG SPMCR
# else
# error AVR processor does not provide bootloader support!
# endif
#endif