Last year (Feb 2009) at the Yahoo! Hack Day in India, a Sun SPOT-based project created a bit of interest. The idea of Hack Day is to create something interesting in 24 hours and one group used Sun SPOTs to integrate with Yahoo Instant Messenger. Vittal, one of the creators of this hack, recently reposted his blogs on the project and reminded me how fun it is to read about the twists and turns that projects take as pressure mounts.
Do you have a Sun SPOT developer story?
Let me know. I'd love to hear your story of projects that didn't end up exactly where you expected, or last minute make-or-break changes that you had to make.
So I came in to the office this morning (ok, so I went downstairs to my office, since I work from home, but I digress) and found the following new post on the Forums at sunspotworld.com and had to share it. I'm sharing it verbatim:


As the picture shows above, we made some intelligent vehicles which equipped Sun SPOT as controllers, Infrared Sensors as detectors, LED lights and Motor Drive.We write some program in the IDE of NetBean to simulate and realize Cooperative driver assistance systems, Current floating car data services and User communication and information application.
Using Sun SPOT as controller ,dual motor drive ,Infrared Sensors,LED lights and so on ,We made Intelligent Vehicle models that can avoid obstacle automatically, be controlled remotely and change speed. Meanwhile Sun SPOT is used as tools of communication. We realized wireless communication networks among Intelligent vehicles without any fixed infrastructures called Mobile Ad Hoc Network.
In Cooperative driver assistance systems, when our Infrared Sensors in the intelligent vehicle detect obstacles ahead , it can automatically change its direction, avoiding a crash happens. On the other hand when hard braking happens in one car ,another car behind would stop and change its direction if it is possible. Another example we can automatically lights up or down according the light intensity, so the drivers would not be troubled by the switches.
In Current floating car data services, We use Sun SPOT Base connected with PC as commander to tell the intelligent vehicle where to go and How fast. if the traffic is heave in the way to our destination, we command our car running slower for example.
In User communication and information application We just exploit some host function that can inquire the temperature and light intensity from cars with Sun SPOT.
We write a host program with a visualized Graphical interface as show above .We can remotely control vehicles with functions we mentioned above.
So therer you have it! A very cool project using Sun SPOTs. Go check it out, and post a kudos to the author, since he did such a cool project, and then was kind enough to post about it on our forums!
[ Larkinson's Law:
All laws are basically false. ]
I've been saying this all year, but really, this time I mean it. No, I really REALLY mean it. I'm going to get back to blogging.
So as a start, I'll let you all in on what I've been working on lately. Yes, once again it's more additions to the Sun SPOT Manager. Cool additions, of course. These additions are not out yet, mind you, so don't go looking just yet. But Real Soon Now(tm) I promise.
So what are these new additions? Well, it's an easy way to share (and find shared) pieces of Sun SPOT code. We call them Code Snippets right now. And there will be a new tab on SPOT Manager for Sharing, and finding, Code Snippets. So far, it looks like this:

You can see the Categories of snippets in the left list. (If there are categories you think should be added, let me know via the comments section. We just made these up out of thin air!). Clicking on a Code Snippet in the list will load it into the Code Viewer/Editor pane on the right which gives you complete syntax highlighting, line numbering, etc. All of that goodness is thanks to jSyntaxPane, which is very cool.

jSyntaxPane also gives me a full search capability in a loaded Code Snippet (via ctl-f), including support for regular Expression syntax, if you're into that sort of thing.

I'm also working on adding (well, I've already added it, just need to tweak it some more) full search capabilities so that you can search the Code Snippet database for exactly what you're looking for, based on any of the fields in the database.

And finally, since everyone will want to know just how good their Code Snippets are, there is a rating and commenting system included. So you can select a Code Snippet and add a rating (in Java Coffee Cups, of course!) and a comment. This system is still under development, and will likely be implemented a lot differently than you see here, but there will be a rating and commenting system, for sure.

If you have suggestions on how you'd like to see the ratings and comments done, feel free to drop me a line!
[ May the bluebird of happiness twiddle your bits. ]
Over the last few months we've been working with WPI and 20 high school robotics teams getting the Java SDK for the FIRST Robotics Competition ready for the 2010 season. We've been getting great feedback from the teams including bugs and questions. We've also seen confirmation of the value that Java brings to some teams. One mentor said that they can usually only find a couple of student C++ programmers for the team, but for 2010 they have 10 Java programmers! Or was it 15?
This week FIRST announced a public release of the Java SDK. Here's the official word from Bill's Blog (the official FRC blog):
In addition, I’m very pleased to let you know that an early version of the FRC Java software is now available for download at http://first.wpi.edu/FRC/frcjava.html . I know we promised this for November, and I apologize for being a few days late, but I think you will be very happy with the results. Our hats off to the extraordinarily dedicated Java beta test teams and the developers for all their hard work! Veteran teams, I encourage you to open your doors to rookies in your area interested in getting an early look at Java and how it works with the robot. Remember they don’t have the advantage of having last year’s control system to experiment with.
This early-release SDK is only fully usable by FRC teams that have the cRIO hardware (veteran teams).
Check the FIRST forums to read or request more information.
This Java SDK is based on the Squawk JVM and the Sun SPOT SDK. Rookie teams can get experience with the Netbeans IDE and Java ME APIs by using the Sun SPOT Emulator. See http://sunspotworld.com/frc for more information.
BTW, if you're an experienced Java programmer, don't sit around pouting about how you never get to program dangerous, high-speed, 120 pound robots. Consider being a programming mentor to a local FRC team! See our mentoring tips wiki as well as usfirst.org.
One of my previous blog posts talked about Elliptic Curve Cryptography, why it is being endorsed by the National Security Agency and how a small team of researchers at Sun Labs has had a big hand in promoting its wide-spread industry adoption.
A few days ago, I received notification that the development team behind Apache has finally integrated the patch that makes this next-generation security technology available to the users and administrators of the world's most popular web server. It has been a long, slow journey -- we demonstrated the first version of ECC-enabled Apache at a Sun Labs Open House in 2004 (and you thought high tech moves fast!) -- but I'm excited to see this final chip fall in place. It is a significant milestone in overhauling the cryptographic underpinnings of the World Wide Web.
The timing couldn't be better. NIST guidelines (see pages 63, 66) recommend that key sizes used with RSA (the currently popular incumbent technology) be doubled from 1024- to 2048-bits after 2010 to guarantee adequate protection of sensitive information -- think online banking and e-commerce. The big advantage of ECC is it can provide equivalent security using much smaller keys. More specifically, corresponding ECC key sizes only need to increase from 160- to 224-bits. Since the computational cost of public-key operations grows roughly as the cube of the key-size, the performance advantage of ECC over RSA increases as security needs increase over time:
| Security lifetime | RSA | ECC | Speed-up with ECC |
||
| keysize | ops/s | keysize | ops/s | ||
| Through 2010 | 1024 | 738.9 | 160 | 1783.6 | 2.41 (i.e. 1783.6/738.9) |
| Through 2030 | 2048 | 113.4 | 224 | 711.4 | 6.27 (i.e. 711.4/113.4) |
Table 1 compares the speed of doing an RSA decryption against the speed of an ECDH computation. These are the main cryptographic operations a web server needs to perform for establishing an HTTPS connection. As shown, ECC operations are faster by a factor of more than six for key sizes needed beyond 2010. I wouldn't expect an ECC-based HTTPS server to perform six times better than an RSA-based server because there are other operations in processing an HTTPS request that are common to both. One needs HTTPS-level testing with a tool like httpperf to determine the actual speedup. We did such a study back in 2004 and found that an ECC-based HTTPS server can handle between two to four times as many connections as an RSA-based server (for key sizes needed beyond 2010). I'd love to repeat that experiment with the latest software running on contemporary hardware when I can find some time. Stay tuned.
Scratch is a great visual programming environment for kids created by some folks at MIT. Randy has put together a little code to connect Sun SPOTs to Scratch and has released a video (below) to show you how to do it.
Its easy and fun! Try it out!
If you were a high school student on summer vacation before heading to college and you had a little extra time and some Sun SPOTs, what would you do? How about sending a Sun SPOT to near space?
The whole project is chronicled here: http://hibal.org/missions/apteryx/
They have made their source code available here: http://kenai.com/projects/hibal-spot
Hmmm.... It reminds me a bit of another project
The following article voids warranty. Say your SPOT is "bricked" and you've been through the Q&A on the SpotWorld forum. Some folks don't like RMAs, warranty and would rather fix it themselves. This blog is for them.
A non-responsive SPOT with no USB activity can often be recovered by reflashing the bootloader. The SPOT's JTAG interface can be used to install a new bootloader if the old one is corrupted. We use a custom eSPOT test fixture and Macraigor USB2DEMON JTAG interface with flash programmer/OCD Commander software for reflashing. The test fixture has PCB retaining plastics and Millmax spring loaded "pogo" pins for connecting to the JTAG interface. The test fixture is not publicly available. How you connect to the SPOT pogo pin targets will take some ingenuity. Soldering wires would be easiest; however, soldering the targets make for poor pogo pin contact and can damage our test fixture.
A bricked SPOT will power up and the power LED comes on. The activity LED may be off, or just steady green. If the activity LED is steady red then it failed the SRAM memory test. There will be no USB activity even though different cables and computers are tried.
JTAG
JTAG (Joint Test Action Group) is a synchronous serial interface used for testing complex ICs. The interface is defined by IEEE Standard Test Access Port and Boundary-Scan Architecture, IEEE1149.1. It is used to control external pins (boundary scan), read and modify internal state and interact with internal modules such as the ARMs debug unit. For this application, we are using the ARMs built-in debug unit.
SPOT JTAG Interface
To get to the JTAG pads, you need to disassemble the SPOT. Remove the Phillips screw holding the plastics together and snap apart the sections gently. Disconnect the battery connector. Remove the main board from the plastics by cutting off the two heat-staked pins near the antenna with a sharp knife flush with the board (Xacto or Swiss Army works). Before you remove the board from the plastic, put a piece of tape over the button plastic to hold into place. It's natural disposition is to escape and disappear once the board is free. The board should pop out of the plastics. Flip the board over with the antenna (or MAC label) at the top. On the upper left side, you will notice 3 x 5 array of gold plated pads. The five pads closest to the shield are the JTAG connections to the ARM. The pogopin targets are 0.060" diameter pads. They measure 0.100" between centers and the JTAG row is 0.300" from the edge of the board.
The JTAG signals from top to bottom are TDI, TDO, TMS, TCK and nRST. The JTAG signals lines are pulled down to ground with 10K resistors. The JTAG interface should not obtain power from the SPOT. The SPOT can be powered by a fully-charged battery or USB. RTCK is not used and we do not use adaptive clocking. nRST is connected to system reset and TRST. VCC (3.0V) can be used as the VDD_SENSE voltage, this let's the JTAG interface know what voltage to signal at. VCC is on the first column second pad down and ground on the first column bottom pad. Ground can be alternately connected to the screw hole pad or the USB shield.
Standard JTAG interfaces connect to a 20 pin (2x10) 0.100" pin center keyed male header through a short ribbon cable. The following drawing are the SPOT JTAG connections to that header.
JTAG Interfaces
There are a large number of interfaces and development software packages.We've used the commercial units from Macraigor and the Segger "ARM-ICE" JLink units. They work out of the box and the companies provide support. If you are doing mission critical stuff, this is the way to go.
Recently I've been experimenting with an open source alternative called openocd. It is a command line application that works with a large number of interfaces. SparkFun has a community forum for openocd and they sell the Olimex ARM-USB-OCD based on FTDI FT2232 USB to serial converter. Amontec has similar JTAG interfaces with openocd support. While the FT2232 is a popular JTAG interface, there are licensing issues with the FTDI drivers and the openocd GPL code. The upshot is they do not release binaries and the sources need to be compiled.
There are good writeups on how to build openocd on the Sparkfun forums, through Yagarto and the openocd documentation. For the PC, you can use Mingw or Cygwin. This project uses libtool, automake and autoconf in addition to the usual gcc tools and you will need to install them if you don't have them already. openocd can be downloaded using subversion.
openocd
openocd is an open source software package for interacting ARM processors using JTAG. While it is capable general JTAG usage, it's primary target is the ARM processor. openocd uses a scripting language called Jim to customize to various ARM processors, cores and boards. Jim is a stripped-down version of Tcl.
openocd can be given optional arguments to run a command, execute a script, set debug level or log to a file. If no arguments are given, it will attempt to load the default script, openocd.cfg, in the current working directory. openocd can connect to telnet or gdb to interact with it once it's launched. There is the Zylin plug in modules for Eclipse SDK which add a GUI for all of this.Yagarto has a good writeup on how that is used.
openocd has builtin commands for low level JTAG manipulation, memory peek and poke, and basic debug with breakpoints, trace, run, register dumps. The higher level functions let you probe, erase and write Flash memory.
For the SPOT, my openocd.cfg script is:
telnet_port 4444
gdb_port 3333
source [find interface/arm-usb-ocd.cfg]
source [find board/espot.cfg]
The first two commands tell openocd what telnet and gdb port number it should listen on. By convention, openocd scripts are organized by subdirectories: "interface" contains information about the specific JTAG interface dongle, "target" is the ARM Processor IC and so on. I used the existing Olimex arm-usb-ocd.cfg script and put the rest of the stuff into the espot.cfg board script. You can download the board config file here -> espot.cfg and copy it into your "board" subdirectory.
The 9200 starts at 32KHz, and JTAG needs to run at a fraction of that (4KHz). The initialization routine in the espot.cfg starts the main oscillator and the two phase lock loops going. It enables and sets up both flash and external RAM. Once initialized, the SPOT will be running 180MHz with JTAG at 6MHz.
We lock the first four sectors of Flash to prevent accidental writes of the bootloader in normal operation. Unfortunately, there was some incompatibility with the openocd flash protect command and the Spansion MCP Flash memory we are using. I ended up writing two procedures which will lock and unlock the lower four sectors.
Say you have a working version of openocd. Make your own openocd.cfg script like the one above. If you have a recent SPOT SDK go into the spot sdk directory and find the "arm" directory. Inside is a file called bootloader-spot.bin, copy this file to the same directory your openocd.cfg file is in.
Connect the JTAG interface and the SPOT, power the SPOT and launch openocd. You should get messages that the JTAG interface is happy. Connect with telnet (I use PuTTY) with localhost as IP and port 4444 as telnet port number. Telnet should give an openocd prompt and wait for input. First thing that must be done is to initialize the processor with the command reset init. It should display progress of setting things up and it's slow.
Open On_Chip Debugger
>reset init
JTAG tap: at91rm9200.cpu tap/device found: 0x05b0203f (mfg: 0x01f, part: 0x5b02, ver: 0x0)
JTAG Tap/device matched
srst pulls trst - can not reset into halted mode. Issuing halt after reset.
target state: halted
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x60000013 pc: 0x20000cc0
MMU: disabled, D-Cache: disabled, I-Cache: enabled
4 kHz
Main oscillator stabilized
PLL A locked at 179.712MHz
PLL B locked at 48.05MHz
External Memory Initialized
Clocks enabled
Update cp15 control register
2: 40001078
6000 kHz
>
This will put the ARM into a known good state. Next try:
>flash probe 0
Flash Manufacturer/Device: 0x0001 0x0000
flash 'cfi' found at 0x10000000
It found the flash and can talk to it.
To flash the new bootloader, give it the command flash_boot.
>flash_boot
Flash Manufacturer/Device: 0x0001 0x0000
flash 'cfi' found at 0x10000000
boot section unprotected
auto erase enabled
wrote 19308 byte from file bootloader-spot.bin in 3.922000s (4.807616 kb/s)
boot section protected
You should be able to plug the unit into USB and do a normal ant upgrade from there.
flash_boot is a procedure I wrote which unprotects the lower four sectors, runs the flash write_image and protects the sectors.
I added a few other commands to the script. One was a dirt simple RAM test.
Testing internal RAM at 0x200000 is
>test_ram 0x00200000 64
Testing external RAM at 0x20000000 is
>test_ram 0x20000000 512
alternatingbits
You can fool with the SPOT LEDs too with
>set_led green on
>set_led red off
Exit the session with:
>shutdown
One more thing. Please don't post SPOT problems here in this blog. Better to post them on the sunspotworld forums.
Thanks
-bob
SPOT Toys
Those of you who know me know that I'm a sucker for new gadgets. There have been a few new Sun SPOT accessories that I think are worth mentioning here.
First from our friends at Circuit Monkey is the breadboard for the Sun SPOT. In a similar vein to the very popular Breakout Board the new breadboard allows you to have direct access to all the signals from the Sun SPOT eDemo board and provides a nice little prototyping area for you to design your own circuit. I think that Circuit Monkey has another hit on their hands with this one. Its on sale right now for under $30, so its reasonably priced as well. I've been playing with one of these for a while and I must say its very flexible and lots of fun. It brings out all the signals from the eDemo board (A0-A3, D0-D4, H0-H3, Vh, SW1, SW2, 3V ref., 5V ref ). It also includes probe hooks on the sides of the board so that you can easily connect a scope. Vcc is brought out on 4 connectors and has an LED to confirm that you are getting external power. Quite convenient and very useful. You can get it and other SPOT accessories from Circuit Monkey site.
For the robot enthusiasts in the crowd, here is a Sun SPOT add-on that you might like. As you know, on several occasions I've mentioned the IARoc competition where students compete to perform tasks using Sun SPOTs and iRobot Creates. The Create is basically a version of the iRobot Roomba but without the vacuum cleaner part. Its a really great robot platform and with a Sun SPOT to control it, it becomes a really fun platform to program as well. The robot simulator in Solarium is based on this combination. The folks who put on the IARoc competition every year, Wintriss Techncial School, have made their interface available for others to use. It does the level shifting for the serial interface between the Create and the Sun SPOT as well as provides an interface to an ultrasonic sensor. You can buy it from their online store.
Technorati Tags: spaughts
An Exercise in Hardware for Software People
A lot of people who use Sun SPOTs are software programmers who are interested in connecting the virtual world of software with the physical world around us. Sun SPOTs are a great platform for this, but often people don't know how to get started. Especially for those of you who have very little experience with hardware, its hard to know where to start. Sun SPOT team member David Simmons has some good "Stupid SPOT tricks" in his blog that help with this. Along those same lines I present here my experiences using Sun SPOTs to help grow tomatoes in hopes that it will give a few software folks the courage to meddle a bit with hardware. You see, we've always had bad luck growing tomatoes, but this year, our plants have been doing much better. Now we are in the tricky time when we need to monitor the water that we feed to the tomatoes to make sure we get the optimal development of fruit. I'd like to use Sun SPOTs to make sure that our watering schedule is appropriate.
Choosing a Sensor
I recently wanted to use Sun SPOTs to monitor our garden. A Sun SPOT with and eDemo board can measure light and temperature which is good, but I was also interested in figuring out whether to not to water the garden. To do this, I needed a moisture sensor that could tell me how wet the soil was. With a little web searching I found the VG400 by Vegetronix. It is fairly inexpensive and seems designed to give me the information I want - soil moisture. The first thing to do when evaluating an external sensor like this is to understand how you interface to it. In this case, the specifications on the web site tell us that it requires 800
at 3-12v to operate and that it produces a 0 - 3v analog voltage that varies with the amount of moisture it senses. We can consult the Sun SPOT Theory of Operation to see if this will work with the eDemo board. On page 20 we can see the the eDemo board is able to supply 3 or 5 volts at 100mA. This means we have more than enough power to provide the VG400 the power that it needs. On the top of page 22 we see that Sun SPOT analog inputs A0-A3 measure the voltage range between 0 and 3V. This is a perfect match for the VG400. Theoretically, we could connect up to 4 moisture sensors with a single eDemo board using A0, A1, A2 and A3.
Vegetronix also has a low power version, the VG400-LV, that uses slightly less power (600
), but it only puts out 0 - 1.8V. This would also work, with the eDemo board analog inputs, however, it would limit the resolution of our measurement. Here's why. Looking at the equation on page 22 we see:

is 3V on the eDemo board. The values will range from 0 - 1023 because it is a 10-bit analog to digital converter and
is 1024. This means that a voltage of 3.0V will produce a value of 1023. A voltage of 0V will produce a value of 0. A voltage of 1.8V will produce a value of 614. So the whole range of dry to wet will be represented by values from 0-1023 on the VG400 and from 0-614 on the VG400-LV. That means the scale of the VG400-LV will be compressed into 614 values instead of 1024. Other than those differences the two sensors will be identical. They will connect to the same inputs on Sun SPOT and generally work the same way.

The probe can be used to measure water level and even water volume. The capacitive principle that the probe is based on changes value as the probe is immersed in water. The further it is immersed, the more it changes. This means you could mount several of these in a tank and, with a little calibration, monitor levels inside the tank. I have done only few tests, but it seems quite viable. In the ground, since the water is suspended in the dirt, the probe measures moisture in the area around the probe. Maybe after tomato season I'll try some more experiments to see what other capabilities this sensor has.


Making the Connection
Armed with this information I placed an order with Vegetronix for the VG400. A few days later an unimposing manilla envelope showed up in the mailbox. Inside was the VG400 sensor, just as promised. The disconcerting part was that there was nothing else in the package. No documentation, no receipt, no nothing. For the novice this could be cause for alarm, but have no fear. Closer examination shows that all the documentation we need is conveniently printed directly on the sensor itself. It says:
RED: +V
BLACK: OUT
BARE: GROUND
This makes connecting easy. We just connect the red wire to the pin labelled +5 along the bottom row. The black wire is connected to pin A0 (the analog input that we will use in our software. It could just as easily be any of the other analog input pins. Finally we connect the bare wire to one of the pins on the right side labelled GND.

That's it! No circuit to design. No resistors, capacitors or transistors. Instead, its just wires connected to the Sun SPOT. I used a pair of pliers to bend the wires and just poked them into the connector on my eDemo board. For my purposes, a short term installation, I don't even worry about soldering the connections. I just plugged the wires in and let it go at that.

Software
Next step is the software. This too proves to be fairly straight forward. I started with the SendDataDemo. We will use two parts of this demo, the onSPOT part that runs on the Sun SPOT device and the GUIonDesktop part that displays a graph of the data received. We will need to change the code a little in the onSPOT side to make read the analog input instead of the light sensor which is what it reads by default. For a quick and dirty check of our hardware, I changed one line. On line 56 of sensorSampler.java it gets the lightSensor:
IScalarInput lightSensor = EDemoBoard.getInstance().getLightSensor();
Instead we'd like to get the analog input:

I have tossed around a number of ideas on how to hook Ethernet to the SPOTs. The AT91RM9200 does have a built in Ethernet MAC and we did bring out the RMII interface with the intention of having Ethernet hooked up someday. The design needed an RMII PHY and 50MHz oscillator and we would have to adapt low level MAC drivers and integrate a TCP/IP stack.
I found an interesting option. When I was at the FIRST competition in Atlanta last April, I met with the Luminary Micro folks about their chips. What interested me the most was a low priced Cortex M3 (ARM) processor with built in Ethernet MAC-PHY. For example, the LM3S6432, a Cortex M3 50MHz processor has 96K Flash, 32K SRAM, 10/100 Ethernet MAC/PHY, 3-32 bit timers, SSI/SPI controller, I2C interface, 2-analog comparators, 2 UARTS, 3 channels of 10 bit ADC, 2 PWM outputs. It cost ~$10 through Digikey – a price comparable to my PHY solution. It has open source tools (gcc) and support for the open source lwip TCP/IP stack. When I got back from Atlanta, I got the RDK-S2E reference design kit and the LM3S6965 eval kit to try out. It is possible to hook these up to a SPOT; however, I don't have anything I can release to open-source at this time.
I thought this blog should be about my experience getting the open tools up and running.
Software Development
For this development, I'm using command line on Cygwin running on Windows XP (msys works just as well). Using eclipse and OpenOCD can be added once the tools and process are working.
The Luminary Micro processors are supported by the CodeSourcery, IAR, Keil, and Code Red software development kit (SDKs). These are commercial offerings with support, IDE, updates, etc. The eval board comes with a 30 day trial of one of these tools. CodeSourcery has downloads for the open tools and to get them go to http://www.codesourcery.com website and take the products tab to Sourcery G++ -> Editions -> Lite -> ARM. Take the Download link and EABI link and download the appropriate package for your OS. It's a standard installer and unless you want the IDE, click on minimal install. This should have all the gcc compiler and utilities to make the project.
Next get the StellarisWare driver library: http://www.luminarymicro.com/products/software_updates.html (requires free login account). Download and install either the individual device or complete firmware development package (~100Mbyte). I would also grab the LMFLashProgrammer utility.
The default install location is C:/StellarisWare. In this directory, the board specific demos are in boards. The driver API source and includes are in driverLib. The third-party folder contains two TCP/IP stacks, fatfs, and other utilities. They have low level device includes in the inc directory and useful source subroutines in the utils directory. There is a makefile at every level of folder leading to the project folders. The makefile at the root level (default is C:/StellarisWare) will make all projects for all boards The file makedefs in the root folder does most of the heavy lifting. This leaves the project makefile to do project specific naming, setting paths and dependencies. The makedefs file is included by the project makefile.
The eval boards use a FTDI USB to Serial IC configured as a JTAG programmer and serial port. It has the 20 pin JTAG connector for external programming of other boards but if nothing is plugged into this connector, JTAG will be directed to the processor on that board. JTAG does not require the on-board processor to be programmed. The eval board comes preprogrammed with a cute but eventually annoying game. It can be easily removed by erasing memory on the onboard CPU so you can JTAG in peace. Some of the reference designs boards need the 10pin to 20pin JTAG Adapter module (MDL-ADA2) and I understand it is included with the kits now. The adapter goes between a mini-JTAG 50mil spaced 2 x 5 connector and the standard 100mil 2 x 10 JTAG connector. If the JTAG isn't working properly, try plugging the eval board directly into the PC. FTDI chips have issues working over hubs.
The FTDI chip also has a serial port that is connected to UART0 on the processor. It's handy for debugging.
I created patch files and add-on makefile definitions that can be downloaded here. Unzip this in the top level of the StellarisWare directory. You can run the batch file ./patchstellaris to fix a couple of minor issues: There is a warning about type punning in lwip 1.3 and the fixes an excluded file name in the makefsfile utility in the 4781 release (Thumbs.db needs to be capitalized) .
There is also a makeaux which can be included either inside of makedefs file or in each of your makefiles after the include ${ROOT}/makedefs. makeaux adds "make program" which adds command line programming of the part with the target binary file. It adds "make prune" which moves (or removes) non-gcc files from a project out of the way to reduce clutter. It adds disassembly listing from objdump (.lss) and symbol table target (.sym) from nm. I have found these invaluable for debugging but don't need them all the time.
To create the disassembly and symbol files, add the line to your project makefile
all: ${COMPILER}/<targetname>.lss ${COMPILER}/<targetname>.sym
after:
all: ${COMPILER}/<targetname>.axf
I didn't want to touch makedefs. My changes wouldn't keep up with future releases and I also wanted to keep the external changes to a minimum. "make program" works but will not do the correct build if the bin file is not there. Makedefs creates the binary file as a side effect and my preference would be to make the objcopy as a separate rule. This not only would fix the dependency issue, it would also print that bin file was made. The other nit is that if you are missing or misspell the .ld file it complains about standalone.ld missing and that is a misleading error. I couldn't find any other references to standalone.ld.
Luminary Micro went to some effort to output very succinct info while building rather than printing the multiline gcc command lines. This is very handy although you can turn it off setting the VERBOSE flag as:
make all VERBOSE=1
A small project
Other than the main c file, a project will need:
A good minimal example is blinky in the boards directory.
Edit and add my stuff to the blinky makefile.
Type "make prune" to remove all non-gcc stuff to reduce the
clutter.You should be left with the essential blinky files.
The startup_gcc.c file contains interrupt vectors, data segment initialization and BSS zero fill and call to main. This would be edited to change the interrupt vectors and change the default interrupt service routines.
The linker file (.ld) contains start address and length of the Flash memory and SRAM. If you are using a bootloader, edit the ld file so that the flash origin is 0x00001000. If you are running a standalone app, set this to 0x00000000. You may need to adjust the length as well.
make clean all
All
resulting files including the binary will be placed in a gcc
subdirectory. You can then run the LM Flash Programmer (or type make
program) to program the device. To program over JTAG, you need to set
the LM Flash Programmer configuration to Manual Configuration - JTAG
FTDI Interface JTAG Speed 100000 and use the selected crystal value
of 8.000MHz (for the eval board). From the program tab, select the
bin file in the projects gcc directory and if standalone app, erase
entire flash, verify and reset MCU with program address offset 0.
Once programmed, Blinky will flash the status LED slowly. You should be in business to start exploring their libraries, examples and utilities.
Location, Location, Location (Radio)
This post is a follow-on to my previous post about determining location using the accelerometer. That post proved to be quite popular, and at the time I promised to follow up with a post about finding location via the radio. Well that was some time ago, but finally, here's more about location. This time, as promised, we will talk about how to derive location from a radio. Can you tell where a Sun SPOT device is, using its radio? As with the accelerometer, unfortunately, the news isn't very good. Its quite difficult to get an accurate position from the Sun SPOT radio, but we'll talk through some of the techniques used to figure out where you are in radio space. We'll talk quite a bit about radio propagation. We'll toss in a little math, but nothing too complicated I promise. I hope you enjoy it.
Generally, to find a location using the radio, we want to find our position relative to other devices of known location. There are two basic techniques. Either we need to figure out the distance and bearing to another device of known location (a vector), or we need to find the distance to multiple devices and triangulate to infer a location.
Direction and Distance to a Known Location

In the first technique we need three things to establish the location of the Sun SPOT. We must know the 1) Bearing and 2) Distance to a 3) station of known location. In the diagram above I call the station of known location station, "Home Base." In order to figure out its bearing we need to calculate an angle relative to a known direction. If we had some way to directionally detect radio waves, we could use a magnetometer to get an absolute direction to compare to and then calculate a bearing off of that. Of course, this would mean that we would need to use a directional antenna or other means of determining the direction of the radio signal from the Home Base. Since we don't have a servo controlled, directional antenna on the Sun SPOT, nor a magnetometer, this is very difficult to measure.
Distance to Multiple Known Locations

Since direction is not likely to be an easy thing to calculate, we can take another approach. Perhaps it would be easier to determine our position by simply using distance to multiple known locations. In the image above, if we know that we are 100 meters to Green Base, then we know we are somewhere on 100m diameter sphere (remember radio waves propagate in 3 dimensions, not just a two dimensional circle) with the Green Base as a center. If we also know that we are 80 meters from the red base, then we know that we are somewhere along the intersection of the green sphere and an 80m diameter sphere with the Red Base as a center. The intersection of two spheres is an ellipse, with three spheres you get two points and finally with a known distance from four other devices, you should be able to pinpoint your location. Of course, most methods of measuring distance in the real world are not completely accurate, so more distances makes for more accuracy in your estimation of position.
One common problem with this technique is that it usually takes time to get these distances. To put it another way you cannot get all the distances simultaneously. If you move between measurements it will affect the accuracy of your estimate. The process assumes that you don't move between measurements. So we must either assume that both our device and the devices we are measuring are stopped during the measurement or apply a level of uncertainty relative to the total amount we and the reference locations could move during the measurement.
Time of Flight
Great, now we've reduced the location problem to just being able to measure distance. This should be easier right? A logical way to measure distance would be by calculating "time of flight" of the radio signal. In other words, calculate how long it takes the signal to get from transmitter to receiver. Let's take a look at this. Radio waves propagate at the speed of light or about 299,792,458 m/sec. This means that a radio wave covers one meter in about 0.000000003334 seconds or just over 3.3 nanoseconds. So, it can cover 3 times the radio range of a typical Sun SPOT in a single microsecond. One thing for sure is that we will need very accurate timings if there is any chance of getting reasonable accuracy to our measurements. The current eSPOT has a 180 MHz clock, or just over 5.5 nanaoseconds/clock. This means that every clock cycle corresponds to about 1.7 meters of radio propagation. Furthermore, the IEEE 802.15.4 radio standard that the eSPOT uses can transmit at 250kbits/sec. That means that a single bit has nearly 1200 meters between its start and finish. Or to put it another way, since the Sun SPOT range is roughly 100m, the start of a bit is always received long before the end of a bit is sent. This isn't strictly true because IEEE 802.15.4 radios use a more complex coding scheme than just sending a bit as an on or off (I explain this amore below), but the point still stands. A bit is much too large a resolution within a few meters.
For this method of measuring distance to have any chance of working we must measure the onset of the leading or trailing end of a bit - some sort of an instantaneous synchronization signal. It would be quite difficult to get any accuracy at all if any software were in the loop because timing is so critical. In order for this to be practical, we would need to have the ability to time tag arriving packets in hardware and not wait a potentially variable amount of time for something like an interrupt to get serviced. Additionally, we would probably need something similar on the output so that we could time tag packets as they are actually being sent. Its not good enough to time stamp them as they are put into the queue to be sent, they would need to be stamped as they are sent out.
However, even if you were able to get the exact time that a packet leaves one device and the exact time that it is received by another, there is still the problem of synchronizing clocks. It would appear that we would have to have clocks that are synchronized to the nanosecond. This seems like another very difficult task until you consider the following. Lets assume that at time
Sun SPOT device
has a clock time of
while Sun SPOT
has a clock time of
. At exactly this moment,
sends our synchronization signal over the radio. We would like to know the propagation time
. We know that
will receive the signal at time
where
![]()
the problem is we don't know
. We don't know the exact reading of another Sun SPOT device's clock at any given time. Either together with the synchronization signal or in a separate message
can tell
what time it believes the signal was sent (ie
). Since the clocks are not calibrated, this may have little relation to the time on the other Sun SPOT device. Using the information available to it,
could calculate a preliminary propagation time (
) as:
![]()
Unless by dumb luck the clocks are synchronized to the nanosecond (not likely), we know that
is incorrect. Let's suppose further that the difference between the two clocks is
.
![]()
We know that the true propagation time,
, is different from the calculated one,
, by
.
![]()
We really need to know the difference in the clocks,
, before we can calculate the true propagation time,
. Suppose that we repeat the experiment going the opposite direction. Then if we assume that the clocks do not drift with respect to each other (a big if at this level) and that the next synchronization signal is sent at
and received at
then we get:
![]()
Now if we make further assumptions that the devices have not moved and that the speed of light has remained basically constant (which for our purposes it is probably reasonable to assume), then we can assume that the propagation time
is also incorrect by
but in the opposite direction.
![]()
thus
![]()
![]()
![]()
Therefore now that we know
, we can plug it in to get the true propagation time:
![]()
These values can be measures, so new we have the true propagation time,
. Now we just divide by the speed of light to get the distance in meters:
![]()
This means that in theory, with proper hardware support we should be able to determine the distance to another device by measuring the time of flight of the radio signal. Practically however, even with hardware assistance, its hard to see how we would get more than about ten of meters of accuracy under good conditions, which is one tenth of the range of an eSPOT. Actually measuring with this precision and accuracy proves quite difficult.
However, our problems with this method aren't over yet. To most computer scientists, the idea sending a bit over a radio seems quite natural, but actually radio waves aren't digital. Digital bits are a convenient simplification that we apply to the real analog world. The signal that is sent is not a bit but an analog encoding of a bit. In 2.4 GHz IEEE 802.15.4 radios used by the eSPOT, data is encoded using Offset Quadrature Phase-Shift Keying (OQPSK). This encoding scheme must be decoded by the receiver and turned into bits. As the signal travels in the air and is affected by its surroundings, other signals and general noise, the characteristic of this signal can change. This means that the receiver needs to do some work to interpret the signal it is receiving. It needs to listen to it long enough to interpret what it is hearing. While this happens very quickly, the time required to notice the signal changes could actually vary slightly depending on the shape of the received signal. Even a few nanoseconds of variations will affect the accuracy of our distance estimations.
The current eSPOT hardware does include some ability to time stamp received packets in hardware, but its not clear to me that is has anything like the required accuracy or precision for the task of measuring time of flight.
Distance From Signal Strength
This leaves us looking for other ways of measuring distance using the radio. Perhaps the most promising is the use of Radio Signal Strength (RSS). It seems intuitive that RSS and distance transmitted are related by the inverse square law. In theory as distance goes up, RSS goes down and vice versa. As I've often found in life, the difference between theory and practice in much greater in practice than it is in theory. In the real world we find this is not strictly true.
One of the early programs that we wrote for the Sun SPOTs was a simple Therimin simulation. The Therimin is a unique electronic instrument that lets the user play music by waving their hands near two antennas that protrude from the device. One controls the volume and the other controls the pitch. Our version was inspired by this, but quite a bit simpler. It simply translated RSS values between two Sun SPOT devices into pitch values for a MIDI synthesizer. Unfortunately, we found it very frustrating to play because there was no strict mapping between distance and the notes that were played. We could start with the two Sun SPOT devices far apart and then slowly bring them together. We would expect this to create an increasing musical scale on the MIDI keyboard. While it was true that holding the SPOTs close together would cause a high note to play and holding them far apart would cause a low note to play, the transition from far to near was full of ups and downs. We double checked our code, but everything seemed to be in order. What was going on?
The problem was that radio propagation is fairly complex thing. At the 2.4GHz frequency range that the eSPOT uses for its radio, the signal propagates by line-of-sight. This generally means that if two eSPOTs are within visual range of each other and <~100m from each other, then should be able to communicate. The problem is that many factors can affect this signal propagation. Early on in the life of the Sun SPOT project, many of our demonstrations would be working perfectly until a crowd of people entered the room to see the demo. We experienced our own little version of a Heisenbug (a bug whose behavior changes when you try to observe it). These, "ugly bags of mostly water" (as Enterprise computer once referred to humans) tend to absorb radio signals. Remember that microwave ovens work in a similar frequency range. The eSPOT radios don't put out anywhere near enough energy to cook a hotdog or much or anything, but people and other water based items in the vicinity can absorb signals. Our observers changed the radio characteristics of our demonstration area just enough to upset our demo.

It turns out that line-of-sight propagation is much more than it may seem. A Sun SPOT does not have a highly directional antenna, so it transmits in all directions, not just toward the intended receiver. While some of this signal finds its way directly to the receiver, more of it will wander off in other directions. If one of these wandering signals bounces in such as way that the bounced signal also finds its way to the receiver, it will have taken a slightly longer path to the receiver than the direct signal. Because of this, it will arrive slightly out of phase with the direct signal. When a signal is received along two or more different routes, the condition is called multipath propagation. The receiver receives a mixture of these tow signals. The amount that the multiple paths affect the signal will change depending on the amount of delay and the strength of the signals experiences being mixed, as shown in the figures below:
The receiver will receive a signal that is the direct signal and the reflected signal mixed together. In mathematical terms this means the signals are added. The first graph shows two signals that are received slightly out of phase with each other (the same signal, just delayed slightly) and the red line is the sum of these signals. The RSS is measured as the amplitude (difference between the lowest and highest values) of the signal received. As you can see, the red line has more amplitude, and so a device receiving this signal will register a stronger signal strength than a device just receiving a direct line-of-sight signal. However, the signals don't always mix in a way that has a positive effect on signal strength.

Sometimes the way these signals add has a net negative effect on the signal strength. In the second graph, the two signals in black add to produce a red signal that has lower amplitude (and signal strength) than either signal individually. They are canceling each other out. You can imagine a situation where the reflected signal is delayed by exactly half a wavelength and thus effectively cancels the original signal completely. In addition to the phase shift caused by the delay, there is usually a bit of difference in amplitude between the signals because the direct signal is usually stronger than the reflected signal. This, and the fact that there are usually many reflected signals, will often keep the signal from being completely cancelled out, so in practice signals will vary significantly and in ways that are difficult to predict, but rarely will cancel completely.
There is something called the Fresnel zone (pronounced fray-NELL) that is an ellipsoid area around of the direct line between two communicating devices.
The zones help to define the effects of the reflections. You can calculate the size of radius of the Fresnel zone with the following equation:
![]()
where
is the distance in meters between the devices,
is the frequency in GHz,
is the Fresnel zone and
is the radius in meters. So for example, if two Sun SPOT devices are 100m apart, and they use the built-in 2.4GHz radios, we get a value for
of 1.77m for zone 1. This is the radius of the zone at its widest point (in the middle). Reflections in Fresnel zone 1 tend to cancel the original signal. Along an ellipsoid shape that is zone 2 (2.5m in our case) the signals will tend to add. Fresnel zone 3 would produce an
value of 3.06m, and so on. In general, reflections in odd numbered zones tend to cancel the direct signal while signals in the even number zones tend to add to the signal strength. It is good to keep at least Fresnel zone 1 clear if possible.
Of course, if the two devices are closer together, then
is smaller. So, for example, if the two devices are only 1 meter apart, then zone 1
would be a mere 17cm. Zone 2 would be 25cm. So moving something reflective to radio waves that is half way between the two devices only 8cm can make the difference between a very strong signal and a very weak signal. Of course, something closer to either device (the end of the ellipsoid) would have to move even less to have a similar effect. Near either of the devices, something moving only a few centimeters could completely change the signal characteristics. Similarly, moving a Sun SPOT device only a few centimeters could completely change the characteristics of the multi-path signal that is reaching it.
We can construct a hypothetical extreme case. The wavelength of the radio signals sent by the eSPOT is about 12.5 cm. This means that in the extreme case of a direct signal and a reflected signal of equal amplitude at right angles to each other, you can go from double signal strength to no signal at all in half a wavelength which is just over 6 cm. Note that this will be true regardless of how far away the two devices are from each other. This makes it very difficult to find a correlation between distance and Radio Signal Strength.
This brings up another question about these radio waves. What types of materials will affect the propagation of a radio signal? We know that they travel optimally through open air (or a vacuum). We know that, at this high frequency, many things tend to affect the signal. In general, metal will reflect signals and water will absorb it, but most things will do some amount of each. Plastic, paper and drywall tend to have little effect on the signal since they aren't metallic and have little water in them. A metal white board in a room can have a large effect on radio propagation. One of the most important materials is the ground. It can both absorb and reflect. Reflections from the ground are a common cause of interference. If we want to keep Fresnel zone 1 clear and get 100m of transmission, then we know from the calculation above that we need to keep them at least 1.7m off the ground and would prefer to be closer to 2.5m.
The story gets even more complicated when we look more closely at the what is going on. There are three phenomena at work when the radio waves encounter a an obstacle: reflection, diffraction and refraction. We discussed reflection earlier. Diffraction occurs when a wave passes by an obstacle or through a small opening and appears to bend. Refraction is the change in direction as a result of a change in speed of a wave as it travels through different media. Refraction is the least common since the speed of light is fairly constant within the realm where we working. However, the diffraction has a real effect. In particular, there is a phenomenon called Edge Diffraction that applies to radio propagation in these frequencies.
Imagine a Sun SPOT device transmitting a signal over a an open area with a single obstruction in it that can block the radio waves. One would expect that the obstruction would create a a radio "shadow" where no signal can reach. Instead, the signal at this point creates a new wavefront at the edge of the obstruction that propagates into the shadow area providing a weak, but sometimes usable diffracted signal. The area of direct propagation just beyond the top of the obstruction now exhibits an interference pattern with the refracted signal causing sporadic losses in the area labeled diffraction loss. Also, some of the signal will be reflected and this will create an interference pattern with the direct propagation wave in the area in front of the obstacle. All these affect signal strength. A similar condition occurs with a radio signal goes through a small opening. Diffraction occurs at the edges and interference patterns result that cause difficult to predict changes in signal strength.
If we want to get really esoteric, there are atmospheric conditions that can affect signal propagation. For instance humidity in the air can affect signal strength. Remember, water tends to absorb radio signals. This means that in addition to objects in the vicinity of the propagation path, even changes in the weather can affect signal strength. This effect is usually not as strong as some of the others mentioned above, but is can be noticeable. In some cases it can cause an effect known as Tropospheric Ducting where signals find paths through "pipes in the sky" created by certain atmospheric conditions that can go on for thousands of miles. This can cause otherwise line of sight signals to travel great distances around the earth. I've never heard of anything like this happening with a radio signal from an eSPOT, but it does show the counter intuitive nature of radio propagation. Besides, "Tropospheric Ducting" is just a cool term to be able to throw out in conversation, so I thought I'd tell you a little about it.
Radio Space Shape

As if all this weren't enough, most of these schemes assume a uniform signal radiating in all directions from the Sun SPOT device. This is simply not true in practice. The diagram at left shows the actual measured propagation pattern of the eSPOT antenna. If it were very uniform, we would see a spherical shape. Instead we see an indescribable shape with all sorts of different lobes and divots. You can see a > 10dB difference between the strongest and weakest edges of the signal. This means that you can change the signal strength can easily more than double just by changing the rotation of the Sun SPOT device. So the orientation of an eSPOT is very important in controlling for signal strength.
Of course, given what we've learned about diffraction and reflection of radio signals, you can see that this also means that in some cases a stronger signal may be aimed as a reflection rather than a direct route which will cause all sorts of confusion when it comes to signal interference and cancellation.
So where does this leave us? Just like with the accelerometer, finding the location of a Sun SPOT using the radio does not look very promising. In theory, we might be able to determine location if the following conditions were met:
1) There are no obstacles anywhere near the Sun SPOT devices or the area between them (for many Fresnel zones) that could reflect, refract, diffract or absorb the signal.
2) The Sun SPOT devices are many meters off the ground
3) The Sun SPOT devices do not change orientation with respect to each other.
4) The Sun SPOT devices don't move between measurements
If ANY of these rules is broken the result is a radio space that is for all practical purposes nearly impossible to predict. On a large scale, the closer devices are the greater their signal strength, but locally this will not hold true.
I'd be happy to be proven wrong. As always, all my gloom and doom may inspire someone to figure out a good way around these limitations and prove that you can measure location with radio and/or acceleration. Sometimes there is no greater motivation than saying it can't be done. Have fun. In the mean time, if you get unexpected readings of radio signal strength, now you may at least have an idea why it is happening.
I stand by now for your questions and comments.
Sun SPOT V5.0 Red Release
Its been a busy summertime so far and I realized that I haven't yet mentioned our new release here... so, here's the scoop: The new v5.0 Red release is available now from SPOTManager. As always, remember it includes an emulator so you can play with it even if you don't have any physical Sun SPOT devices.
Here are a few interesting things to check out in the new release:

Updates to Solarium
Solarium includes several new views that add significantly to its usefulness. Radio View, Robot Simulator and Deployment View. Each is described below. Also, there is a new demo that shows how to add your own extentions to Solarium (SolariumExtensionDemo ).
Robot Simulator


Solarium now includes a robot simulator that lets you program a virtual Sun SPOT-based robot to navigate a maze and other virtual obstacles. These robots are based roughly on the iRobot Create which is a fine little robotics platform used in the IAROC competition among other things. From Solarium, simply open the RobotView and then click on "Add Robot." This will create a robot and virtual Sun SPOT to control it. You can even run multiple robots at the same time in the simulator. Its quite fun. Try the tutorial here.
RadioView

Radio View give you a visualization of the radio space of your Sun SPOTs. Its tells you which devices can talk to each other and the relative signal strength of the connection in each direction. This makes it much easier to construct multi-hop experiments and understand issues with your network topology. Click on a node to get information about its transmit power, MAC filtering and routing manager. Click on a link to get information about the strength ofJust open a Radio View from within Solarium to try it out.

Crypto Library
The Sun SPOT platform includes advanced cryptographic capabilities. Many people don't even know that they are using Elliptic Curve Cryptography every time they deploy code to their Sun SPOTs, but they are. The system verifies the owner and validity of the code during deployment.
Now there is a demonstration of the SSL library for the Sun SPOTs based on the code in Sun's reference implementation of Java ME for cell phone. The Sun SPOT SSL library includes support for TLS 1.0, support for server-side SSL/TLS, support for Elliptic Curve Cryptography cipher suites (for now, only ECDH-ECDSA-RC4-SHA and secp160r1 are supported).
SPOT Web
SPOTWebDemo is a host application that starts up a simple web server and lets remote users interact with a collection of SPOTs in the vicinty of the attached basestation using a standard web browser. Authorized remote users can monitor the state of sensors, applications and other system statistics. They can also install, start, pause, resume, stop and remove applications. This allows you to do many of the functions that you would do in Solarium, via a standard web browser.
Yggdrasil
Many applications on Sun SPOT devices collect data. Yggdrasil is a data collection framework to allow you to stream sensor data to a centralized repository. The demo provides libraries and sample code to use the framework. The way that Yggdrasil works, the Sun SPOT sends sensor samples to host for the first time. The host does not recognize the sensor, so it queries the Sun SPOT. The Sun SPOT responds with handshake information and metadata about the sensor. Now the host knows about the sensor and begins to print out the sample data as it arrives.
AirStore

AirStore is an experimental shared data repository for Sun SPOT applications. It is designed to make a common usage of Sun SPOTs much easier... sharing simple data. Currently, when you write a program and want it to share data with another Sun SPOT over the radio, you have write some code to set up and transmit your data. Similarly, you have to write code to receive the data on the other side. AirStore attempts to make this much easier. With simple one line puts and gets, distributed applications can share primitive Java data types. One Sun SPOT application can set a variable x with
AirStore.put(x, 17);
and another can get x with
int x = AirStore.getInt(x);
The system works in cases where all devices are within broadcast range of each other and do not sleep. Thus for UI experiments or simple robot control, this method can work well. The data types supported are: int, double, String, boolean, byte, long, plus arrays of these types.
If you look in the demos folder you will find documentation, and inspector (host application) as well as several example programs including a rather interesting integration of Sun SPOT with a popular programming environment for kids called Scratch.
Other Enhancements
TWI (two-wire interface) is now supported to both the eDemoBoard and main ARM9 processor board.
You can now limit received radio packets to those from a sender on a whitelist or not on a blacklist.
Sun SPOTs are tiny, battery-powered, wireless computers that can be programmed in Java. Different types of sensors (e.g. GPS, temperature, humidity, proximity, light) and actuators (e.g. servos, motors) can be attached to these devices for use in a wide range of applications. It has been more than
two years since we started selling these and they've proved quite popular with students, researchers and hobbyists (see here and here for some pictures/videos of Sun SPOT-based projects from around the world). This blog entry discusses two web-based services - SPOTWeb and Sensor.Network - for interacting with these devices and collecting, analyzing and visualizing data from attached sensors.
The SPOTWeb service lets remote users interact with a network of SPOTs using a standard browser. Authorized users can monitor the state of sensors, applications and other system statistics. They can also install, start, pause, resume, stop and remove applications. In the following video, I walk you through many of these features (I recommend the HD-version in full-screen mode to minimize the blurriness of on-screen text). You can follow along on your own by downloading the latest SPOT SDK (red-090706 at the time of this writing) from sunspotworld.com and running SPOTWebDemo (it is one of the new demos bundled with the red release).
Sensor.Network is a web-based service for sharing, visualizing and analyzing sensor data collected from a variety of sources, e.g. mobile phones, automobiles, datacenters or embedded devices like the Sun SPOT. Besides supporting a heterogenous mix of data sources, the service supports multiple sensor installations, each of which could potentially be owned by a different entity. It places a strong emphasis on security and privacy concerns and gives researchers and scientists fine-grained control over how their data is shared with authorized partners. Additional details are available in this article. The service is still under development but the following video filmed during JavaOne 2009 provides a good overview of the currently available functionality.
Last month, I demonstrated SPOTWeb and Sensor.Network at a meeting of the Sensor Web Enablement working group at the Open GeoSpatial Consortium (OGC). The OGC is an international organization that develops standards for geospatial content and services, GIS data processing and data sharing, e.g. KML (used by Google Earth) and Sensor ML. Both of these are of interest to our potential customers like the USGS.
We are currently in the process of integrating SPOTWeb and Sensor.Network more closely and finalizing a REST-based API for Sensor.Network that would allow others to input, retrieve and share their sensor data with strong access controls.
The Internet started out in 1969 as a network of four nodes (it was called the ARPANET back then). Today, it has grown to over half-a-billion nodes that include not just computers (mainframes, servers, desktops, laptops, netbooks) but also PDAs, smart phones, automobiles, industrial equipment and home appliances. New technological developments, like the ones outlined here, promise to extend the Internet's reach to even smaller, more ubiquitous devices turning it into the "Internet of Things".
The eSPOT demo board has an Atmel AVR microcontroller (MCU) for LEDs, pushbuttons and general IO. This MCU comes preprogrammed at the factory and can be reprogrammed in the field with an ant upgrade command. A SPOT owner might wish to change the firmware to either add functionality or do something the eDemo board currently doesn't provide.
The latest Red release of the SPOT SDK will program the eDemo AVR firmware directly and without a bootloader during the upgrade process. The same code that is used to upgrade the eDemo board firmware can be used to load custom firmware into the eDemo AVR. This blog walks you through the steps of downloading a tool chain for Windows and programming a simple example on the eDemo board. It does use an existing java class that is in the Red release of the SPOT SDK and this SDK must be installed on the desktop and the target SPOT plugged into USB for this to work.
The firmware for the AVR MCU is written in C and compiled using the open source avr-gcc, Gnu Compiler Collection . Warning: modifying the firmware can render the SPOT inoperable or bricked. Most RMA Bricked SPOTs eventually end up in my office and while we recover most of them, it is a slow process. You've been warned.
As a prerequisite, you should have working knowledge of the C programming language, be able to use gcc tools especially make and know your way around a microcontroller. If you want to learn C, I'd start with the Kernighan and Ritchie book, "The C Programming Language" and use the abundant material online. For learning about the AVR MCU, a place to start is with AVRFreaks for forums, downloads, tutorials, etc. The datasheet for the Atmega88 is needed for code development and can be downloaded here. The current eDemo board (Rev 5.x and before) uses the Atmega88 or Atmega88V. Atmel is replacing this part with the Atmega88PA but we are not using that part yet.
The Atmega MCU has 8Kbytes of Flash memory, 1Kbyte of SRAM, and 512 bytes of EEPROM. It has built in peripherals such as general purpose IO, analog to digital converters, serial interfaces (UART, I2C/TWI, SPI), and timer/counters. The peripherals share pins in common and interact with the processor through memory mapped registers. The registers are set to default values on reset. The default values and register/bit field naming are all in the Atmega88 datasheet.
The tool chain
Tool chains come in a lot of flavors and for different operating systems. For example, the IAR Workbench is a commercial and complete integrated development environment (IDE). It has source code editors, build automation tools, compilers, libraries and debugging built in. Net Beans, Eclipse, AVR Studio and Programmers Notepad (included with WinAVR) are open source IDEs with front end extensions to run compilers, debuggers and build automation programs. There is a good write-up at Linux Journal on putting the tool chain in Linux for the AVR. WinAVR is one of the best AVR tool chain packages for Windows. There is a plugin for Eclipse and WinAVR.
On Windows, you can run the tools from command line using Cygwin. Cygwin is an open sourced Linux-like environment that runs on Microsoft Windows. It uses Linux syntax but there are differences between the two which can cause problems from to time such as spaces in filenames, the use of '\' or '/' as path names and the drive letter. The advantage of Cygwin is there are a large number of additional tools and utilities that can be downloaded with it.
A typical avr-gcc tool chain flow starts with the source code in C (.c file extension), assembler (.s) and the header or include files (.h). The header files contain the function prototypes, typedefs, macros (#define) and other preprocessor directives. As a rule of thumb, if it directly generates code or data, it probably shouldn't be in the include file. After preprocess, the source is compiled into an object file (.o), a relocatable compiled code module with external references unresolved. The next phase, GCC takes on the linker role and combines the object files into a single executable link format (.elf).
avr-objcopy tool then converts the .elf file into a formatted binary file (.hex intel format) that can be programmed into the flash memory of the MCU. The tool chain process can be automated using the 'make' utility. make reads the rules of how a project is made from makefile script (Makefile) and determine, from the modify date of the files, which tools need to be run to bring everything up to date.
Installing the command line tool chain on Windows
Install cygwin on your system and launch it. The first time cygwin window opens, it creates a C:\cygwin\home\<user> directory with the default startup script .bashrc. Edit this script and add at the end:
#----------------
export WEBBROWSER=`sed -e 's/" *-.*//' -e 's/\\\\/\//g' -e 's/"//' '/proc/registry/HKEY_CLASSES_ROOT/http/shell/open/command/@'`
export SPOTHOME=`sed -n "/^sunspot.home/{s/sunspot.home=//;s/ /\ /g;p}" "$USERPROFILE/.sunspot.properties"`
export JAVADOCS=`cygpath -wa $SPOTHOME/doc/javadoc/index.html`
alias ports='devcon status =ports'
alias resetspot='devcon restart USB\\VID_0430\&PID_1000\*'
alias spot='cd "$SPOTHOME"'
alias spotdoc='"$WEBBROWSER" "$JAVADOCS"&'
alias spotfinder='"$SPOTHOME/bin/spotfinder.exe"'
#----------------
Save this file and restart the cygwin window.
This adds SPOT relate bash commands:
spot - changes the current working directory to be the currently installed SPOT SDK directory
spotdoc - opens current SPOT SDK javadoc with the default browser
spotfinder - opens the current SPOT SDK's spotfinder command.
ports - lists all ports in use
resetspot - reset the SPOT USB port
You must have the Red SPOT SDK installed (Click here for installer). If not, SPOTHOME will not be defined and spot, spotdoc and spotfinder will not work. If you activate or install a different release of the SPOT SDK, you will have to restart Cygwin. For ports and resetspot, you need devcon. Devcon can be downloaded from Microsoft here. Move devcon to C:\cygwin\usr\local\bin folder. Devcon is Microsoft's command line device manager for Windows and handy when dealing with USB devices.
I have had problems with cygwin make in the past and use the make included with WinAVR instead. I renamed Cygwin make to get it out of the way with:
mv /bin/make /bin/cygmake
Download and install the WinAVR tool chain from here. This package contains the avr-gcc compiler, avrdude programmer, avr-gdb (debugger), programmers notepad, bin-utils, and avr-lib. Look inside the WinAVR-<release data> folder and read the WinAVR-user-manual.html. Inside the avr/include folder are all of the system include files for specific microcontrollers, standard C libraries, etc.
AVR C programs will include <avr/io.h> for all of the register definitions, bit fields, interrupt vectors, memory sizes, etc. The register names and bitfield names are the same as Atmel's datasheet. <avr/io.h> reads the MCU type from the Makefile to figure what device specific files are included. For the Atmega88, these are iom88.h and iomx8.h.
To program the AVR from the SPOT, we need to instruct make on what to do. Download the file SPOT.make and put it into your project directory. Add the line
-include SPOT.make
towards the end of your makefile. This adds two new rules:
make deploy - program the AVR with the generated .hex file
make restore - restore eDemo firmware to last upgrade
make deploy copies the current demosensorboardfirmware.jar file to your project directory and creates a small build.xml for it. If you change SPOT SDK, delete the .jar file in your project. It will make a copy of your project binary and name it edemo.hex moving that into the jar file. This will not work unless you have SPOTHOME set. Mine is set through the .bashrc script and Cygwin. Once the file is installed, make runs ant jar-deploy to install and run the java program which in turn programs the AVR.
An example
The following is a small program which can be put in the eDemo AVR that randomly flashes the eight tricolor LEDs. It has two functions: init() for port initialization and setLED() for bit shifting the color information into the LED shift registers. The main function gets a random number and sets the red, green and blue variables accordingly. We call a millisecond delay defined in util/delay.h, turn the LEDs off, delay some more and rerun.
Start by creating a project folder 'eblinky' and create a makefile using WinAVR's mfile program. mfile is an menu item in the WinAVR start menu. When it starts, click the Makefile tab and select:
Main file name: eblinky
MCU type: atmega88
Output format: ihex
Edit the make file and before the line: "# Target: clean project." add:
-include -SPOT.make
Save the file as Makefile in your project folder. Download SPOT.make and save in your project folder.
This Makefile will respond to the follow rules:
make all - compile all source and generate hex binary
make clean - delete intermediate files from the project
make program - program an AVR with a programming module (like AVRISP)
make deploy - program the intel hex binary into the SPOT eDEMO AVR.
make restore - restore the SPOT eDEMO firmware
Now copy between the dotted lines and paste into a text file or download from here. Save the file in our project folder as eblinky.c.
//-------------------
#include <avr/io.h>
#include <stdint.h>
#include <stdlib.h>
#include <util/delay.h>
// taken from edemo.h
#define LED_SCLK PD4
#define LED_SI PD5
#define LED_EN PD6
#define ACCEL_PD PD7
#define ACCEL_ST PB6
#define ACCEL_FS PB7
#define CALM 900
#define BUSY 200
#define BERZERK 90
#define RED_BULL 20
#define LED_SPEED RED_BULL
void init(void) {
// set the frequency to 8MHz
CLKPR = _BV(CLKPCE);
CLKPR = 0;
// Power down unused atmega modules
PRR = _BV(PRUSART0) | _BV(PRTWI) | _BV(PRADC) | _BV(PRTIM0) | _BV(PRTIM2);
// set the accelerometer control, rest are inputs
PORTB = _BV(ACCEL_ST);
DDRB = _BV(ACCEL_ST)|_BV(ACCEL_FS);
// LED_EN is active low, starts high
// ACCEL_PD starts low reseting the LED shift register
PORTD = _BV(LED_EN);
// LED serial chain are outputs
DDRD = _BV(LED_SCLK)|_BV(LED_SI)|_BV(LED_EN)|_BV(ACCEL_PD);
// PC0-3 are output, rest inputs default
PORTC = 0;
DDRC = 0xF;
// Accel Self test is off
PORTB &= ~_BV(ACCEL_ST);
// Power up and remove reset from LED shift register
PORTD |= _BV(ACCEL_PD);
}
// simple LED program
// parameter red, green and blue are bit fields which turn on the respective color LED
// red bit 0 turns on red led1 (left LED), blue bit 7 turns on blue led8 (right LED)
void setLED(unsigned char red, unsigned char green, unsigned char blue) {
unsigned char i;
unsigned char led;
enum {BLUE, GREEN, RED} color;
PORTD &= ~_BV(LED_EN); // drop enable low
for(color = BLUE; color <= RED; color++) {
if (color == BLUE) led = blue;
else if (color == GREEN) led = green;
else led = red;
for(i = 0; i < 8; i++) {
// if our led bit is set, output '0' to turn on the LED
if((led & 0x80) == 0) {
PORTD &= ~_BV(LED_SI);
} else {
PORTD |= _BV(LED_SI);
}
PORTD |= _BV(LED_SCLK);
PORTD &= ~_BV(LED_SCLK);
led <<= 1;
}
}
// enable high, load shift register to output register
PORTD |= _BV(LED_EN);
}
int main(void) {
int n;
unsigned char r, g, b;
init();
while (1) {
n = rand();
r = g = b = 0;
if (n & 0x100) r = (unsigned char) n;
if (n & 0x200) g = (unsigned char) n;
if (n & 0x400) b = (unsigned char) n;
setLED(r, g, b); // turn LEDs on to some random pattern and color
_delay_ms(LED_SPEED);
setLED(0, 0, 0); // turn LEDs off
_delay_ms(LED_SPEED);
}
}
//-------------------
Once these files are in your project, open up a cygwin window and change directory to your project folder. (cd)
You should be able to type:
make all
You should see something like this:
$ make all
-------- begin --------
avr-gcc (WinAVR 20090313) 4.3.2
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Compiling C: eblinky.c
avr-gcc -c -mmcu=atmega88 -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char -f
unsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ad
hlns=./eblinky.lst -std=gnu99 -MMD -MP -MF .dep/eblinky.o.d eblinky.c -o eblink
y.o
Linking: eblinky.elf
avr-gcc -mmcu=atmega88 -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char -funs
igned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhln
s=eblinky.o -std=gnu99 -MMD -MP -MF .dep/eblinky.elf.d eblinky.o --output eblin
ky.elf -Wl,-Map=eblinky.map,--cref -lm
Creating load file for Flash: eblinky.hex
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock eblinky.elf eblinky.hex
Creating load file for EEPROM: eblinky.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O ihex eblinky.elf
eblinky.eep || exit 0
Creating Extended Listing: eblinky.lss
avr-objdump -h -S -z eblinky.elf > eblinky.lss
Creating Symbol Table: eblinky.sym
avr-nm -n eblinky.elf > eblinky.sym
Size after:
AVR Memory Usage
----------------
Device: atmega88
Program: 756 bytes (9.2% Full)
(.text + .data + .bootloader)
Data: 4 bytes (0.4% Full)
(.data + .bss + .noinit)
-------- end --------
After doing the make all, plug in a Spot and try make deploy. It may ask to reset the Spot when doing the ant deploy portion.
You can restore the SPOT back to the original eDemo firmware with make restore.
A number of files will be generated by make. Open the eblinky.lss file and you will see C source interspersed with the generated
assembly code from the compiler. Here is a fragment:
PORTD |= _BV(LED_SCLK);
a6: 5c 9a sbi 0x0b, 4 ; 11
PORTD &= ~_BV(LED_SCLK);
a8: 5c 98 cbi 0x0b, 4 ; 11
On the Atmega88, there are four GPIO peripherals A, B, C and D. Each GPIO peripheral has a set of three 8-bit registers: output (PORTn), input (PINn) and data direction register (DDRn). Each bit corresponds to a pin on the package of the microcontroller and a bit in each register. The data direction register (DDRn) defines whether the corresponding bit is an output ('1') or an input ('0'). If the Data direction register has a bit set as an output and the output register has that bit written as a '1', the output pin will be high. If the output bit is written as a '0', the pin will go low. The input register reads the state of it's corresponding pins. Likewise, if the pin is low, the bit in the input register will read '0', else if the pin is high, it will read '1'. Now if the output register is read, it will read back the state that was last written not the state of the pins. So PORTD is defined as the memory mapped output register for port D in the avr/io.h chain.
_BV() or bit vector, is a macro defined in sfr_defs.h (part of io.h chain) as _BV(x) = 1 << (x). Register bit fields in the io.h include are defined by bit position not actual bit mask. PD4 is defined as 4 and _BV(PD4) = 1 << (4) = 0b00010000 or 0x10. PORTD |= _BV(LED_SCLK) would be the same as PORTD = PORTD | _BV(LED_SCLK). To clear a bit, we use bit and operation ('&=') and invert the bit mask ( '~'). The compiler is smart enough to recognize these are bit set and clear operations on an IO register and generates the appropriate instructions. The compiler will evaluate expressions with constants early and not generate additional code as is the case with 1 << (LED_SCLK).
Sometimes if the compiler does not see a variable change inside of a loop, it may optimize the variable away. The variable may be changing from an interupt routine or it is an memory mapped IO device. In these circumstances you need to force the compiler to keep the reference by declaring the variable 'volatile'.
Constant strings, arrays etc. do not necessarily reside in flash such as const char str[] = "Hello World\n"; avr-gcc will copy the arrays from flash into SRAM on initialization and eat our precious RAM quickly. The alternative is to use the avr/pgmspace.h and define the strings as const prog_char str[] = "Hello World\n"; . There are functions equivalent to those used in string.h for accessing the strings in pgmspace.h. I'd suggest reading the faq for the tools for other subtle differences between C on a desktop and AVR C.
A few SPOT specific caveats. The AVR can wedge the ARM causing general havoc for the SPOT. Unless you are using SPI and it is in Slave mode, do not enable Port B bit 4 - MISO (PB4) as an output. This will disrupt any SPI communication and the SPOT will not function well. If you are not generating an interrupt to the, do not enable Port D bit 3 - IRQ0 (PD3) as an output. If you do enable it, the output is normally low and a high will cause an interrupt.
If you want to modify the existing eDemo firmware, the source code is on java.net in a subversion repository. I use tortoiseSVN client for subversion on Windows and has a good UI. You need an account on Java.net to get the sources and signing up is free.
The source to the demosensorboardfirmware.jar can be found here.
The AVR fuses are also programmed from the java. The fuses set the clock source, start location on reset, brownout detect levels, etc. The fuses are different than prior releases and is coded to reset to 0x0000 (no bootloader).
Known bugs: If running more than one SPOT, it will ask for which SPOT to use. It may come back and look like it's hanging but it's waiting for input. I had to enter the SPOT number four times before it responded. I filed a bug report.
There was a problem of the system checking integrity of eDemo before deploying SPIFirmwareUpdater. I've corrected this in 7/21/2009 SPOT.make
We have a PS3. I got it 'cause it's a great blu-ray player. My son uses it for playing those games. Nevertheless, it will not only play little round discs but movies on a USB stick, or from a "Media Server". The "Media Server" caught my eye - it looked like something that my Solaris NAS box could do.
First shot was to try to set up the server from Windows. It was simple enough, download windows media player and start the services. Of course, it only wanted to play wmv files. That was ok, I just wanted to see what a "media server" was and what it could do. I went a few rounds, learned way more than I wanted about codecs and turned the problem over to my son.
He found Mediatomb on the web and installed it on his Ubuntu box. It worked great even with the mp4s, so we started off on a weekend project to put it on Solaris.
Fortunately, Constantin Schmitz already did this and wrote an excellent blog about how to do it. This makes my blog a whole lot shorter. If you don't want Mediatomb, you can try Twonkymedia, he wrote a blog on setting up that. Follow his blog on Mediatomb on how to install it and I'll make comments from my experiences.
Mediatomb is very configurable. The media organization can be set up through a configuration xml script, javascript and the built in web service. The webpage gives you a view of what the PS3 sees and a file tree to add directories and media files. The organization from the files on the server and what is seen by the PS3 is managed through javascript.
Tweaks in the installation
Blastwave instructions don't use pkg-get -i anymore. The instructions now use pkgutil --install. pkg-get is still around but the default wasn't pointing to anything useful and pkgutil worked fine.
You have to grab a copy of libmagic and will have to poke around ftp.astron.com with ftp to find the latest release. I ended up with 5.0 and that will likely change again. I couldn't get it to compile correctly with cc, I changed to gcc and it worked fine. Compile taglib as per instructions and then grab a copy of Mediatomb. I used gcc for that too.
I used SMF for starting up and shutting down mediatomb. I'll describe the setup at the end. You do need a start up script. I put the configuration for it in /etc/mediatomb.
mkdir /etc/mediatomb
Cut the following and put into a file /etc/mediatomb/mediatomb.conf
Customize for your own preferences.
--------------------
# install in /etc/mediatomb
MT_INTERFACE="e1000g0"
## MediaTomb port must be private >= 49152
MT_PORT="49194"
# Username and group
MT_USER="bob"
MT_GROUP="family"
# PID file path
MT_PIDFILE="/var/run/mediatomb/mediatomb.pid"
# Log file path
MT_LOGFILE="/var/log/mediatomb/mediatomb.log"
# Config file path
MT_HOME="/export/home/bob"
-------------------
You want to create a mediatomb directory in /var/run and in /var/log
cd /var/run (and /var/log)
mkdir mediatomb
chown user:group mediatomb
chmod 755 mediatomb
Create a startup script in /lib/svc/method/ called svc-mediatomb
-------------------------
#!/sbin/sh
. /etc/mediatomb/mediatomb.conf
LD_LIBRARY_PATH=/opt/csw/lib:/opt/local/lib:/usr/lib/firefox /opt/local/bin/mediatomb \
--interface $MT_INTERFACE \
--port $MT_PORT --daemon \
--pidfile $MT_PIDFILE \
--logfile $MT_LOGFILE \
--home $MT_HOME
A few notes. LD_LIBRARY_PATH is not the best way to go. I don't like LD_PRELOAD either and it was not clear to me from the error message of how to get that to work. The LD_LIBRARY_PATH does work and I'm using it for now. I hope a cleaner method eventually comes to past. I do believe the use of ZFS/Solaris and a mediaserver is a big win.
First time Mediatomb is run, it creates a directory in $HOME/.mediatomb. Inside .mediatomb are the database files and default configuration file config.xml. This is the basic configuration file and it is read when the service is restarted.
You will need to edit the config.xml file:
Set a login for those that want to set up Mediatomb.
<accounts enabled="yes" session-timeout="30">
<account user="bob" password="a password"/>
</accounts>
The name tag is what shows up on the PC and on the PS3 as the media server name. Good idea to make it something identifiable.
<name>Bob's Solaris Media Server</name>
I set it up to view the media files with javascript and didn't need the directory view for the PS3.
<pc-directory upnp-hide="yes"/>
We are going to change the javascript files from the default. This requires the following lines changed:
<common-script>/opt/local/share/mediatomb/js/common.js</common-script>
<playlist-script>/opt/local/share/mediatomb/js/playlists.js</playlist-script>
<virtual-layout type="js">
<import-script>/opt/local/share/mediatomb/js/import.js</import-script>
</virtual-layout>
The virtual-layout tag must be changed from builtin to js for it to read the javascript that you modified.
Add Constantin's changes to the config.xml file for <filesystem-charset>, <magic-file>, <protocolInfo extend="yes"/> and map to tags as he suggested.
Adding some categories for Video
Mediatomb uses javascript to map the media files over to the upnp container structure that the PS3 uses. It's very smart about this for pictures and audio files as the metadata is quite rich. This is not the case for video default is to dump all videos into a 'Video' container.
I didn't like this but didn't want anything very complicated. I needed basic categories and the movie title. I set it up that each user had a 'media' directory that would contain movies, pictures, and audio. Inside of this directory would be subdirectories to categorize the movies. The filename of the video will be used as the title of the move but with the file extension removed.
This is done by changing the javascript file, import.js.
In import.js, replace the text:
// currently no video metadata supported
function addVideo(obj)
{
var chain = new Array('Video');
addCdsObject(obj, createContainerChain(chain));
}
with
function addVideo(obj)
{
var loc = obj.location.split('/');
var mediaFound = false;
var chain = new Array("Video");
for(i=0; i<loc.length-1;i++) {
if(mediaFound) chain.push(loc[i]);
if(loc[i].toLowerCase() == "media") mediaFound = true;
}
str = loc[loc.length-1];
obj.title = str.substring(0,str.lastIndexOf('.'));
addCdsObject(obj, createContainerChain(chain));
}
Save these files and restart the server.
Setting up the media
You will need to create a media directory in your user space. Within this directory create subdirectories for categories like movies, tv shows, etc. and possibly further subdirectories for series, episodes. Do not get carried away with the hierarchy as there is a limit of subdirectories on the PS3. The audio and pictures can go into the media directory without subdirectories.
If you have upnp on in Windows, it should show up as a networked monitor with rabbit ears in Network Places. Clicking on this should open up your webbrowser to Mediatomb file/database configuration page. If you enabled login, it will then have a login screen for user/password. It will then show two tabs, filesystem and database.
Click on filesystem tab and browse the file tree until you find your media directory. Click on the + icon with the little round arrows (Tooltips would be nice here). This will bring up a form to set up autoscan of this directory. Set the scan level and make sure recursive folders is checked to pick up the subdirectories.
Any files added to the media directory will be automatically added to the upnp container from then on.
Clicking on the Database tab will show the organization of how it will look on the PS3. The only difference is while the PC Directory always shows in the browser, it can be selectively hidden for the PS3.
Setting up a service
This is my first shot at setting up a service. Copy the following xml between the dotted lines and
write as /var/svc/manifest/application/mediatomb.xml
-------------------
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type="manifest" name="mediatomb">
<service name="application/mediatomb" type="service" version="1">
<create_default_instance enabled="false"/>
<single_instance/>
<dependency
name="network"
grouping="require_all"
restart_on="error"
type="service">
<service_fmri value="svc:/milestone/network:default"/>
</dependency>
<dependency
name="filesystem"
grouping="require_all"
restart_on="error"
type="service">
<service_fmri value="svc:/system/filesystem/local"/>
</dependency>
<exec_method
type="method"
name="start"
exec="/lib/svc/method/svc-mediatomb"
timeout_seconds="60">
<method_context>
<method_credential user="bob" group="family"/>
</method_context>
</exec_method>
<exec_method
type="method"
name="stop"
exec=":kill"
timeout_seconds="60">
</exec_method>
<property_group name="startd" type="framework">
<propval name="ignore_error" type="astring" value="core,signal"/>
</property_group>
<stability value="Evolving"/>
<template>
<common_name>
<loctext xml:lang="C">
UPnP Media Server
</loctext>
</common_name>
<documentation>
<manpage
title='mediatomb'
section='1'
manpath='/opt/local/share/man' />
<doc_link name='mediatomb.cc'
uri='http://mediatomb.cc' />
</documentation>
</template>
</service>
</service_bundle>
-------------------
The /etc/mediatomb/, /var/run/mediatomb,/var/log/mediatomb, mediatomb.conf and config.xml home tag all should have a username/groupname and appropriate protection fields set. Once everything is set, check the manifest to make sure it's ok with:
svccfg validate /var/svc/manifest/application/mediatomb.xml
if ok, then import
svccfg import /var/svc/manifest/application/mediatomb.xml
and check status
svcs mediatomb
It should be disabled.
Start mediatomb with
svcadm enable mediatomb
stop it with
svcadm disable mediatomb
if it isn't running check status with
svcs -xv
Problems show up as "maintenance" mode
You can check both the smf log files in the svcs error message and the log file from mediatomb to find what is going wrong.
Once the problem is fixed, clear smf with
svcadm clear mediatomb
svcadm disable mediatomb
and try again, svcadm enable mediatomb
Elliptic Curve Cryptography (ECC) is a next-generation public-key cryptographic technology that is more resource efficient than RSA (learn why) and was recently endorsed by the NSA for protecting sensitive US Government Information (see The Case for ECC and Suite B).
Sun Labs has played a major role in promoting wide-spread industry adoption of this technology by:
ECC has been part of Firefox since October 2006 when version 2.0 was released but isn't yet included in the default build of the Apache web server (see Bug 40132). I recently updated the patch and corresponding instructions to create an ECC-enabled version of Apache 2.2.11 with OpenSSL 1.0.0-beta2. If you happen to try out the patch, I'd love to get your feedback.
In case you are wondering "why should I care?", think of this as another step in reducing the computational cost of security so service providers like Amazon, Facebook, Google and Yahoo can turn on HTTPS by default for all user interactions (not just the login phase), thereby boosting privacy on the Internet.
In the battery blog I did, I mentioned using a java program to measure internal resistance of the battery. I updated the program and will post the snippets here.
The internal resistance of a battery increases with cold, age and power cycles. This limits its ability to provide high currents and eventually make the cell unusable. Most of the increase over age is from oxidation of the electrodes. The higher the internal resistance, the higher are both the charging and discharging losses of the cell.
There are two methods of measuring internal resistance. The first method places a small AC signal, about 1KHz, across the cell and measures the in-phase AC current. This yields Z = E/I, where E is the AC voltage amplitude and I is the measured AC current. The second method is a DC load test. Measure the battery voltage and discharge current under both light and heavy loads. The internal resistance is then R = DE/ DI. The AC measurement is usually an order of magnitude less than the DC load method and can provide more information of the condition of the battery.
The program I wrote uses the DC load test and requires two SPOTs. One is the SPOT-under-test (SPOUT?) and a basestation that prints the results to a terminal emulator (or ant echo). It uses the 802.15.4 radio to communicate its results. Each SPOT is running a different application. IntresSensor.java goes on the SPOUT and intresHost.java goes on the basestation. I used the latest RED release; however, this should work for BLUE. SPOUT requires an eDemo board and battery.
The SPOUT goes to sleep for sixty seconds, wakes up and takes a low current reading. SPOUT cranks up the current by turning on the radio and set LEDs to full maximum for another sixty seconds. It takes a second reading and transmits the result to the basestation.
The basestation prints the current and voltage measured, calculates the internal resistance and prints it. The code is provided as a snippet, without imports, pauseApp() nor destroyApp() methods. Using a basic SPOT template will provide a skeleton and Netbeans or Eclipse have a means of finding the imports.
Most of the work I’ve done on the radio has been low-level stuff – real low-level, for testing and compliance. This was my chance to use some of the basic Radio libraries like RadioDatagram. I wanted to keep this simple, and didn’t need Lowpan or mesh stuff. I did a dirt simple discovery method. I didn’t put any retries, back off strategies, etc. and this may break with a lot of SPOTs around.
The basestation broadcast a message containing an arbitrary string, appName. When the SPOUT receives the broadcast, it sends all subsequent messages to that basestation address. The basestation stops broadcast once it starts receiving packets addressed to itself. More than one SPOT can send to the basestation and the address will be printed with the sensor data. If this is used in a classroom, each student could assign appName to a unique “username” to pair the SPOTs.
SPOUT Code
public class intresSensor extends MIDlet {
private static final byte PORT = (byte) 93;
private IBattery battery;
private ITriColorLED[] leds;
private static final String appName = "intres";
private String dstAddress = null;
private void sendSensor() {
int sleep_discharge;
int sleep_vbatt;
int run_discharge;
int run_vbatt;
IPowerController pctrl = null;
RadiogramConnection rc = null;
Datagram dg = null;
try {
// open a direct connection between this SPOT and the basestation
// dstAddress is the basestation discovered by lookForHost
rc = (RadiogramConnection) Connector.open("radiogram://" + dstAddress + ":"+PORT);
dg = rc.newDatagram(rc.getMaximumLength());
rc.setRadioPolicy(RadioPolicy.AUTOMATIC);
} catch (IOException e) {
System.out.println("Could not Send");
return;
}
pctrl = Spot.getInstance().getPowerController();
leds = EDemoBoard.getInstance().getLEDs();
battery = Spot.getInstance().getPowerController().getBattery();
for(int i = 0; i < 8; i++) {
leds[i].setColor(LEDColor.WHITE);
leds[i].setOff();
}
while(true) {
// can do this test only when discharging
if (battery.getState() == IBattery.DISCHARGING) {
// turn everything off
Spot.getInstance().getGreenLed().setOff();
Spot.getInstance().getRadioPolicyManager().setRxOn(false);
for(int i = 0; i < 8; i++) {
leds[i].setOff();
}
// this should go into deep sleep but it doesn't
// there is a bug prob with radio stuff keeping it awake
Utils.sleep(60000); // 60 sec
sleep_discharge= pctrl.getIdischarge();
sleep_vbatt = pctrl.getVbatt();
// turn everything on
Spot.getInstance().getGreenLed().setOn();
Spot.getInstance().getRadioPolicyManager().setRxOn(true);
for(int i = 0; i < 8; i++) leds[i].setOn();
for(int i = 0; i < 600; i++) Utils.sleep(100); // 60 secs
run_discharge = pctrl.getIdischarge();
run_vbatt = pctrl.getVbatt();
try {
// transmit our data
dg.reset();
dg.writeInt(sleep_discharge);
dg.writeInt(run_discharge);
dg.writeInt(sleep_vbatt);
dg.writeInt(run_vbatt);
dg.writeInt(battery.getBatteryLevel());
rc.send(dg);
} catch (IOException e) {
System.out.println("Could not Send");
}
}
}
}
private boolean lookForHost() {
RadiogramConnection rc = null;
Datagram dg = null;
long adr;
String name;
dstAddress = null;
// open a connection to listen for broadcast
// PORT needs to match between sender and receiver
try {
rc = (RadiogramConnection) Connector.open("radiogram://:" + PORT);
dg = rc.newDatagram(rc.getMaximumLength());
} catch (IOException e) {
System.out.println("Could not open receiver");
return false;
}
while(true){
try {
dg.reset();
rc.receive(dg);
name = dg.readUTF(); // UTF is a java String
// message sent by broadcast is an arbitrary string
// appName could be changed to a students name to pair
// SPOTs in a classroom
if (name.equals(appName)) {
dstAddress = dg.getAddress();
System.out.println("Host found: " + dstAddress);
return true;
}
} catch (IOException e) {
System.out.println("Nothing received");
return false;
}
}
}
protected void startApp() throws MIDletStateChangeException {
// Listen for downloads/commands over USB connection
new com.sun.spot.util.BootloaderListener().start();
// Make sure this SPOT has an eDemo board
if (Spot.getInstance().getExternalBoardMap().isEmpty()) {
System.out.println("Requires eDemo board");
} else {
// do discovery and if successful, the main loop
if (lookForHost()) sendSensor();
}
}
Host Code
public class intresHost extends MIDlet {
private static final byte PORT = (byte) 93;
private static final String appName = "intres";
private IBattery battery;
private boolean discovery;
private ILed greenLite = Spot.getInstance().getGreenLed();
// broadcast thread
synchronized private void sendBroadcast() {
new Thread() {
public void run() {
discovery = true;
RadiogramConnection rc = null;
Datagram dg = null;
try {
// open a broadcast connection
rc = (RadiogramConnection) Connector.open("radiogram://broadcast:"+PORT);
dg = rc.newDatagram(rc.getMaximumLength());
} catch (IOException e) {
System.out.println("Could not broadcast");
return;
}
discovery = true;
while(discovery){
try {
// Send appName (UTF encoded)
dg.reset();
dg.writeUTF(appName);
rc.send(dg);
// flash the LED slowly indicate broadcast
// stops flashing when SPOTs are sending data back
greenLite.setOn(!greenLite.isOn());
} catch (IOException e) {
System.out.println("Could not broadcast");
}
Utils.sleep(500);
}
greenLite.setOff();
} // run
}.start();
}
// receiver thread
private void receiveSensor() {
new Thread() {
public void run() {
double dv;
double di;
int ir;
int sleep_discharge = 0;
int sleep_vbatt = 0;
int run_discharge = 0;
int run_vbatt = 0;
int batt_level = 0;
RadiogramConnection rc = null;
Datagram dg = null;
try {
// open port to receive
rc = (RadiogramConnection)
Connector.open("radiogram://:" + PORT);
dg = rc.newDatagram(rc.getMaximumLength());
} catch (IOException e) {
System.out.println("Could not open receiver");
e.printStackTrace();
return;
}
while(true) {
try {
// receive the data packet
dg.reset();
rc.receive(dg);
sleep_discharge = dg.readInt();
run_discharge = dg.readInt();
sleep_vbatt = dg.readInt();
run_vbatt = dg.readInt();
batt_level = dg.readInt();
discovery = false;
} catch (IOException e) {
System.out.println("Nothing received");
}
// multiple SPOTs can send to this basestation
// print the sensor SPOT address to identify
System.out.println("Device: " + dg.getAddress());
System.out.println("Battery Level: " + batt_level + "%");
System.out.println("Low: " + sleep_discharge + "mA " + sleep_vbatt + "mV");
System.out.println("High: " + run_discharge + "mA " + run_vbatt + "mV");
// find the delta volts/delta current for internal resistance
dv = ((double) sleep_vbatt - run_vbatt);
di = ((double) run_discharge - sleep_discharge);
if (di > 0 && dv > 0) {
// internal resistance is dv/di
// remove the sense resistance (0.1ohm) contribution
// convert to milliohms and round (why? double to string isn't formatted)
ir = (int) (((dv/di - 0.1)*1000.0) + 0.5);
System.out.println("Battery Resistance: " + ir + " milliohms");
}
} // while
} // run()
}.start();
}
protected void startApp() throws MIDletStateChangeException {
// listen for USB
new com.sun.spot.util.BootloaderListener().start();
// start broadcast thread
sendBroadcast();
// start receive thread
receiveSensor();
}
I've finally caught my breath after JavaOne - we had a busy week. We were able to bring FIRST to a lot of technical people that had never heard of FIRST, and let people know that Java was coming.
JavaOne PavilionWe had local FRC teams demonstrating robots in the pavilion, along with representatives from FIRST. This was very popular at the show - anytime the robots were running we had an audience.
Some related media: |
|
|
|
Technical Session and BOFEric Arseneau and Brad Miller presented TS-4945 "FRC-FIRST Robotic Competition" (slides to be posted). And Derek White and Brad Miller lead the Birds-Of-a-Feather session BOF-4953 "FRC-FIRST Robotic Competition" - but the teams were the stars of the BOF. |
|
James Gosling's Toy Show Keynote
Brad Miller and James Gosling talked about FIRST and Java in front of a live audience of thousands and webcast to many more. I helped with a demo along with Scott and Austin. This was the most nerve-wracking demo I've given, and it wasn't even due to the huge crowd. Imagine running a demo using WiFi in a room with 20-30 industrial-sized access points in the same band. Then add in thousands of laptops. In rehearsal we spent between 2-30 minutes each time to get a link between the robot and the driver station! We started the morning by linking the robot to the router, and left everything on (battery powered) for an hour and a half. When we were called on stage for the live demo, we had to do a quick check for power and connectivity. We had backup plans for the backup plans, but luckily didn't need to use them. |
|
Correction: The C++ experience on the new cRIO-based robots isn't as neolithic as James makes out - the IDE includes modern debugging support. But it's not Java.
As mentioned previously, WPI won the Duke's Choice Award for it part in porting Java to the new robot system, enabling teams to use Java in next years competition.
Correction: Please refer only to this version of the press release. Other versions make some inaccurate claims.
This wouldn't have happened without the work of a lot of people. I'd like to thank the FRC teams for coming to JavaOne right in the middle of final exams, and sharing their robots for the demos. I'd especially like to thank DJ and Scott of team 971 for coming every single day of JavaOne! And I'd like to thank James Gosling for his support and forbearance. You'll note that Brad Miller was involved in just about everything. Jim Beck from FIRST helped get the teams lined up, Eric arranged the whole FIRST @ JavaOne experience, and a pile of Sun people helped everything run smoothly (well, as smoothly as it did).
Worcester Polytechnic Institute (WPI) won the 2009 Duke's Choice Award in the Category: Java Technology in Education for it's work bringing Java to the FIRST Robotics Competition.
|
This was worked started by WPI students Brian O'Keefe, Marouane Afiri, and Albedith Diaz for their "Major Qualifying Project". They ported the open source Squawk JVM to the compactRIO robot control system, and ported WPILib, the C++ robotics library used in the FIRST Robotics competition, to Java. They did a great job in in a very short time - they did the first port of Squawk to VxWorks (it was actually only the second port of Squawk to run "natively" on an OS), and were part of the initial proposal to the FIRST organization. I was very happy to be the team's "industry" advisor - this became my introduction into the world of FIRST robotics! This work has been continued by the WPI Robotics Resource Center,
assisted by the Squawk and Sun SPOT teams at Sun Microsystems
Laboratories and other volunteers. |
![]() |
It's great to see WPI get recognized for the efforts to bring Java to the thousands of students developing robots for the FRC. Be on the lookout for robots in James Gosling's Toy Show keynote, and for the award presentation to Brad Miller of WPI!
CommunityOne
Monday, June 1 - S311736: "Lightning Talks, Part 4/FRC-FIRST Robotic Competition" 2:40 PM - 3:30 PM Esplanade 303
CommunityOne Registration
CommunityOne events are free to all. Register at http://www.cplan.com/communityone2009/w ... gistration
JavaOne
Pavilion - Java Playground
Will
have representatives from FIRST, WPI, and several FRC teams. Robots
will be demoed in the robot arena. Learn about FIRST, the FIRST
Robotics Competition, and Java for FRC. Find out how to get involved!
Monday (June 1) 3:00 pm - 7:00 pm,
Tuesday 11:30 am - 7:30 pm
Wednesday 10:00 am - 4:30 pm
Thursday 10:00 am - 2:00 pm
Thursday, June 4 - TS-4945: FRC-FIRST Robotic Competition 2:50 PM - 3:50 PM Esplanade 305
1.The Java™ platform is an interesting vehicle for teaching kids about programming.
2. FIRST is an organization whose mission is to inspire young people to be science and technology leaders by engaging them in exciting mentor-based programs that build science, engineering, and technology skills; inspire innovation; and foster well-rounded life abilities such as self-confidence, communication, and leadership.
3. Robots are cool; robotic competitions are even cooler.
What happens when you mix these three things? You come up with a winning combination that lets kids and "adults" have a lot of fun.
What do robots and FIRST have to do with Java™ technology? Come to this session and see firsthand what Java technology is enabling kids to do today with some cool hardware. Get to play with big competition robots and their teams.
I attended the 2009 FIRST Championship April 16-18 at the Georgia Dome in Atlanta, GA as part of the Java for FRC announcement. We demoed Java running on several robots, over-the-air debugging, and multi-platform development (Windows, Linux, Mac (and we kept getting asked about Solaris)). We gave a couple of talks with James Gosling about Java for FRC.
This was my first time at a FIRST Championship and it was pretty overwhelming.
But what was really impressive were the teams. It was really clear that FIRST was succeeding at its mission of inspiring students in science and technology. Students didn't just learn that science was cool - they knew that they were cool. These are kids that are not worried about being called geeks, or anything else for that matter:
As always, check out FIRST Robotics @ Sun for information on getting involved with FIRST.
|
Last Friday we had three teams, five robots, WPI and FIRST come to visit Sun's Burlington, MA campus. The teams talked about their robots and experiences with FIRST, and mentors explained what mentoring for FIRST was all about.
Two of the robots were Java-powered - team 1519's little "Speed Racer" (look for the Duke on top), and WPI's demo robot ("demo" may stand for demonstration or demolition). Steve Heller arranged a demonstration of torque:
Check out FIRST Robotics @ Sun for future FIRST show-and-tells on campus, and more information about FIRST.
Next stop - JavaOne! |
![]() |
|
|
|