Skip to content

Data acquisition is the process of sampling signals that measure real-world physical conditions and converting the resulting samples into digital numeric values that can be manipulated by a computer.

In the powerAPI context, the DataAPI helps the user retrieve the values sampled by the ADC.

The Data API configures the DMAs to store the ADCs acquisitions for the Spin board, and dispatches them in per-channel buffers that can be read by the user. The module also provides functions to convert the raw values acquired by the sensors into values in the adequate unit.

If using a shield such as Twist, channels are automatically made available for configuration and conversions functions are automatically calibrated using the device tree.

Include

Note

#include <DataAPI.h>

To use the Data API, include DataAPI.h in your source file. From there, a data object is available to interact with the API.

Data dispatching

When using the control task (critical task) data are dispatched at the start, which means there are ready to be retrieved.

data dispatch

Initialization sequence

If you want specific ADC behavior (trigger sources, discontinuous mode, etc.), you may want to configure the ADCs using the lower-level ADC API first. Then, you can enable channels that you want to acquire.

After channels have been enabled, the conversion parameters can be set so that raw values can be automatically converted to the relevant unit. This is done using the data.setParameters() function.

After channels have been enabled (and optionnally conversion parameters have been set), there are two ways of starting the API, depending on your use of other OwnTech APIs. If your code uses an uninterruptible task, nothing more is required, the Data API will be started automatically when task is started. However, if you do not have an uninterruptible task in your code, you need to manually start the API by calling data.start().

Note

  1. Enable acquisition on the pins you want: data.enableAcquisition()
  2. Define acquisition conversion parameter: data.setParameters()
  3. start data dispatching data.start()
  4. Trigger an initial adc conversion data.triggerAcquisition(ADCx)
  5. Retrieve values : data.getLatest() or data.getRawValues()
  1. Make sure PWM engine is initialized
  2. Enable acquisition on the pins you want: data.enableAcquisition()
  3. Define acquisition conversion parameter: data.setParameters()
  4. start data dispatching data.start()
  5. Retrieve values : data.getLatest() or data.getRawValues()

Example

data.enableAcquisition(1, 5); // ADC 1 ; Pin 5
data.triggerAcquisition(1); // ADC 1
float32_t adc_value = data.getLatest(1, 5); // ADC 1 ; Pin 5
/* PWM unit initialization */
spin.pwm.setModulation(PWMA, UpDwn);
spin.pwm.setAdcEdgeTrigger(PWMA, EdgeTrigger_up);
spin.pwm.setAdcDecimation(PWMA, 1);
spin.pwm.setMode(PWMA, VOLTAGE_MODE);
spin.pwm.initUnit(PWMA);
spin.pwm.setDeadTime(PWMA, 200,200);
spin.pwm.setAdcTrigger(PWMA, ADCTRIG_1);
spin.pwm.enableAdcTrigger(PWMA);
spin.pwm.setDutyCycle(0.5);
spin.pwm.startDualOutput(PWMA);

/* ADC initialization */
spin.adc.configureTriggerSource(1, hrtim_eev1); // ADC 1 ; HRTIM event 1
spin.adc.configureDiscontinuousMode(1, 1); // ADC 1 ; acquire 1 pin at each event
data.enableAcquisition(1, 5); // ADC 1 ; Pin 5
data.start();
float32_t adc_value = data.getLatest(1, 5); // ADC 1 ; Pin 5

Retrieving last value

Getting the last measured value to feed the control algorithm is super simple.

Example

data.getLatest(1, 5)
This will retrieve the last sampled value of ADC 1 pin 5.

Getting values with the right unit

DataAPI contains commodity functions to convert the raw binary measurement values in meaningful units.

Example

data.setParameters()

Get an array of values

DataAPI contains commodity function to retrieve an array of raw values that can be fed to a post processing filter.

Example

data.getRawValues()

Class DataAPI

ClassList > DataAPI

Public Functions

Type Name
float32_t convert (channel_t channel, uint16_t raw_value)
Use this function to convert values obtained using matching data.get*RawValues() function to relevant unit for the data: Volts, Amperes, or Degree Celcius.
float32_t convert (uint8_t adc_num, uint8_t pin_num, uint16_t raw_value)
Use this function to convert values obtained using matching data.get*RawValues() function to relevant unit for the data: Volts, Amperes, or Degree Celcius.
int8_t enableAcquisition (uint8_t adc_num, uint8_t pin_num)
This function is used to enable acquisition on a Spin PIN with a given ADC.
int8_t enableShieldChannel (uint8_t adc_num, channel_t channel_name)
This function is used to enable a channel on a given ADC using its name on a shield, rather than the ADC channel number. This function requires the presence of an "adc-channels" node in the shield device-tree.
void enableTwistDefaultChannels ()
This function is used to enable acquisition of all voltage/current channels on the Twist shield. Channels are attributed as follows: ADC1: - I1_LOW ADC2: - I2_LOW.
DispatchMethod_t getDispatchMethod ()
Gets the dispatch method of the module.
float32_t getLatest (channel_t channel, uint8_t * dataValid=nullptr)
This function returns the latest acquired measure expressed in the relevant unit for the channel: Volts, Amperes, or Degree Celcius.
float32_t getLatest (uint8_t adc_num, uint8_t pin_num, uint8_t * dataValid=nullptr)
This function returns the latest acquired measure expressed in the relevant unit for the channel: Volts, Amperes, or Degree Celcius.
uint16_t * getRawValues (channel_t channel, uint32_t & number_of_values_acquired)
Function to access the acquired data for specified channel. This function provides a buffer in which all data that have been acquired since last call are stored. The count of these values is returned as an output parameter: the user has to define a variable and pass it as the parameter of the function. The variable will be updated with the number of values that are available in the buffer.
uint16_t * getRawValues (uint8_t adc_num, uint8_t pin_num, uint32_t & number_of_values_acquired)
Function to access the acquired data for specified pin. This function provides a buffer in which all data that have been acquired since last call are stored. The count of these values is returned as an output parameter: the user has to define a variable and pass it as the parameter of the function. The variable will be updated with the number of values that are available in the buffer.
float32_t peek (channel_t channel)
Function to access the latest value available from the channel, expressed in the relevant unit for the data: Volts, Amperes, or Degree Celcius. This function will not touch anything in the buffer, and thus can be called safely at any time after the module has been started.
float32_t peek (uint8_t adc_num, uint8_t pin_num)
Function to access the latest value available from a pin, expressed in the relevant unit for the data: Volts, Amperes, or Degree Celcius. This function will not touch anything in the buffer, and thus can be called safely at any time after the module has been started.
void setDispatchMethod (DispatchMethod_t dispatch_method)
Sets the dispatch method of the module.
void setParameters (channel_t channel, float32_t gain, float32_t offset)
Use this function to tweak the conversion values for the channel if default values are not accurate enough.
void setParameters (uint8_t adc_num, uint8_t pin_num, float32_t gain, float32_t offset)
Use this function to tweak the conversion values for the channel if default values are not accurate enough.
void setRepetitionsBetweenDispatches (uint32_t repetition)
Indicates the repetition count between two external dispatches when it is handled externally by the Scheduling module. This value is used to calibrate buffers sizes.
void setTwistChannelsUserCalibrationFactors ()
Retrieve stored parameters from Flash memory and configure ADC parameters.
int8_t start ()
This functions manually starts the acquisition chain.
bool started ()
Checks if the module is already started.
void triggerAcquisition (uint8_t adc_num)
Triggers an acquisition on a given ADC. Each channel configured on this ADC will be acquired one after the other until all configured channels have been acquired.

Public Functions Documentation

function convert [1/2]

Use this function to convert values obtained using matching data.get*RawValues() function to relevant unit for the data: Volts, Amperes, or Degree Celcius.

float32_t DataAPI::convert (
    channel_t channel,
    uint16_t raw_value
) 

Note:

This function can't be called before the channel is enabled.

Parameters:

  • channel Name of the shield channel from which the value originates
  • raw_value Raw value obtained from which the value originates

Returns:

Converted value in the relevant unit.


function convert [2/2]

Use this function to convert values obtained using matching data.get*RawValues() function to relevant unit for the data: Volts, Amperes, or Degree Celcius.

float32_t DataAPI::convert (
    uint8_t adc_num,
    uint8_t pin_num,
    uint16_t raw_value
) 

Note:

This function can't be called before the pin is enabled.

Parameters:

  • adc_num Number of the ADC from which the value originates.
  • pin_num Number of the pin from which to obtain values.
  • raw_value Raw value obtained from the channel buffer.

Returns:

Converted value in the relevant unit.


function enableAcquisition

This function is used to enable acquisition on a Spin PIN with a given ADC.

int8_t DataAPI::enableAcquisition (
    uint8_t adc_num,
    uint8_t pin_num
) 

Note:

Not any pin can be used for acquisiton: the pin must be linked to a channel of the given ADC. Refer to Spin pinout image for PIN/ADC relations.

Note:

This function must be called before ADC is started.

Parameters:

  • adc_number Number of the ADC on which acquisition is to be done.
  • pin_num Number of the Spin pin to acquire.

Returns:

0 if acquisition was correctly enabled, -1 if there was an error.


function enableShieldChannel

This function is used to enable a channel on a given ADC using its name on a shield, rather than the ADC channel number. This function requires the presence of an "adc-channels" node in the shield device-tree.

int8_t DataAPI::enableShieldChannel (
    uint8_t adc_num,
    channel_t channel_name
) 

Note:

This function must be called before ADC is started.

Parameters:

  • adc_number Number of the ADC on which channel is to be enabled.
  • channel_name Name of the channel using enumeration channel_t.

Returns:

0 if channel was correctly enabled, -1 if there was an error.


function enableTwistDefaultChannels

This function is used to enable acquisition of all voltage/current channels on the Twist shield. Channels are attributed as follows: ADC1: - I1_LOW ADC2: - I2_LOW.

void DataAPI::enableTwistDefaultChannels () 

  • V1_LOW - V2_LOW
  • V_HIGH - I_HIGH

Note:

This function will configure ADC 1 and 2 to be automatically triggered by the HRTIM, so the board must be configured as a power converted to enable HRTIM events. All other ADCs remain software triggered, thus will only be acquired when triggerAcquisition() is called.

Note:

This function must be called before ADC is started.


function getDispatchMethod

Gets the dispatch method of the module.

DispatchMethod_t DataAPI::getDispatchMethod () 

Note:

End-user should not worry about this function, which is used internally by the Scheduling module.

Returns:

Dispatch method indicatinng when the dispatch is done.


function getLatest [1/2]

This function returns the latest acquired measure expressed in the relevant unit for the channel: Volts, Amperes, or Degree Celcius.

float32_t DataAPI::getLatest (
    channel_t channel,
    uint8_t * dataValid=nullptr
) 

Note:

This function can't be called before the channel is enabled and the DataAPI module is started, either explicitly or by starting the Uninterruptible task.

Note:

When using this functions, you loose the ability to access raw values using data.get*RawValues() function for the matching channel, as data.get*() function clears the buffer on each call.

Parameters:

  • channel Name of the shield channel from which to obtain value.
  • dataValid Pointer to an uint8_t variable. This parameter is facultative. If this parameter is provided, it will be updated to indicate information about data. Possible values for this parameter will be:
  • DATA_IS_OK if returned data is a newly acquired data,
  • DATA_IS_OLD if returned data has already been provided before (no new data available since latest time this function was called),
  • DATA_IS_MISSING if returned data is NO_VALUE.

Returns:

Latest acquired measure for the channel. If no value was acquired in this channel yet, return value is NO_VALUE.


function getLatest [2/2]

This function returns the latest acquired measure expressed in the relevant unit for the channel: Volts, Amperes, or Degree Celcius.

float32_t DataAPI::getLatest (
    uint8_t adc_num,
    uint8_t pin_num,
    uint8_t * dataValid=nullptr
) 

Note:

This function can't be called before the pin is enabled. The DataAPI module must have been started, either explicitly or by starting the Uninterruptible task.

Note:

When using this functions, you loose the ability to access raw values using data.get*RawValues() function for the matching channel, as data.get*() function clears the buffer on each call.

Parameters:

  • adc_num Number of the ADC from which to obtain value.
  • pin_num Number of the pin from which to obtain values.
  • dataValid Pointer to an uint8_t variable. This parameter is facultative. If this parameter is provided, it will be updated to indicate information about data. Possible values for this parameter will be:
  • DATA_IS_OK if returned data is a newly acquired data,
  • DATA_IS_OLD if returned data has already been provided before (no new data available since latest time this function was called),
  • DATA_IS_MISSING if returned data is NO_VALUE.

Returns:

Latest acquired measure for the channel. If no value was acquired in this channel yet, return value is NO_VALUE.


function getRawValues [1/2]

Function to access the acquired data for specified channel. This function provides a buffer in which all data that have been acquired since last call are stored. The count of these values is returned as an output parameter: the user has to define a variable and pass it as the parameter of the function. The variable will be updated with the number of values that are available in the buffer.

uint16_t * DataAPI::getRawValues (
    channel_t channel,
    uint32_t & number_of_values_acquired
) 

Note:

This function can't be called before the channel is enabled and the DataAPI module is started, either explicitly or by starting the Uninterruptible task.

Note:

When calling this function, it invalidates the buffer returned by a previous call to the same function. However, different channels buffers are independent from each other.

Note:

When using this functions, the user is responsible for data conversion. Use matching data.convert*() function for this purpose.

Note:

When using this function, DO NOT use the function to get the latest converted value for the same channel as this function will clear the buffer and disregard all values but the latest.

Parameters:

  • channel Name of the shield channel from which to obtain values.
  • number_of_values_acquired Pass an uint32_t variable. This variable will be updated with the number of values that are present in the returned buffer.

Returns:

Pointer to a buffer in which the acquired values are stored. If number_of_values_acquired is 0, do not try to access the buffer as it may be nullptr.


function getRawValues [2/2]

Function to access the acquired data for specified pin. This function provides a buffer in which all data that have been acquired since last call are stored. The count of these values is returned as an output parameter: the user has to define a variable and pass it as the parameter of the function. The variable will be updated with the number of values that are available in the buffer.

uint16_t * DataAPI::getRawValues (
    uint8_t adc_num,
    uint8_t pin_num,
    uint32_t & number_of_values_acquired
) 

Note:

This function can't be called before the pin is enabled. The DataAPI module must have been started, either explicitly or by starting the Uninterruptible task.

Note:

When calling this function, it invalidates the buffer returned by a previous call to the same function. However, different channels buffers are independent from each other.

Note:

When using this functions, the user is responsible for data conversion. Use matching data.convert*() function for this purpose.

Note:

When using this function, DO NOT use the function to get the latest converted value for the same channel as this function will clear the buffer and disregard all values but the latest.

Parameters:

  • adc_num Number of the ADC from which to obtain values.
  • pin_num Number of the pin from which to obtain values.
  • number_of_values_acquired Pass an uint32_t variable. This variable will be updated with the number of values that are present in the returned buffer.

Returns:

Pointer to a buffer in which the acquired values are stored. If number_of_values_acquired is 0, do not try to access the buffer as it may be nullptr.


function peek [1/2]

Function to access the latest value available from the channel, expressed in the relevant unit for the data: Volts, Amperes, or Degree Celcius. This function will not touch anything in the buffer, and thus can be called safely at any time after the module has been started.

float32_t DataAPI::peek (
    channel_t channel
) 

Note:

This function can't be called before the channel is enabled and the DataAPI module is started, either explicitly or by starting the Uninterruptible task.

Parameters:

  • channel Name of the shield channel from which to obtain value.

Returns:

Latest available value available from the given channel. If there was no value acquired in this channel yet, return value is NO_VALUE.


function peek [2/2]

Function to access the latest value available from a pin, expressed in the relevant unit for the data: Volts, Amperes, or Degree Celcius. This function will not touch anything in the buffer, and thus can be called safely at any time after the module has been started.

float32_t DataAPI::peek (
    uint8_t adc_num,
    uint8_t pin_num
) 

Note:

This function can't be called before the pin is enabled. The DataAPI module must have been started, either explicitly or by starting the Uninterruptible task.

Parameters:

  • adc_num Number of the ADC from which to obtain value.
  • pin_num Number of the pin from which to obtain values.

Returns:

Latest available value available from the given channel. If there was no value acquired in this channel yet, return value is NO_VALUE.


function setDispatchMethod

Sets the dispatch method of the module.

void DataAPI::setDispatchMethod (
    DispatchMethod_t dispatch_method
) 

Note:

End-user should not worry about this function, which is used internally by the Scheduling module.

Parameters:

  • dispatch_method Indicates when the dispatch should be done (default value: DispatchMethod_t::on_dma_interrupt)

function setParameters [1/2]

Use this function to tweak the conversion values for the channel if default values are not accurate enough.

void DataAPI::setParameters (
    channel_t channel,
    float32_t gain,
    float32_t offset
) 

Note:

This function can't be called before the channel is enabled. The DataAPI must not have been started, neither explicitly nor by starting the Uninterruptible task.

Parameters:

  • channel Name of the shield channel to set conversion values.
  • gain Gain to be applied (multiplied) to the channel raw value.
  • offset Offset to be applied (added) to the channel value after gain has been applied.

function setParameters [2/2]

Use this function to tweak the conversion values for the channel if default values are not accurate enough.

void DataAPI::setParameters (
    uint8_t adc_num,
    uint8_t pin_num,
    float32_t gain,
    float32_t offset
) 

Note:

This function can't be called before the pin is enabled. The DataAPI module must not have been started, neither explicitly nor by starting the Uninterruptible task.

Parameters:

  • adc_num Number of the ADC to set conversion values.
  • pin_num Number of the pin from which to obtain values.
  • gain Gain to be applied (multiplied) to the channel raw value.
  • offset Offset to be applied (added) to the channel value after gain has been applied.

function setRepetitionsBetweenDispatches

Indicates the repetition count between two external dispatches when it is handled externally by the Scheduling module. This value is used to calibrate buffers sizes.

void DataAPI::setRepetitionsBetweenDispatches (
    uint32_t repetition
) 

Note:

End-user should not worry about this function, which is used internally by the Scheduling module.

Parameters:

  • repetition Number of repetitions between two calls of dispatch. Used to calibrate buffers sizes.

function setTwistChannelsUserCalibrationFactors

Retrieve stored parameters from Flash memory and configure ADC parameters.

void DataAPI::setTwistChannelsUserCalibrationFactors () 

Note:

This function requires Console to interact with the user. You must first call console_init() before calling this function.

Note:

This function can't be called before the all Twist channels have been enabled (you can use enableTwistDefaultChannels() for that purpose). The DataAPI must not have been started, neither explicitly nor by starting the Uninterruptible task.


function start

This functions manually starts the acquisition chain.

int8_t DataAPI::start () 

Note:

If your code uses an uninterruptible task, you do not need to start Data Acquisition manually, it will automatically be started at the same time as the task as their internal behavior are intrinsically linked. If for some reason you have an uninterruptible task in your code, but do not want the Scheduling module to be in charge of Data Acquisition, you need to indicate it when starting the uninterruptible task. In that case, Data Acquisition must be manually started using this function. Note that in taht case, dispatch will use DMA interrupts which consumes a non-negligible amount of processor time and it is not advised.

Note:

Data Acquisition must be started only after ADC module configuration has been fully carried out. No ADC configuration change is allowed after module has been started. If you're using the Twist shield and are not sure how to initialize ADCs, you can use data.enableTwistDefaultChannels() for that purpose.

Note:

Data Acquisition must be started before accessing any data.get*() or data.peek*() function. Other Data Acquisition functions are safe to use before starting the module.

Returns:

0 if everything went well, -1 if there was an error. Error is triggered when dispatch method is set to be external, but the repetition value has not provided. Another source of error is trying to start Data Acquisition after it has already been started.


function started

Checks if the module is already started.

bool DataAPI::started () 

Returns:

true is the module has been started, false otherwise.


function triggerAcquisition

Triggers an acquisition on a given ADC. Each channel configured on this ADC will be acquired one after the other until all configured channels have been acquired.

void DataAPI::triggerAcquisition (
    uint8_t adc_num
) 

Note:

This function can't be called before the at least one channel is enabled on the ADC and the DataAPI module is started, either explicitly or by starting the Uninterruptible task.

Parameters:

  • adc_num Number of the ADC on which to acquire channels.


The documentation for this class was generated from the following file docs/core/zephyr/modules/owntech_data_api/zephyr/public_api/DataAPI.h

Using the Data API with a Twist shield

The Data API is optimized for running on Twist shields. It provides variants of the functions that take Twist sensors as parameters instead of pins numbers.

To enable the Twist Shield channels, use set(SHIELD twist) in CMakeLists.txt. From there, this module will provide additional functions to acquire and convert Twist channels by name.

If you use the Twist sensors, you can use data.enableTwistDefaultChannels() to automatically perform a standard configuration. From there, all current/tension channels of the Twist shields will be enabled as part of the default configuration. Default parameters for the channels are also loaded automatically as part of the process.