Boomerang Connect External Sensors

From TinyOS Wiki
Jump to: navigation, search

Analog sensor TinyOS code

Using an ADC channel on the 16-pin Tmote Sky expansion area can be relatively easy. See tinyos-1.x/apps/TelosADC/ for an example.

Header: specify the ADC port

The essence of preparing an external ADC port for TinyOS is in the definition of two numbers: TOS_ADC_xxx_PORT and its partner TOSH_ACTUAL_ADC_xxx_PORT. "xxx" is a name you can pick when defining these values, perhaps picking a name that describes your sensor. Pretending I have a sensor called Super Sensor connected to ADC channel 0, I could define those two values in a header file like this:

enum {
  TOS_ADC_SUPERSENSOR_PORT = unique("ADCPort"), 

  TOSH_ACTUAL_ADC_SUPERSENSOR_PORT = ASSOCIATE_ADC_CHANNEL(
    INPUT_CHANNEL_A0,
    REFERENCE_VREFplus_AVss,
    REFVOLT_LEVEL_1_5
  ),
};

For your sensor, change the "SUPERSENSOR" name and the three parameters given to ASSOCIATE_ADC_CHANNEL. Those parameters are

  1. The pin on the microcontroller your device is connected to. INPUT_CHANNEL_AO means "ADC0" or "ADC port 0". Find the names of the pins in the Tmote Sky datasheet in the section "External Sensors". For instance, pin 7 of the 10-pin expansion header is connected to ADC2 which you could specify with INPUT_CHANNEL_A2.
  2. Use the internal reference voltage specified with REFERENCE_VREFplus_AVss.
  3. For the internal reference voltage, use the 1.5V reference voltage specified with REFVOLT_LEVEL_1_5. The one other option here is the 2.5V internal reference voltage specified with REFVOLT_LEVEL_2_5.

You can see similar specifications in gio0.h in the TelosADC/ directory. Beware, I believe a naming bug in that file is that port A0 does *not* correspond to GIO0 on Tmote Sky.

Module: bind and use the ADC port

In the module file that you will write or modify to use this sensor, you must use the ADC interface for each ADC port you are going to use, and use the ADCControl interface once to perform the ADC port "binding". Here are some key lines of module code. You will find similar lines of code in TelosADCM.nc. In StdControl.init():

// initialize the ADC subsystem
call ADCControl.init();
// Initialize the Super Sensor ADC port by binding it to its actual specification
call ADCControl.bindPort( TOS_ADC_SUPERSENSOR_PORT, TOSH_ACTUAL_ADC_SUPERSENSOR_PORT );

Later, you can just call ADC.getData which will response later with an ADC.dataReady event:

void readSuperSensor() {
  // ...
  call ADC.getData();
  // ...
}

async event result_t ADC.dataReady( uint16_t data ) {
  // do something interesting with data
}

Configuration: wire the ADC port

The last step is to wire up the ADC and ADCControl interfaces in your component configuration:

 components ADCC;
 SuperSensorM.ADC -> ADCC.ADC[TOS_ADC_SUPERSENSOR_PORT];
 SuperSensorM.ADCControl -> ADCC;

Wrapping up

Now you're ready to sample ADC data form your Super Sensor. A nice first exercise could be to integrate your sensor with the Oscilloscope application in /opt/moteiv/apps/Oscilloscope.