- Polling mode
- Ready for multi-devices use
- Address management
- Interrupt mode
- Provide an example application with Nucleo F401
- Provide easier FreeRTOS compatibility
A Nucleo F401RE is required.
The example shows the concurrent use of 3 devices and have been tested with one and two axis devices.
We assume that you:
- You redirected the printf function to write on an known output (USART1 for this kind of Nucleo)
- You enabled
- Generate the CubeMX project
- Redirect the printf function to write on the output you want (ITM, or UART)
- Enable float printf by adding "-u _printf_float" in the Linker flags
- Add the following code section in Src/freertos.c :
#include "i2c.h"
#include "ads_hal.h"
#include "ads.h"
#define USING_ONE_AXIS_SENSORS 1
#define USING_TWO_AXIS_SENSORS 0
#if USING_ONE_AXIS_SENSORS
#define SENSOR_1_ADDRESS 0x08
#elif USING_TWO_AXIS_SENSORS
#define SENSOR_1_ADDRESS 0x10
#endif
#if USING_ONE_AXIS_SENSORS
#define SENSOR_2_ADDRESS 0x09
#elif USING_TWO_AXIS_SENSORS
#define SENSOR_2_ADDRESS 0x11
#endif
#if USING_ONE_AXIS_SENSORS
#define SENSOR_3_ADDRESS 0x0A
#elif USING_TWO_AXIS_SENSORS
#define SENSOR_3_ADDRESS 0x12
#endif
char getChar();
void calibrate(ads_handler_t * h)
{
char c;
c = getChar();
ads_calibrate(h, 0, 0);
if (h->type == ADS_TWO_AXIS)
{
printf("Good. Now press a key when the sensor is straight from base but 90 degrees up from table (along Y axis)\n");
c = getChar();
ads_calibrate(h, ADS_CALIBRATE_PERP, 90);
}
printf("Good. Now press a key when the sensor is flat on table but bent at 90 degrees (along X axis)\n");
c = getChar();
ads_calibrate(h, 1, 90);
printf("Calibration complete.\n");
}
char getChar()
{
uint8_t buf[0];
HAL_StatusTypeDef res1;
do {
res1 = HAL_UART_Receive(&huart2, buf, 1, 0x0A);
if (ads_poll_data(&ads1))
{
printf("%.1f\n", ads1.data[0]);
}
} while (res1 != HAL_OK);
return buf[0];
}
- Place the following code section in the StartDefaultTask generated by CubeMX:
ads_handler_t ads1;
ads_handler_t ads2;
ads_handler_t ads3;
bool getDataFlag = true;
/* Let the HAL know which i2c handler is being used */
ads_hal_set_i2c_handler(&hi2c1);
/* Set parameters */
memset(&ads1, 0, sizeof(ads_handler_t));
ads1.comSize = ADS_TRANSFER_SIZE_ONE_AXIS;
ads1.sps = ADS_100_HZ;
ads1.i2c_address = SENSOR_1_ADDRESS;
ads1.reset_pin = GPIO_PIN_0;
ads1.reset_port = (void*) GPIOC;
ads1.interrupt_mode = 0; //disable the interrupt mode
memset(&ads2, 0, sizeof(ads_handler_t));
ads2.comSize = ADS_TRANSFER_SIZE_ONE_AXIS;
ads2.sps = ADS_100_HZ;
ads2.i2c_address = SENSOR_2_ADDRESS;
ads2.reset_pin = GPIO_PIN_1;
ads2.reset_port = (void*) GPIOC;
ads2.interrupt_mode = 0; //disable the interrupt mode
memset(&ads3, 0, sizeof(ads_handler_t));
ads3.comSize = ADS_TRANSFER_SIZE_ONE_AXIS;
ads3.sps = ADS_100_HZ;
ads3.i2c_address = SENSOR_3_ADDRESS;
ads3.reset_pin = GPIO_PIN_2;
ads3.reset_port = (void*) GPIOC;
ads3.interrupt_mode = 0; //disable the interrupt mode
ads_init(&ads1); /* Init */
ads_init(&ads2); /* Init */
ads_init(&ads3); /* Init */
osDelay(150);
/* Infinite loop */
for(;;)
{
if (getDataFlag)
{
if (ads_poll_data(&ads1))
{
printf("%.1f\n", ads1.data[0]);
}
if (ads_poll_data(&ads2))
{
printf("%.1f\n", ads2.data[0]);
}
if (ads_poll_data(&ads3))
{
printf("%.1f\n", ads3.data[0]);
}
}
osDelay(100);
// Quick way to get an input from the user to see if we need to calibrate or enable/disable the stream
memset(tbuf, 0, 16);
HAL_StatusTypeDef res1;
res1 = HAL_UART_Receive(&huart2, tbuf, 1, 0x0A);
if (res1 == HAL_OK)
{
printf("Input: %c\n", tbuf[0]);
if (tbuf[0] == 'a')
{
ads_calibrate(&ads1, ADS_CALIBRATE_FIRST, 0);
ads_calibrate(&ads2, ADS_CALIBRATE_FIRST, 0);
}
else if (tbuf[0] == 'b')
{
ads_calibrate(&ads1, ADS_CALIBRATE_FLAT, 90);
ads_calibrate(&ads2, ADS_CALIBRATE_FLAT, 90);
}
else if (tbuf[0] == 'c')
{
calibrate(&ads1);
}
else if (tbuf[0] == 'd')
{
getDataFlag = 1;
}
else if (tbuf[0] == 'e')
{
getDataFlag = 0;
}
}
}
}