Hello,
I'm working on a project where I need to get accurate static tilt measurements. I've been trying & figuring out multiple sensors and refined my requirements. Currently I am trying to work with the IIS2ICLX accelerometer which is outside of the well documented Arduino domain.
The amount of complexity this adds is a bit overwhelming. Their examples are based on their own MCU platforms. They do provide a platform independent driver with an example application (formatted at the bottem of this post). I can't quite figure out if - and how this is adjustable to an Arduino platform.
I am fairly new to all this but would really like to learn. The code has a couple of functions that need to be adjusted to the platform, like:
static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp,
uint16_t len)
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp,
uint16_t len)
My general attempts to adjust these to Arduino are as follows;
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp,
uint16_t len)
{
Wire.beginTransmission(ADDRESS);
Wire.write(reg);
Wire.requestFrom((uint8_t)ADDRESS, (uint8_t)len);
Wire.readBytes(bufp, len);
Wire.endTransmission();
delay(1000);
return 0;
}
Am I on the right track here, or how would I approach this? I'm not sure how to continue and am looking for any information that could help, as I have virtually no experience with this stuff. Thanks in advance!
Full example code:
/*
******************************************************************************
* @file read_data_simple.c
* @author Sensors Software Solution Team
* @brief This file show the simplest way to get data from sensor.
*
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/*
* This example was developed using the following STMicroelectronics
* evaluation boards:
*
* - STEVAL_MKI109V3 + STEVAL-MKI209V1K
* - NUCLEO_F411RE + STEVAL-MKI209V1K
* - DISCOVERY_SPC584B + STEVAL-MKI209V1K
*
* and STM32CubeMX tool with STM32CubeF4 MCU Package
*
* Used interfaces:
*
* STEVAL_MKI109V3 - Host side: USB (Virtual COM)
* - Sensor side: SPI(Default) / I2C(supported)
*
* NUCLEO_STM32F411RE - Host side: UART(COM) to USB bridge
* - Sensor side: I2C(Default) / SPI(supported)
*
* DISCOVERY_SPC584B - Host side: UART(COM) to USB bridge
* - Sensor side: I2C(Default) / SPI(supported)
*
* If you need to run this example on a different hardware platform a
* modification of the functions: `platform_write`, `platform_read`,
* `tx_com` and 'platform_init' is required.
*
*/
/* STMicroelectronics evaluation boards definition
*
* Please uncomment ONLY the evaluation boards in use.
* If a different hardware is used please comment all
* following target board and redefine yours.
*/
//#define STEVAL_MKI109V3 /* little endian */
//#define NUCLEO_F411RE /* little endian */
//#define SPC584B_DIS /* big endian */
/* ATTENTION: By default the driver is little endian. If you need switch
* to big endian please see "Endianness definitions" in the
* header file of the driver (_reg.h).
*/
#if defined(STEVAL_MKI109V3)
/* MKI109V3: Define communication interface */
#define SENSOR_BUS hspi2
/* MKI109V3: Vdd and Vddio power supply values */
#define PWM_3V3 915
#elif defined(NUCLEO_F411RE)
/* NUCLEO_F411RE: Define communication interface */
#define SENSOR_BUS hi2c1
#elif defined(SPC584B_DIS)
/* DISCOVERY_SPC584B: Define communication interface */
#define SENSOR_BUS I2CD1
#endif
/* Includes ------------------------------------------------------------------*/
#include <string.h>
#include <stdio.h>
#include "iis2iclx_reg.h"
#if defined(NUCLEO_F411RE)
#include "stm32f4xx_hal.h"
#include "usart.h"
#include "gpio.h"
#include "i2c.h"
#elif defined(STEVAL_MKI109V3)
#include "stm32f4xx_hal.h"
#include "usbd_cdc_if.h"
#include "gpio.h"
#include "spi.h"
#include "tim.h"
#elif defined(SPC584B_DIS)
#include "components.h"
#endif
/* Private macro -------------------------------------------------------------*/
#define BOOT_TIME 20 //ms
/* Private variables ---------------------------------------------------------*/
static int16_t data_raw_acceleration[2];
static int16_t data_raw_temperature;
static float acceleration_mg[2];
static float temperature_degC;
static uint8_t whoamI, rst;
static uint8_t tx_buffer[1000];
/* Extern variables ----------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*
* WARNING:
* Functions declare in this section are defined at the end of this file
* and are strictly related to the hardware platform used.
*
*/
static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp,
uint16_t len);
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp,
uint16_t len);
static void tx_com( uint8_t *tx_buffer, uint16_t len );
static void platform_delay(uint32_t ms);
static void platform_init(void);
/* Main Example --------------------------------------------------------------*/
void example_main_iis2iclx(void)
{
stmdev_ctx_t dev_ctx;
/* Initialize mems driver interface */
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;
dev_ctx.handle = &SENSOR_BUS;
/* Init test platform */
platform_init();
/* Wait sensor boot time */
platform_delay(BOOT_TIME);
/* Set Bus mode */
iis2iclx_bus_mode_set(&dev_ctx, IIS2ICLX_SEL_BY_HW);
/* Check device ID */
iis2iclx_device_id_get(&dev_ctx, &whoamI);
if (whoamI != IIS2ICLX_ID)
while (1);
/* Restore default configuration */
iis2iclx_reset_set(&dev_ctx, PROPERTY_ENABLE);
do {
iis2iclx_reset_get(&dev_ctx, &rst);
} while (rst);
/* Enable Block Data Update */
iis2iclx_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
/* Set Output Data Rate */
iis2iclx_xl_data_rate_set(&dev_ctx, IIS2ICLX_XL_ODR_12Hz5);
/* Set full scale */
iis2iclx_xl_full_scale_set(&dev_ctx, IIS2ICLX_2g);
/* Configure filtering chain(No aux interface)
* Accelerometer - LPF1 + LPF2 path
*/
iis2iclx_xl_hp_path_on_out_set(&dev_ctx, IIS2ICLX_LP_ODR_DIV_100);
iis2iclx_xl_filter_lp2_set(&dev_ctx, PROPERTY_ENABLE);
/* Read samples in polling mode (no int) */
while (1) {
uint8_t reg;
/* Read output only if new xl value is available */
iis2iclx_xl_flag_data_ready_get(&dev_ctx, ®);
if (reg) {
/* Read acceleration field data */
memset(data_raw_acceleration, 0x00, 2 * sizeof(int16_t));
iis2iclx_acceleration_raw_get(&dev_ctx, data_raw_acceleration);
acceleration_mg[0] =
iis2iclx_from_fs2g_to_mg(data_raw_acceleration[0]);
acceleration_mg[1] =
iis2iclx_from_fs2g_to_mg(data_raw_acceleration[1]);
sprintf((char *)tx_buffer, "Acceleration [mg]:%4.2f\t%4.2f\r\n",
acceleration_mg[0], acceleration_mg[1]);
tx_com(tx_buffer, strlen((char const *)tx_buffer));
}
iis2iclx_temp_flag_data_ready_get(&dev_ctx, ®);
if (reg) {
/* Read temperature data */
memset(&data_raw_temperature, 0x00, sizeof(int16_t));
iis2iclx_temperature_raw_get(&dev_ctx, &data_raw_temperature);
temperature_degC = iis2iclx_from_lsb_to_celsius(data_raw_temperature);
sprintf((char *)tx_buffer,
"Temperature [degC]:%6.2f\r\n", temperature_degC);
tx_com(tx_buffer, strlen((char const *)tx_buffer));
}
}
}
/*
* @brief Write generic device register (platform dependent)
*
* @param handle customizable argument. In this examples is used in
* order to select the correct sensor bus handler.
* @param reg register to write
* @param bufp pointer to data to write in register reg
* @param len number of consecutive register to write
*
*/
static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp,
uint16_t len)
{
#if defined(NUCLEO_F411RE)
HAL_I2C_Mem_Write(handle, IIS2ICLX_I2C_ADD_L, reg,
I2C_MEMADD_SIZE_8BIT, (uint8_t*) bufp, len, 1000);
#elif defined(STEVAL_MKI109V3)
HAL_GPIO_WritePin(CS_up_GPIO_Port, CS_up_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit(handle, ®, 1, 1000);
HAL_SPI_Transmit(handle, (uint8_t*) bufp, len, 1000);
HAL_GPIO_WritePin(CS_up_GPIO_Port, CS_up_Pin, GPIO_PIN_SET);
#elif defined(SPC584B_DIS)
i2c_lld_write(handle, IIS2ICLX_I2C_ADD_L & 0xFE, reg, (uint8_t*) bufp, len);
#endif
return 0;
}
/*
* @brief Read generic device register (platform dependent)
*
* @param handle customizable argument. In this examples is used in
* order to select the correct sensor bus handler.
* @param reg register to read
* @param bufp pointer to buffer that store the data read
* @param len number of consecutive register to read
*
*/
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp,
uint16_t len)
{
#if defined(NUCLEO_F411RE)
HAL_I2C_Mem_Read(handle, IIS2ICLX_I2C_ADD_L, reg,
I2C_MEMADD_SIZE_8BIT, bufp, len, 1000);
#elif defined(STEVAL_MKI109V3)
reg |= 0x80;
HAL_GPIO_WritePin(CS_up_GPIO_Port, CS_up_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit(handle, ®, 1, 1000);
HAL_SPI_Receive(handle, bufp, len, 1000);
HAL_GPIO_WritePin(CS_up_GPIO_Port, CS_up_Pin, GPIO_PIN_SET);
#elif defined(SPC584B_DIS)
i2c_lld_read(handle, IIS2ICLX_I2C_ADD_L & 0xFE, reg, bufp, len);
#endif
return 0;
}
/*
* @brief Write generic device register (platform dependent)
*
* @param tx_buffer buffer to transmit
* @param len number of byte to send
*
*/
static void tx_com(uint8_t *tx_buffer, uint16_t len)
{
#if defined(NUCLEO_F411RE)
HAL_UART_Transmit(&huart2, tx_buffer, len, 1000);
#elif defined(STEVAL_MKI109V3)
CDC_Transmit_FS(tx_buffer, len);
#elif defined(SPC584B_DIS)
sd_lld_write(&SD2, tx_buffer, len);
#endif
}
/*
* @brief platform specific delay (platform dependent)
*
* @param ms delay in ms
*
*/
static void platform_delay(uint32_t ms)
{
#if defined(NUCLEO_F411RE) | defined(STEVAL_MKI109V3)
HAL_Delay(ms);
#elif defined(SPC584B_DIS)
osalThreadDelayMilliseconds(ms);
#endif
}
/*
* @brief platform specific initialization (platform dependent)
*/
static void platform_init(void)
{
#if defined(STEVAL_MKI109V3)
TIM3->CCR1 = PWM_3V3;
TIM3->CCR2 = PWM_3V3;
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
HAL_Delay(1000);
#endif
}