Skip to main content
Graduate II
January 16, 2025
Solved

No I2C communication with Nucleo-F411RE and ADXL345

  • January 16, 2025
  • 2 replies
  • 1339 views

I used STM32CubeMX to set up a Nucleo board (STM32F411RE) to communicate via I2C with a ADXL345 accelerometer.

- RCC & clock settings at default

- SDA on PB9 and SCL on PB8

- I2C Fast Mode

- targeted MDK-ARM toolchain

- generated code

 

In `main.c` added the following code,

 

#define adxl_address 0x53<<1 // was told that this left shift was necessary for the HAL to fucntion properly??

uint8_t data_rec[6]; // data recieved in bytes
uint16_t x, y, z; // acc data

void adxl_write(uint8_t reg, uint8_t value)
{
uint8_t data[2];
data[0] = reg;
data[1] = value;
HAL_I2C_Master_Transmit(&hi2c1, adxl_address, data, 2, 10);
}

void adxl_read(uint8_t reg, uint8_t numberofbytes)
{
HAL_I2C_Mem_Read(&hi2c1, adxl_address, reg, 1, data_rec, numberofbytes, 100);
}

void adxl_init(void)
{
/* registers are all listed in adxl345 datasheet */
adxl_read(0x00, 1); // check if adxl is on line
adxl_write(0x2d, 0); // reset all bits
adxl_write(0x2d, 0x08); // measure bit-1, wakeup 0, 0 at 8hz
adxl_write(0x31, 0x01); // set range to +/- 4g
}

 

In `main()` I added the call to the adxl_init() function & in the main while loop,

 

 while (1)
 {
 /* USER CODE END WHILE */
 adxl_read(0x32, 6); // adxl output data register starts at 0x32
		x = (data_rec[1]<<8) | data_rec[0];
		y = (data_rec[3]<<8) | data_rec[2];
		z = (data_rec[5]<<8) | data_rec[4];
		
		HAL_Delay(10);
 /* USER CODE BEGIN 3 */
 }

 

I compile, all's fine, no errors, no warning. Download to the board, no issues. Open the debugger & run and get nothing! No values being read...

NicRoberts_0-1737041819726.png

I've tried 2 different ADXL345s neither give any values.
ADXL set up the same as the pic below (R - 4k7)

NicRoberts_1-1737041989360.png

Anyone see anything obvious?

 

EDIT:: I added a function to see if there was a device attached it comes up "NO" everytime

 

int ADXL345_ScanDeviceID()
{
	for(uint8_t address = 0; address < 255; address++)
	{
		if(HAL_I2C_IsDeviceReady(&hi2c1, address, 1, 100) == HAL_OK)
		{
			return address;
		}
	}
	return 0xff;
}

 

 EDIT 2:: I'm an ***, I had the wrong pins in the Nucleo board wired up!

    This topic has been closed for replies.
    Best answer by NicRoberts

    Yes thanks, I had the wrong pins in the Nucleo board wired up and the problem was matching the Nulceo board breakout header pins with the MCU pins. In my case I needed access to PB8 & PB9 which are found on the Arduino header at D15 & D14 respectively.

    NicRoberts_0-1737110950862.png

     

    2 replies

    Super User
    January 16, 2025

    @NicRoberts wrote:

     EDIT 2:: I'm an ***, I had the wrong pins in the Nucleo board wired up!


    So is it working now?

    NicRobertsAuthorAnswer
    Graduate II
    January 17, 2025

    Yes thanks, I had the wrong pins in the Nucleo board wired up and the problem was matching the Nulceo board breakout header pins with the MCU pins. In my case I needed access to PB8 & PB9 which are found on the Arduino header at D15 & D14 respectively.

    NicRoberts_0-1737110950862.png

     

    Super User
    January 17, 2025
    Graduate II
    January 16, 2025

    >>I compile, all's fine, no errors, no warning.

    Means its sufficiently syntatically correct, little else.

    The errors returned by the function tell a more helpful story

    The I2C addresses are 7-bit, not 8, and the 7-bits occupy the higher order bits, on the wire, and in the STM32

    The low order bit is for read or write indication, so NOT 0 thru 255

    int ADXL345_ScanDeviceID() // Will find first decoding part
    {
    	for(uint16_t address = 0; address < 128; address++)
    	{
    		if(HAL_I2C_IsDeviceReady(&hi2c1, address<<1, 1, 100) == HAL_OK)
    		{
    			return address;
    		}
    	}
    	return 0xff;
    }