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/./initnet.c
../../platform/micaz/./initnet.c:64:28: fatal error: net/uipfwdrv.h: No such file or directory
#include "net/uipfwdrv.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 initnet.c so that the #include line points out to the right directory:
#include "net/ipv4/uipfwdrv.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.
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/./initnet.c
../../platform/micaz/./initnet.c:64:28: fatal error: net/uipfwdrv.h: No such file or directory
#include "net/uipfwdrv.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 initnet.c so that the #include line points out to the right directory:
#include "net/ipv4/uipfwdrv.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
#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
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