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:




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.


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 it gets the lightSensor:

IScalarInput lightSensor = EDemoBoard.getInstance().getLightSensor();

Instead we'd like to get the analog input:
IScalarInput lightSensor = EDemoBoard.getInstance().getScalarInputs()[EDemoBoard.A0];

Please note that this is VERY temporary. I should really rename the variable lightSensor to be a bit more descriptive of its new function, but this is just a test. With just that one line change, we can run that code on the Sun SPOT device and connect a base station and run SendData-GUIonDesktop. We get the following output:

You can see that at first the readings were very low. Then I put the sensor in a glass of water and the reading shot up. After about a minute, I removed the sensor from the water and it dropped back down to the approximately the previous value. It looks like it is working!
From here, you can get as fancy as you want, but first lets review what we have accomplished so far. We've gone from identifying a sensor on the web to connecting it by just connecting 3 wires and then changing one line of code in a demo program.. and now we're looking at graphs of data we collected wirelessly. Not too bad!
Of course, for a more permanent installation, there are other things to think about.
One other consideration of some importance is the item in the specification sheet labelled "Power on to Output stable." This is the amount of time between giving the probe power and the time it has valid output. This time is rated at 400mS. Just to be sure I have the enough time, I wake the Sun SPOT up half a second before I take readings from the probes. The Sun SPOT has a nice feature that it shuts the power off during deep sleep, but keeps it on during shallow sleep. This means that I can wake up, disable deep sleep, then go back to shallow sleep while the probe stabilizes.
sleepManager.disableDeepSleep (); // Assure that we will be awake to power the moisture sensor
Utils.sleep (STABILZATION_PERIOD); // give the sensor time to stabilize

then later after taking the readings go into deep sleep

// Go to sleep to conserve battery
sleepManager.enableDeepSleep ();
try {
sleepManager.ensureDeepSleep((SAMPLE_PERIOD - STABILZATION_PERIOD) - (System.currentTimeMillis() - now));
} catch( UnableToDeepSleepException ex ){
ex.printStackTrace(); Utils.sleep((SAMPLE_PERIOD - STABILZATION_PERIOD) - (System.currentTimeMillis() - now));
[FONT='times new roman', -webkit-fantasy]
There are a few things to do to make sure that deep sleep works properly:
  • First, make sure that no other applications are running when your application is running. Having multiple threads and isolates is an amazing feature of Sun SPOTs, but if you want to save power you need to keep them under control.
  • Second make sure that OTA is turned off.
  • Third set the routing policy to ENDNODE so that you don't spend energy routing other node's packets
RoutingPolicy rp = new RoutingPolicy(RoutingPolicy.ENDNODE);
RoutingPolicyManager.getInstance().policyHasChange d(rp);
Based on what I've measured so far, when I set the Sun SPOT to report all the values every 5 minutes I get a duty cycle with over 99% deep sleep. Of the 1% that is left, most of that time is in deep sleep. The moisture probes don't use very much power, so I anticipate several months of operation between battery charges.

The sensor seems to suit my purposes well. It certainly easy to use. I got a second probe so that I can monitor the moisture in two places simultaneously. This was fairly straight forward. I just had to repeat the process I did for the first probe on a second analog input (A1). While I was at it, I modified the application to send light, temperature and battery levels as well as the moisture reading. I've modified the host side of the application to plot all of these values plus write them out as a CSV file to the disk drive.
I put a cable tie around the Sun SPOT device to hold the wires in place. Next I screwed an eSPOT mounting clip to a piece of PVC pipe and clipped the eSPOT in place. I put this on the end of a 6 foot tall piece of pipe stuck in the ground. Next I cut the top off an old Costco ibuprofen container and inverted it over the eSPOT. It is waterproof and translucent enough to be able to get diffused light readings right through the container. In fact, in direct sunlight it is still enough to saturate the light sensor. I buried the moisture sensors a few inches down in the dirt.
Now I have a complete system to monitor light, temperature, and moisture in two locations in the garden. I'm recording data every 5 minutes. Finally I'll be able to collect scientific data about optimal watering schedules. Is it better to have daily short waterings or less frequent deeper waterings? I should be able to find out how long it takes for the soil to return to a baseline condition after watering and from that infer how often I need to water. My goal for now is to keep the soil moisture over multiple days from trending up or down. I want to water enough to keep the over moisture level approximately constant.

Issues and Future Enhancements
The temperature readings are not very accurate. I know that the built-in temperature sensor is really measuring the temperature of the ADC chip, but I've found that if you have applications that sleep a lot and then take the temperature reading immediately after waking from deep sleep, you can get fairly accurate readings (this only works for eSPOTs that are NOT plugged in. In this case I'm actually using the ADC and I'm taking the temperature reading after waiting for half a second to stabilize the probe. I'll have to play around with this to see if I can get more accurate readings.
In the future I hope to be able to send this data to a public server where I can view the data from anywhere and adjust the watering schedule while I'm on the road. I'd also like to be able measure the soil temperature early in the season so that I can tell when its time to plant.
In a future post, I'll make the code available in case anyone else wants to poke around with it a bit more.