Department of Electrical Engineering and Computer Science
EECS 194 D. E. Culler
Spring 2008 J. Hui & P. Dutta
Important: Please use the lab worksheet to hand in answers to questions electronically.
This lab focuses on system concepts related to acquisition of meaningful data from a variety of sensors.
We have set up a source control system for the class called subversion. From here on out, all the code that you use and that you turn in and exchange will be done through SVN.
svn co https://isvn.eecs.berkeley.edu/cs194-5 svn
You will have to accept the certificate. When it asks for a passwd, give it a bogus passwd the first time it asks for one so that that it will ask for your user id. Supply your inst named account name and passwd. This checks out the current tree and creates a directory ~/svn.
After modifying your .bashrc you need to source it or open a new terminal window for the changes to take effect. Now you should have an operational source control environment. Verify that $MAKERULES make sense.
./udpserver 1234 // run a listener on port 1234
You should see reports coming from your node showing the raw ADC readings for Vcc and Lux. OK, you are up and running. Time to study the code.
Section 1. Example ADC driver
Study the SampleADC in detail.
Draw a little diagram indicating the relationship of the application component to the ADC driver component and the surrounding kernel.
Modify the application to use Vcc as the reference, build and run it. Record the results. Explain why you get the results that you see.
What change do you need to make to measure Vcc greater than 3 volts?
Verify that the readings are live by covering the light sensor and observing the change.
Section 2. Conversion to Engineering Units
So far we have been using raw ADC counts. The engineering unit of the phenomenon being measured is volts. What is the range of the measured values (in engineering units)? What is the accuracy of the measured value? How do these compare to the range and precision of the ADC outputs?
Modify SampleADC so that it outputs the measurements in units of volts to a precision of 0.1 v.
The obvious way to start is to use FLOATs in the C code. Start there and notice how the code size increases when the floating point libraries are included. (There is no hardware floating point. There almost never is on microcontrollers. ) You will discover that sprintf does not handle %f. So youíll need to work around that.
Eliminate the use of floating point by doing your calculations in fixed point. You may remember for CS61C (and CS150) that one beauty of 2s complement arithmetic is that it does not care where the binary point actually is. (The binary point is all in the eye of the beholder.) Letís use an 8.8 fixed point.
Modify your SampleADC to convert to volts in this fixed point format.
Write a snp_fix(char *buf, int val, int w, int d) that fills in buf with a string of w digits of the fixed point value val including d digits below the decimal point, eg., 2.91 has w=3 and d=2.
Hint: as a development setting, it is pretty convenient to leave udpserver running on 10.97.0.1:1234 just printing out what it gets from the mote. When you update the mote code (either with make reinstall or with swupdate) it stalls for a while and then new stuff shows up after the mote rejoins the network. Cool.
Section 3. Enhancing the Driver to sample internal temperature
Now letís make the embedded application more interesting.
You should notice how every module has two parts: a configuration that defines its external interface and maps that interface to the internal interface, and an implementation of that internal interface.
Modify Msp430AdcDriverC and Msp430AdcDriverP so that it supports a third Read interface ReadChanTemp that reads the internal temperature sensor. Notice how the interfaces multiplex into the same Timer.fired() and signalReadDone() and then demultiplex out with the result events.
Modify SampleADC to sample this additional channel.
Initially you should send out the raw ADC readings for the temperature sensor. Then convert them to engineering units, i.e., degrees F or degrees C. Pay attention to the arithmetic when you do the conversion. What is best for humans to read is not necessarily best for the microcontroller to do.
Notice that the internal Vcc channel and the external Light channel use different ADC timing. You will need to use the more conservative timing of the external channel for the internal Temp sensor.
Section 4. Epic Platform
In this lab, we are also going to make a switch from telosb to the Epic platform. The Epic has the same core chipset as the telosb (TI MSP430 + CC2420), but comes in a form factor that is not only smaller but much easier to work with. Unlike telosb, the Epic exports a wide array of pins.
To make development for the Epic platform easier, weíve developed a development board for the class. The development board brings all the pins out into standard IDC headers. Youíll notice a ring of pins around the epic board. The outer ring is Vcc, the inner ring is GND, and the middle two rings map directly to the pins on the epic platform. A neat little trick with this design is that any pin can be tied to Vcc or GND by simply putting a jumper between them. The development board also adds a USB interface for easy reprogramming and screw terminals for hooking up external devices without soldering.
Notice that without jumpers, the Epic is completely disconnected from the devboard. This is by design. Look at the Epic schematic and connect all DVDD, AVDD, FVDD, RVDD, and 4 GND pins appropriately. Look at the schematic and see what each of the VDD pins are used for.
The epic schematic is available at: EPIC-CORE_A_03-26-2007.pdf
The epic development board schematic is available at: EPIC-DEVBOARD_A2.pdf
Compiling and installing for the epic platform is identical to the telosb:
make epic reinstall
Note that while we typically use the curl to associate a node, you can also set the 802.15.4 parameters during installation as follows:
make epic reinstall,1 154channel,11 154panid,9876
Make sure to use the channel and panid that you have set in /opt/rosetta/conf/rosetta.conf
Section 5. External Channels
Now we are ready to add a ratiometric external sensor. Pull out your RTD from last week. Check its resistance in boiling water and in ice water to get some calibration points.
Connect the RTD with a pull-up using the screw terminals on the epic devboard. This shouldnít require any soldering if you do it right. You can utilize three screws (Vcc, GND, and sense point). Each of the screw terminals map to an IDC header pin. You can then use standard IDC jumper cables to wire them to the appropriate Vcc, GND, and MSP430 pins on the devboard.
From the schematic and the datasheet, construct a table showing the mapping of epic connector pin to MSP430 pin to ADC channel.
Add another channel to SampleADC and the driver to sample this channel too.
Section 6. A Sensor Service
Letís get rid of the ugly static IP address buried in your SampleADC and make it a service. Weíll design a tiny protocol to go along with the reporting. Using udpclient and udpserver from Lab 3 as a starting point, create a new host side program called udplistener that takes a mote IP address, mote port, and listener port as argument. It contacts the mote to tell it where to send readings. It then prints out the strings it gets from the mote containing readings.
You will notice now that listener does not keep printing mote outputs across mote reboots, since the mote lost track of the listener IP:port. So enhance your listener so that if it goes a long time without hearing from the mote it resends the connect request. What you are really doing is building an application protocol over UDP, much like HTTP and IMAP are built over TCP.
In a few sentences, discuss the pros and cons of doing the conversion to engineering units in the embedded device and doing it in the listener.
Section 7. Power Control
Your sensor in Section 5 was probably powered directly by VCC. If we only want to power it when we are sensing something, we want to connect the pull-up to a GPIO output pin. Pick an available GPIO pin on your Telos. Modify SampleADC to drive this high before sampling the channel. You will want to introduce a warm-up time before sampling. How long should it be? Make it a parameter in your code so you can play with it.
Section 8. Sensor Web
Letís turn this simple application into a real physical web server. We are going to use a form of http based RPC called REST (which stands for Representation State Transfer). You can read all about HTTP and REST in wikipedia, but letís play around with it a little bit.
Compile the TCP tools in ~/svn/trunk/lab1/sockets.
Fire up rserver on some port (e.g., ./rserver 1234). If you look at the code, it prints out what it gets and echos it back.
Open up a browser and point it to this port (e.g. http://localhost:1234). Take a look at what gets sent to the server. See the GET request. Trying adding a verb (e.g. http://localhost:1234/func). And now some args ((e.g. http://localhost:1234/fun?arg1=0&arg2=7).
Convert SampleADC to become a web server. Take a look at the example in ~/svn/trunk/lab1/Web. It is up to you to decide how much html to produce, what appears as a document, and what appears as a REST call. Have fun.