VanGo
High-Rate Data Acquisition System
»Home
»Download
»Install
»Brief Intro
System Overview

The Sampler

The Sampler is created to be reconfigurable and to fit many different sampling scenarios. The Sampler can be instructed to collect varying amounts of data from different channels, different number of channels, and at many sampling rates.

The Sampler control interface, used by ControlM, is used to modify how the Sampler collects data.

Example: vango/tos/interfaces/SamplerControl.nc
...
interface SamplerControl {
  command void init(uint8_t numChannels);
  command void start(uint16_t collectCount,
                     sample_rate_t rate,
                     uint16_t sampler_send_mask);
  command void stop();
}

The init function is used to initialize the Sampler and to tell it how many channels will be sampled. The start function is used to tell the Sampler to begin sampling for a collectCount number of points (0xffff being infinity) at a rate of rate. The sampler_send_mask parameter is used to dictate which SampleSet data-structure elements will be sent over the radio. Before beginning the data buffer calculation of a SampleSet, the Sampler first asks the SampleSet to calculate the size of the packet header by using the SampleSet.getHeaderSize function on the mask and passing the result as an argument to the bufferSize function of the SingleFilter interface. The mask is also attached to each SampleSet created to inform Packetizer how to marshal the SampleSets into a packet at the end of the filter chain. The rate and send mask are defined as default values in the SnackConstants.h file and are used by ControlM to start the Sampler. The stop function is used to stop the Sampler.

The Sampler internally uses the ADC to sample data, the DMA to collect the data into a SampleSet, and a DoubleBuffer and a queue to manage the created SampleSets. The ADC is initialized to run at a rate of rate and to collect data from numChannels ADC ports. The DMA is configured to collect data from the ADC into a buffer attached to a SampleSet.

Double Buffering

Since allocating SampleSets takes time and can delay ADC data collection, SampleSet data buffers are allocated before the DMA is done filling a buffer while the rest of the SampleSet is allocated after the DMA has been restarted. This "double buffering" is handled by the DoubleBuffer module that makes sure to have a SampleSet data buffer prepared to be filled before the DMA needs it.

Example: vango/tos/interface/DoubleBuffer.nc
...
interface DoubleBuffer {
  async command result_t init(length_t buffer_size);
  async command void *getWriteBuffer();
  async command void *getReadBuffer();
  async command length_t getBufferSize();
}

The DoubleBuffer works by allocating a new write buffer each time the getWriteBuffer function is called and setting the current write buffer as the read buffer accessible by calling the getReadBuffer function.

Synchronization - The Queue

The Sampler generates SampleSets asynchronously triggered by the ADC data collection rate. Pushing data through a filter chain can take up many processor cycles and reduce the real-time reaction of the mote because system interrupts that post tasks to the TinyOS scheduler would be severely delayed by long filter chains. Also, a high data generation rate could overflow a filter chain (make a new SampleSet available for processing before the previous one is processed), resulting in lost SampleSets, in the face of momentary filter processing peaks. To reduce SampleSet loss due to load peaks and to increase the responsiveness of the mote, the asynchronous SampleSet generation needs to be converted to synchronous tasked computation. This is achieved by using a queue built-in to the Sampler.

The queue sits between the Sampler and the very first filter in the filter chain. The queue collects SampleSets generated by the Sampler and pushes them through the filter stack only when the filter chain is done processing the data. (Technically, untill the SampleSet is split up into packets and put into a second queue before being sent out over the radio.) In the current implementation of a VanGo queue, dequeues are triggered only when data is enqueued. If the queue contains SampleSets, but no SamplesSets are enqueued, the queued SampleSets will remain in the queue.

Run Time

The ADC continuously generates data at a fixed rate while the DMA places the data into a buffer every time the ADC makes a value available. As soon as the DMA fills the buffer, the DMA triggers an interrupt that informs the Sampler that a DMA buffer is filled. The Sampler then quickly restarts the DMA with a buffer that was already allocated by the DoubleBuffer; the Sampler then places the collected SampleSet into the queue, and instructs DoubleBuffer to allocate a new write buffer so that when the next buffer-filled DMA interrupt occurs, a buffer will be ready. The queued data is pushed through the filters as soon as the filters are done processing the previous SampleSet.