Skip to content

Nucleo Accel Starter Project

wisabel0 edited this page Sep 13, 2023 · 12 revisions

About

The purpose of this starter project is to guide you through being able to get readings from the ADXL343 accelerometer over the I2C bus on a Nucleo.

Hardware

  • Nucleo STM32F303RE

image

  • ADXL343 accelerometer

image

  • At least 4 solid core female-female wires
  • 1 USB A to mini B cable

Data Sheets and Pinouts

ADXL343 accelerometer datasheet

What is a Nucleo?

A “Nucleo” is a microcontroller evaluation board manufactured by STM32 to prototype with STM32’s MCUs. Nucleos come with a removable ST-Link debugger/programmer integrated on the board, allowing firmware flashing and extensive debugging options through a simple USB connection. STM32 MCU have a wide range of hardware capabilities, with dedicated internal circuitry for I2C, SPI, UART, timers, and more. Firmware is typically written in C/C++ using STM32’s extremely capable Hardware Abstraction Layer (HAL) libraries, and compiled in STM32’s Cube IDE. Read this for more information.

What is an accelerometer?

The ADXL343 is a digital accelerometer that you’ll be using today. This device measures acceleration in all the x, y and z axes and sends this data via a serial line using the I2C communication protocol.

What is I2C?

I2C offers two-way communication between a device such as the ADXL343 (slave) and the Nucleo (master). Notice the SDA (Serial Data) and SCL (Serial Clock) pins on both the accelerometer and the Nucleo.

I2C relies on the clock line (SCL) to keep time between the devices connected so that they can communicate at the same rate. The data line (SDA) is a shared data line between the devices.

Each enabled with I2C also has an address. Try to find the address for the ADXL343 accelerometer in the documentation sheet.

Read this if you want to learn more about I2C.

Wiring and Set up

Pin 20 (GND): The GND (ground) cable is your negative power terminal.

Pin 16 (3V3): The VIN (voltage in) cable is your positive power terminal.

Pin 17 (PA15): The SCL (serial clock) cable is your clock cable.

Pin 21 (PB7): The SDA (serial data) cable is your data communication cable.

Refer to the following wiring diagram:

image

Starter code

If you have already cloned embedded-testbench for the Servo starter project, you do not need to do it again for the accelerometer.

To get the starter code, open up a new terminal window, clone the embedded test bench repository, and make a nucleo tutorial branch
$ git clone https://github.com/umrover/embedded-testbench/ (if not already cloned)
$ cd embedded-testbench
$ git checkout starter-projects
$ git checkout -b starter/<name>
Open up the Cube IDE project by opening the folder and double clicking on the .project file. Make sure that you already have Cube IDE installed.

What is a register?

A register is a direction to a place on a device such as the accelerometer that one can access data from or send commands to. The registers we will be using hold the acceleration data we are looking for. The types of data that can be read and written to each register can be found on the datasheet. You can look up various other addresses on the datasheet.

What is an I2C address?

This is the address that allows us to specify which I2C device we are querying since a master device can have multiple slaves. The accelerometer I2C address and registers we will need to write to and read from are summarized here. They are typically written in hexadecimal. Useful addresses and registers. These come from the adxl343 datasheet. image

What is LSB and MSB?

The Most Significant Bit and Least Significant Bit are a way for the data to be separated by significance. To get a full reading from the accelerometer, we must combine these two numbers. Essentially the data is split into two pieces and these are in two separate registers on the device.
As an analogy to this, imagine you have the number 2048. In MSB/LSB format it could be split up as 20 and 48. In order to combine the two correctly, you have to shift 20 over 2 decimal places (multiply by 10^2) and then add it to 48.
When it comes to retrieving and combining the data of the MSB and LSB registers, the idea is the same.
Splitting the data to be sent in two registers allows for higher precision data to be sent. More in depth info.

How interface with the register?

For reading data from registers, some functions are provided to you. If you look inside the main.c, you'll see that long read_byte_data(uint8_t addr, char cmd) and void write_byte_data(uint8_t addr, char cmd, uint8_t data) are provided to you.

The first step of this project is to write to the accelerometer's power&sleep register and get it out of sleep mode.
We must use the void write_byte_data(uint8_t addr, char cmd, uint8_t data) function for this. As implied by the parameters of the function, we must know three things:

  • the i2c address of the accelerometer
  • the hexidecimal value of the register we want to write to (or sometimes it is called the command)
  • the hexidecimal value we want to set that register to be

The i2c address of the device can be found in the datasheet listed as 'i2c address'. Take a look at page 16 in the datasheet.

For our use case, the ALT ADDRESS pin is grounded.

The register we want to write to is the power&sleep register.

Take a look at page 23 of the datasheet under 'POWER_CTL(Read/Write)'.

Listed next to it is 0x2D, which is the hex value of the register we want to write to.

How do you know what hexadecimal data to set that register to be? You have to take a further look at the register.

image

This is a picture from the datasheet. It shows us that register 0x2D is an 8 bit register, and labels each bit.

Below this on page 26/27 of the datasheet is a description of each bit, and what setting it to be a 0 or 1 means.

To summarize:

Bits 7 and 6 are automatically set to be zeros.

Bit 5, the Link bit, has to do with interrupts, which we are not using so it can be set to 0.

Bit 4, the AUTO_SLEEP bit, automatically puts the device into sleep mode if it detects inactivity. It says if the link bit is a zero this bit must also be set to 0.

Below is a description of bit 3, the Measure bit.

image

According to the description, in order to place the accelerometer into measurement mode, we need to set that bit to 1.

Bit 2, the Sleep bit, puts the device into sleep mode if it is set to 1, so we want to set this to 0.

Bits 1 and 0, the Wakeup bits control the frequency of readings in sleep mode, which is off, so we can leave these as 00 (since there are two of them).

More in depth descriptions are in the datasheet.

image

Overall, this gives us a bit string of 00001000 which is what we want to set the register to be.

For ease of readability we usually send this over as a base 16 hexidecimal value. Our bit string is currently in binary (base 2) so we need to convert it to base 16. Here is a good online converter for going from binary to hex. Go ahead and use that calculator to convert the binary string to hex. A thing to note about hex values is that they are all prefixed by 0x.

With these three pieces of information we can now enable the accelerometer. Using write_byte_data you can do this in your accelerometer code like so:

write_byte_data(i2c_dev_address, <insert register to write to>, <insert hex value to set register to>);.

Further Instructions

Initialize the sensor, and read x, y, and z data from it. The starter code along with this tutorial has some hints on what to do. Make sure you're taking a close look at the datasheet and all the registers to verify that you are turning the accelerometer on with all the correct bits set in the relevant registers, having it read data correctly, and for what values you need for unit conversions to m/s^2. Feel free to reach out to the ESW lead or other returning members for guidance!

Building

Before you test your code you will want to see that it can 'compile' by building the project. If there are any errors, fix them.

Testing

Because in this tutorial we do not print the data anywhere, we will have to use the debugger to investigate whether or not the code is working properly. This is good practice for what you may expect to see in the future.

Debugging in Cube IDE

Make sure that your Nucleo is connected to your computer. Also make sure that your project is able to build.

Click on Run -> Debug As -> 1 STM32 C/C++ Application.

image

On the following screen, you can just press OK.

image

If your device is unable to detect the Nucleo connected to it, you may see the following screen.

image

Retry the previous steps and if that does not work, then either double check your connections, or seek a new Nucleo board.

In the future, you may be able to get away with just clicking on Run -> Debug, or using the keyboard shortcut F11. This does not work the first time if you have never clicked on the Debug As button.

image

Now that you're in the debug mode, you may set breakpoints and run through your code or pause at any given moment. When paused, we can also see the values of certain variables. We will use this feature to view if the data we are reading for our accelerometer is reasonable.

TODO - Add to the wiki of how to set breakpoints and read variables..

Congratulations!

You have completed the Accelerometer on Nucleo Starter Project! Contact the ESW lead for further instructions.

Clone this wiki locally