cancel
Showing results for 
Search instead for 
Did you mean: 

ADXL345 (using I2C connection) in stm32f103c8t6 controller for knowing the motion value

Shaktimayee
Associate II

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.

 

0 REPLIES 0