SUNSpot Programming

SunSPOTs where a cool IoT hardware from SUN/Oracle that ran JavaME. They are now dead, but this may help some that catch them again.

Hints on SUNSpot programming

Lifecycle

The MIDlet can be started, paused and destroied (see Sun On Mobility)

  • startApp(): will be called on the MIDlet when the app is started or after being paused. Resources should be allocated here;
  • pauseApp(): can be called on the MIDlet after the app has been started. Non-one-time resources should be released here;
  • destroyApp(): will be called on the MIDlet when the app is to be “killed”. May be called in pause or active state.

Deploying apps

(from the developer’s guide:Batch operations) If two SPOTs are connected locally, then for example:

ant port="COM3,COM4" deploy

And if they are accessible remotely via a basestation then

ant remoteId="0014.4F01.0000.0006,0014.4F01.0000.0007"

If the SPOTs are connected locally, or if a shared basestation is in use, the multiple operations will proceed in parallel. For remote SPOTs when the basestation is not shared, the operations happen in sequence.

Network

Local address

//deprecated long myAddr = Spot.getInstance().getRadioPolicyManager().getIEEEAddress();
long myAddr = RadioFactory.getRadioPolicyManager().getIEEEAddress();
String myAddrSt = IEEEAddress.toDottedHex(myAddr); 

Sending data

(from the developer’s guide:The radio communication library)

Data is sent over the air when the output stream buffer is full or when a flush() is issued. [when using the DataOutputStream interface of RadiostreamConnection See using the Datagram objects.

Datagram Size

The max size (for releases after/including orange) is 1260 bytes as per the 6LowPAN, as there is auto-fragmentation by the java code. The 802.15.4 standard seems to state 127 bytes. See:

Acks

(from the developer’s guide:The radio communication library)

Behind the scenes, every data transmission between the two devices involves an acknowledgement. The sending stream will always wait until the MAC-level acknowledgement is received from the next hop. If the next hop is the final destination then this is sufficient to ensure the data has been delivered. However if the next hop is not the final destination then an acknowledgement is requested from the final destination, but, to improve performance, the sending stream does not wait for this acknowledgement; it is returned asynchronously. If the acknowledgement is not received despite retries a NoMeshLayerAckException is thrown on the next stream write that causes a send or when the stream is flushed or closed. A NoMeshLayerAckException indicates that a previous send has failed and the application has no way of knowing how much data was successfully delivered to the destination.

Power control

(from the developer’s guide:The radio communication library)

//deprecated IRadioPolicyManager rpm =Spot.getInstance().getRadioPolicyManager();
IRadioPolicyManager rpm = RadioFactory.getRadioPolicyManager();
int currentPower = rpm.getOutputPower(); 
rpm.setOutputPower(-31); // valid range is -32 to +31 

Notes:

  • If the radio is already turned on, changing the channel or PAN identifier forces the radio to be turned off and back on again. The most significant consequence of this is that remote devices receiving from this radio may detect a “frame out of sequence” error (reported as an IOException). The radio is turned on when the first RadiogramConnection is opened, or when the first input stream is opened on a RadioConnection.
  • While the range of power values specified in the 802.15.4 specification is -32 to +31, the CC2420 radio chip used in the Sun SPOT only has 22 different power levels, the maximum one being 0. That’s why you can set the transmit power to one value and then read back another. Also note that for channel 26 the maximum power is -3, not 0 due to FCC regulations

Radio On/Off

(from the developer’s guide:The radio communication library) Policies

  • ON: the default policy, where the existence of the connection forces the radio receiver to be on.
  • OFF: where the connection does not require the radio receiver to be on.
  • AUTOMATIC: where the connection is prepared to handle incoming radio traffic but is happy to acquiesce if another connection wants the radio off.

However care should be taken when OTA is on:

If your application does not use the radio but has the OTA command server running, then because the OTA command server’s connection has its policy set to AUTOMATIC the radio will be on. So, if you want to turn the radio off to conserve power, or to allow deep sleep to happen, you should create a dummy connection and set its policy to off:

RadiogramConnection conn = (RadiogramConnection)Connector.open("radiogram://:42");  
conn.setRadioPolicy(RadioPolicy.OFF); 

This will overrule the OTA command server connection AUTOMATIC policy. Note that if you close the dummy connection, then the radio will turn back on, in line with the OTA command server’s AUTOMATIC policy.

Signal quality

(from the developer’s guide:The radio communication library)

  • RSSI (received signal strength indicator) measures the strength (power) of the signal for the packet. It ranges from +60 (strong) to -60 (weak). To convert it to decibels relative to 1 mW (= 0 dBm) subtract 45 from it, e.g. for an RSSI of -20 the RF input power is approximately -65 dBm.
  • CORR measures the average correlation value of the first 4 bytes of the packet header. A correlation value of $\sim$ 110 indicates a maximum quality packet while a value of $\sim$ 50 is typically the lowest quality packet detectable by the SPOT’s receiver.
  • Link Quality Indication (LQI) is a characterization of the quality of a received packet. Its value is computed from the CORR, correlation value. The LQI ranges from 0 (bad) to 255 (good).

These values are obtained using:

myRadiogram.getRssi();  
myRadiogram.getCorr();
myRadiogram.getLinkQuality(); 

Net Information:

(from the developer’s guide:Network information) Note that:

  • net management server needs to be running to enable this (system property spot.mesh.management.enable)
  • a basestation needs to be attached
ant netinfo -DremoteId=xxx [ -Dcommand=yyyy]

where command can be:

  • stats: retrieves the LowPanStats object from a remote node
  • routes: retrieves the current routing table from the remote node
  • tracert: traces the current route to the specified SPOT.

Power and Turning off services

USB and USART

Saving power by disconnection USB and USART:

By default, the SPOT’s USB device controller and two of its USARTs are always enabled. A small amount of power can be saved by disabling these if they are not required. Control is via operations on IAT91_PowerManager. To turn off the USB support:

Spot.getInstance().getAT91_PowerManager().setUsbEnable(false); 

Turning off the USB saves about 1.5mA (measured as battery draw current). To turn off the USART support:

Spot.getInstance().getAT91_PowerManager().setUsartEnable(false); 

Turning off the USARTs saves about 0.3mA (measured as battery draw current). Note that support for USB and USARTs is not reenabled when the VM restarts; if the VM exits with support disabled it will be necessary to turn off the SPOT and turn it back on. For this reason it is best to enclose statements that turn off these devices in a try/finally block, where the finally section turns them back on.

In case of problems with the disconnection see here.

Other services

Using the ISpot interface it is possible to stop() other services (list in the IService interface page)

// Deprecated Spot.getInstance().getOTACommandServer().stop() 
OTACommandServer.getInstance().stop();

Don’t know of a way to get the Service list programmaticaly.

Deep Sleep

The minimum idle time for which deep sleeping is allowed can be found from the SleepManager. For example, the following code can only ever trigger a shallow sleep:

ISleepManager sleepManager = Spot.getInstance().getSleepManager();  
Thread.sleep(sleepManager.getMinimumDeepSleepTime() - 1); 

Conditions for:

  • Deep sleep mode must not have been deactivated using the SleepManager (as shown above).
  • All threads must be blocked either on synchronization primitives or on a timed wait with a time to wake up at least as long as the minimum deep sleep time (including the wake time allowance)
  • At least one thread must be on a timed wait (that is, the Sun SPOT will not deep sleep if all threads are blocked on synchronization primitives).
  • All device drivers must store any necessary persistent state in RAM (to protect against the associated hardware being switched off) and agree to deep sleep. A driver may veto deep sleep if switching off its associated hardware would cause problems. In this case all drivers are set up again and a shallow sleep is performed instead.

Note the above on the OTA command server regarding the Radio.

Device Condition to permit deep sleep
CC2420 Radio receiver must be off
Timer-counter The counter must be stopped
PIO All pins claimed must have been released
AIC All interrupts must be disabled
PowerManager All peripheral clocks must be off

Checking / Getting readings

See the SpotCheck code in the sdk\SPOT-Utilities\SpotCheck dir.

Previous
Next