2025-08-18 5:40 AM
Hello everyone,
I am interfacing ADXL345 in stm32f103c8t6 by using I2C connection. I have fixed the set up on a board.
I would like to know if I can identify the movement of adxl by observing the changes in x, y, and z values if there is no vibration but the board is moving smoothly, that is, to the right or left. If not, how can I predict when the adxl will go forward or backward without relying on the sensor's tilt or vibration? I just want to create a basic activity detector where the logic would be :
1. If the setup does not move, the output should be zero.
2. If the setup is vibrating and moving, the output should be one.
3. If it is simply vibrating (and not moving in space), the output should be 0.
So, basically, I want to detect actual movement and not just vibration noise.
I noticed that when the movement is smooth or constant ADXL345 values do not change much, so my logic is not detecting that as “motion.”
STM32f103c8t6<-> ADXL345
PB6<->SCL
PB7<->SDA
GND<->GND
3V3<->VCC
the follwing code is the initialization
struct AdxlCommands
{
uint8_t DEVID; /* Device ID */
uint8_t THRESH_ACT; /* Activity threshold */
uint8_t THRESH_INACT; /* Inactivity threshold */
uint8_t TIME_INACT; /* Inactivity time */
uint8_t ACT_INACT_CTL; /* Axis enable control for activity and inactivity detection */
uint8_t BW_RATE; /* Data rate and power mode control */
uint8_t POWER_CTL; /* Power-saving features control */
uint8_t INT_ENABLE; /* Interrupt enable control */
uint8_t INT_MAP; /* Interrupt mapping control */
uint8_t INT_SOURCE; /* Source of interrupts */
uint8_t DATA_FORMAT; /* Data format control */
uint8_t DATAX0; /* X-Axis Data 0 */
uint8_t DATAX1; /* X-Axis Data 1 */
uint8_t DATAY0; /* Y-Axis Data 0 */
uint8_t DATAY1; /* Y-Axis Data 1 */
uint8_t DATAZ0; /* Z-Axis Data 0 */
uint8_t DATAZ1; /* Z-Axis Data 1 */
};
struct AdxlCommands AdxlReg = { 0x00, 0x24, 0x25, 0x26, 0x27, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 };
enum AdxlBitNum
{ D0, D1, D2, D3, D4, D5, D6, D7 };
struct AdxlData
{
uint8_t int_src;
uint8_t id;
int16_t x,y,z;
uint8_t raw[6];
}Adxl345;
i2c_tx[0] = AdxlReg.BW_RATE;
i2c_tx[1] = ((1 << D3) | (1 << D1));
HAL_I2C_Master_Transmit(&hi2c1, ADXL_ADR, (uint8_t*)i2c_tx, 2, 1000);
/* Range 16g */
i2c_tx[0] = AdxlReg.DATA_FORMAT;
i2c_tx[1] = ((1 << D0) | (1 << D1));
HAL_I2C_Master_Transmit(&hi2c1, ADXL_ADR, (uint8_t*)i2c_tx, 2, 1000);
/* Measure */
i2c_tx[0] = AdxlReg.POWER_CTL;
i2c_tx[1] = (1 << D3);
HAL_I2C_Master_Transmit(&hi2c1, ADXL_ADR, (uint8_t*)i2c_tx, 2, 1000);
The register setting of the ADXL345 sensor is
BW_RATE<->0x2C set to 10(D1 and D3 are set to 1)
DATA_FORMAT<->0x31 set to 3(D0 and D1 set to 1)
POWER_CTL<->0x2D set to measure mode
ACT_INACT_CTL<->0x27 set to FF
THRESH_INACT<->0x25 set to 3
THRESH_ACT<->0x24 set to 2
TIME_INACT<->0x26 set to FF
INT_MAP<->0x2F set to either for active or inactive interrupt
INT_ENABLE<->0x2E set to enable for both active and inactive
POWER_CTL<->0x2D set to again measure mode
The following code is to visualize the previous and current value differentiation
void ADXL3AXISVAlue(void)
{
// HAL_I2C_Master_Transmit(&hi2c1, ADXL_ADR, (uint8_t*)&AdxlReg.DATAX0, 1, 100);
// HAL_I2C_Master_Receive(&hi2c1, ADXL_ADR, (uint8_t*)&Adxl345.raw, 6, 100);
uint8_t rawData[6];
HAL_I2C_Mem_Read(&hi2c1, ADXL_ADR, AdxlReg.DATAX0, 1, rawData, 6, 100);
Adxl345.x = ((int16_t)(rawData[1] << 8) | rawData[0]);
Adxl345.y = ((int16_t)(rawData[3] << 8) | rawData[2]);
Adxl345.z = ((int16_t)(rawData[5] << 8) | rawData[4]);
X=abs((Adxl345.x) - prev_x);
Y=abs((Adxl345.y) - prev_y);
Z=abs((Adxl345.z) - prev_z);
// Check if movement exceeds tolerance
if (X > MOVEMENT_THRESHOLD || Y > MOVEMENT_THRESHOLD || Z > MOVEMENT_THRESHOLD)
{
is_moving = 1; // Movement detected
}
// Update previous values
prev_x = Adxl345.x;
prev_y = Adxl345.y;
prev_z = Adxl345.z;
sprintf((char*)data, "X: %6d, Y: %6d, Z: %6d\r\n", Adxl345.x, Adxl345.y, Adxl345.z);
HAL_UART_Transmit(&huart2, (uint8_t *)data, strlen((char*)data), HAL_MAX_DELAY);
// Print values via UART
HAL_Delay(100);
}
and call in the loop.
Using the above code i am only getting the is_moving is set when there is only vibration otherwise the value is in reset condition though the board is moving smoothly.
Guide me regarding this.