CSE 466 Lab 6: Radio Communication and the SuperBird Board
Introduction
In this lab, you'll learn how to use the 802.15.4 radio on the iMote2.
You will extend your accelerometer application to read values
from one iMote2 and transmit them to another iMote2, where you will
draw a spot on the LCD screen corresponding to the tilt of the
accelerometer.
WARNING:
NEVER
attach or detach the iMote2 from the debug board or the sensor board
when power is attached. ALWAYS
make sure you've unplugged ALL of the USB cables when connecting or
disconnecting the sensor board or debug board.
Objectives
In this lab, you will learn:
- how to write applications that use the radio on the iMote2
- how to use the LCD on the SuperBird board
- how to use sound on the SuperBird board
Hints
- Practice
incremental design. Take this lab step by step and test
along the way to make sure you understand your code and verify that it
is working as you expected. Coding the entire project then trying to
debug a problem can be challenging. Make sure to test pieces
of the assignment one at a time and convince yourself that they are
working before moving on to another piece.
- Modules that you can load with modprobe can be automatically loaded at startup by adding them to the /etc/modules file. Lines that start with a ~ are disabled; remove the ~ to enable the modules.
- You can make your own modules loadable with modprobe (and therefore loadable at startup) by placing them in /lib/modules/2.6.14_r1.0/kernel/drivers and adding a line to /lib/modules/2.6.14_r10/modules.dep. This line should contain the full path to the module, followed by a colon, followed by a space-separated list of all modules that must be loaded before your module (this list may be empty.)
Suggested Reading and Resources
NOTE: There is a new version of the radio (tos_mac) driver here. This version does not do a printk every time there is new data in the receive FIFO. You should replace the one in /lib/modules/2.6.14_r1.0/kernel/drivers.
Part 1: Using the radio
In this part, you will be introduced to the radio functionality of the
iMote2. We will give you example code for sending and receiving from
the radio, but you will have to come up with your own packet structure
for your communications protocol.
- Download the radio code here
and un-zip it in your attu account. It should contain the following
files:
- tosmac.h: header file for the radio driver
- count_and_send.c: a program that increments a counter
at 1Hz, displays the counter value as a color on the LED, and sends the
value with the radio
- receive_to_led.c: a program that receives the count via
the radio and displays it as a color on the LED
- led.h: a header file for the simple LED driver that
these programs use
- a Makefile that will build the sample applications
- Change the GROUP_NUMBER constant in
both .c files to your group's number. This will let you send and
receive messages on a channel unique to your group, which is helpful
when you are trying to debug your radio code. Note, however, that your
communications protocol in your own programs, when finished, should use
some kind of unique identifier or address and ignore packets that are
not your own. Your unique channel (again, for debugging purposes only)
will be your group number plus 11.
- Run make to compile the applications.
Load count_and_send onto one of your iMote2s and receive_to_led
on the other. (Make sure that you've updated the tos_mac
driver on both iMote2s, and that you are not
running your PWM driver, which will interfere with the basic LED
driver.)
- You should see the LEDs on both iMote2s updating at the
same time to the same colors. The sending iMote2 will also print out
the current value that it is sending, and the receiving iMote2 will
print out the value that it is receiving.
- Once you're convinced that the programs work, change the
channel back to 11 (set GROUP_NUMBER to 0) and
implement a communications protocol so that your receiving iMote2 will
only update its LED based on messages it receives from your sending
iMote2, even when there are several other iMote2s transmitting on the
same channel. The design of your protocol is up to you, but you should
use at least a unique identifier (use your group number) and an
arbitrary node ID unique to each of your iMote2s.
Note that the tos_mac driver does not implement
the full 802.15.4 standard or the entire ZigBee protocol stack.
Regardless of what you set the destination address to in your
applications, all packets will be sent as broadcast (0xFFFF).
As such, you cannot rely on the 802.15.4 addressing scheme to send
packets to a particular iMote2; you must implement this in the data
payload. (This may be fixed in the current radio driver, but
for now, you should implement the addressing in the data payload.)
Part 2: Combining the radio, accelerometer, and PWM
- Write a new application that will read values from the
accelerometer and send them to your other iMote2. You should
implement a packet structure that incorporates the same addressing as
you used in Part 1, so that your receiving iMote2 will only respond to
packets with its address, and will ignore messages from other groups'
iMote2s.
- Write an application for the receiving iMote2 that
will take the accelerometer values it receives and use them to set the
color of the RGB LED. Use your PWM module.
- Make sure that
your applications are friendly to other groups trying to send radio
packets. Since everyone will be using the same channel, it is
important that you choose a transmit rate that is frequent enough that
the color of the LED is responsive to movement of the other iMote2, but
not so frequent that you are flooding the air with packets. A
rate of 10 updates per second is about right.
Part 3: Using the LCD on the SuperBird board
In this part, you
will learn how to display graphics on the SuperBird's LCD screen.
You will use the LCD to display graphical feedback about the
position of the transmitting iMote2's accelerometer.
- Obtain
a SuperBird board, power supply, and battery from a TA. The
SuperBird board adds several peripherals to the iMote2, including an
LCD screen, speaker, jog dial switch, microphone, and heart rate sensor.
- Turn
off your iMote2 and disconnect it from the USB cable. Connect
it
to the SuperBird. Connect the power cable to the SuperBird,
and
use the power switch (SW4) to turn it on. This should also
turn
on the iMote2.
- Wait for the LED on the iMote2 to turn green, then connect
the USB cable to the PC. You should always connect the iMote2
and SuperBird in this order to ensure that the iMote2 does not turn on
before the SuperBird.
- Run
insmod lcd.ko to load the graphical LCD driver. When you run
cat
/proc/devices, you should see a device called epson-lcd. Run
mknod /dev/lcd c 253 0 (where 253 is the number associated with
epson-lcd) to make an entry in /dev for the LCD.
- You can copy
graphics to the display by writing a raw stream of bytes to /dev/lcd.
The LCD controller expects images to be 132x132 pixels, with
12
bits per pixel. (The actual display is 130x130 pixels; the
rightmost 2 columns and bottom 2 rows are not displayed.) In
order to represent 2 pixels, it takes 3 bytes. Each 4-bit
color
is packed into these 3 bytes as follows: RG BR GB.
- There is an example graphic on the iMote2 that you can
output to the LCD device to test it, with the following command:
dd if=/var/img/cse-boot2.lcdbmp of=/dev/lcd bs=26136 count=1
- Write a C program that allows you to draw a colored square
on the screen at a position you specify.
- Now,
combine this with your previous program. Tilting your
transmit
iMote2 should cause the LED on the receiving iMote2 to change its
color, and should cause the square on the LCD to move to correspond to
the tilt of the sending iMote2.
Part 4: SuperBird buttons & bi-directional
communication
In
this part, you will learn how to read input from the buttons and jog
dial on the SuperBird and implement a bi-directional communications
protocol. You will use the jog dial to tell the transmitting
iMote2 to temporarily stop sending messages.
- Run
insmod superbird.ko to load the driver for the SuperBird buttons, and
create an entry for the corresponding device (superbird in
/proc/devices) at /dev/superbird.
- Download superbird.h,
which contains the ioctls for reading from the switches on the
SuperBird.
- Modify
your program so that pushing the jog dial up sends a message back to
the transmitting iMote2 telling it to stop sending accelerometer data
and start updating its own LED instead.
- Pushing the jog dial down should send a message telling it
to start sending accelerometer data again.
Part 5: Sound on the SuperBird
- Download the sound starter code. The archive contains several items:
- auplay is a simple application for reading an audio file in .au format and playing it back. You won't need this for Lab 6, but you might want to look it over so you can add sounds to your soccer player controller later on.
- simplesynth is a small library for producing a sine tone at a frequency you specify.
- synthtest is an example application that uses simplesynth.
- A makefile for building the above
- A few .au files to use with auplay
- Additionally, sndoutctl is an executable program that allows you to control various parameters of the audio codec on the SuperBird board. Run it without any arguments for usage information.
- Load the audio driver by running modprobe superbird-audio. The audio output device is already present at /dev/dsp (it's device number 14 3 if you're curious.) You may also want to make a node for the superbird-audio device (look up the numbers in /proc/devices) at /dev/sa-test if you want to use the sndoutctl application.
- Run make in the directory with the audio code on your attu account to build the sound applications. Copy auplay, a few sound files, and synthtest to your iMote2 and run them to see what they do and how they work.
- Add a feature to the simplesynth library that allows you to change the amplitude of the waveform that is being played. Test your code by adding a few lines to synthtest to play tones at different amplitudes.
- Now, add the simplesynth library to your program from Part 4 so that the receiving iMote2 plays a tone. The amplitude of the tone should correspond to one of the received accelerometer axes, and the pitch/frequency should be controlled by the other received axis.
Deliverables
- The following files should be turned in:
- Your code, both for your user applications and your
kernel modules
- Your answers to the questions (.txt, .rtf, .pdf, or .doc;
NO .docx)
- Submit files to the Catalyst drop box for your section:
- Demonstrate
your completed Part 5 to a TA during the first half-hour of
next week's lab period.