Interfacing With the AS5600 Magnetic Encoder
by joshua796 in Circuits > Sensors
234 Views, 1 Favorites, 0 Comments
Interfacing With the AS5600 Magnetic Encoder
This project is a guide on intefacing a microcontroller (pico 2) with the AS5600 rotary magnetic encoder.
This project also aims to teach creating your own hardware abstraction layers (HALs).
Supplies
- AS5600 magnetic encoder
- a magnet specifically made for the AS5600
- raspberry pi pico 2 or a microcontroller of your choice.
- jumper wires
- Data sheets for the as5600 sensor which can be found below,
- and documentation for the pico c/c++ sdk library which can be found using this link -> https://www.raspberrypi.com/documentation/microcontrollers/c_sdk.html
For your reference I have included pictures of some of the components that you will need.
The CODE
We can start by creating a new header file called AS5600.h in the project folder you want to use the as5600. You can use any code editor or IDE of your choice.
We will be using the I2C interface of the AS5600 for this project.
the as5600 operates as a slave on the I2C bus and has a 7-bit slave address of 0x36 in hexadecimal.
the maximum clock signal i.e SCL frequency supported is 1MHz.
To start off the project we can create a hardware abstraction layer that contains all of the registers and bit masks that we need. You can use pages 18-20 for this. I have attached the c code below.
Keep in mind that the following code can be used for any microcontroller its only a HAL.
For example in the data sheet the ANGLE register has a word address of 0x0E, when writing to or reading from a register you first have to specify the slave address to the native i2c function of your chosen microcontroller, and next you include the address of the register you want to access (this is referred to as word address in the data sheet).
according to the data sheet the only data stored in this register is the absolute angle value in the range 0 to 360; which is stored as a 12-bit value since this is a 12-bit sensor.
To extract this value you need a bit mask for those specific bits in the register; here the bit mask for the ANGLE register is 0x0FFF.
If a register has more than one address like for CONF we only need to take the top/ first address as the as5600 automatically reads the whole register including the part that is tied to the second address (data contained at this address is also called the Low byte whereas the first address has data called the high byte).
for CONF we create a bit mask for each part of the register that supports a certain function
i.e one for the PM bits, one for the HYST bits and so on.
Bit masks are like a sheet of paper with a hole in it that only allows certain parts of a register to be seen,
similarly a bit mask along with bitwise and shift operators can be used to extract the values of certain bits in a register. Refer to the data sheet.
now lets create a few functions to actually read and write to these registers.
here I will be implementing code specific to the pico 2 but only the I2C read and write commands, the rest of the function's logic is the same irrespective of which microcontroller you use.
we first need to include <stdio.h> and "hardware/i2c.h" inorder to be able to use the i2c functions for the pico2
so in this example to read the ANGLE register lets create a function called readAS5600_Angle() as below
next in the {} brackets lets first create an array called raw_data to store the 2 bytes (high byte and low byte) of data that we receive .
next to actually perform the read
we first have to write to the ANGLE register asking it to transmit the data stored in the ANGLE register
and then read the data that the as5600 transmits back to us over I2C.
the above two functions are specific to the pico c/c++ sdk but the logic is the same for any other microcontroller;
In i2c_write_blocking() function You first specify which i2c port (here its i2c0) you are using, next specify the slave address of the as5600 ic (which we defined to be 0x36) , and then provide the register that you want to access (the ANGLE register which has address of 0x0E, after which we say true to nostop which ensures that the host in this case the microcontroller still has control over the I2C Bus and enables the AS5600 to transmit the data, after which we specify false for nostop in the i2c_read_blocking() function so that the microcontroller relinquishes control. the 2 bytes of data received gets stored in raw_data.
Now we need a way to extract the angle information from the two bytes, this is where our bit masks come in handy.
each byte has 8 bits so two bytes of data contain 16 bits. we need to place both bytes side by side with the high byte first and then the low byte so that it forms a single 16 bit value which we store in a variable called angle.
what the above line does is it converts the high byte (raw_data[0]) into a 16 bit and then shifts it to the left by 8 bits using << 8 and then combines this with the low byte (raw_data[1]) using the binary | operator.
now that we have a single 16 bit long number its time we extracted the 12-bit angle value from these 16 bits.
this is where the ANGLE_mask bit mask comes in.
we use binary & operator to leave us with only the 12 bits and converts the rest of the 4 bits in the 16 bit number to 0.
now that we have our angle value as binary, we need to convert this into a value between 0 and 360, for this we can use the following expression ->. angle*360.0/4096.0
and then return the angle value from the function.
so overall the function readAS5600_Angle() looks like
Below I have provided all the other functions along with all of the bit mask definitions combined into a single AS5600.h file.
now to actually test this out #include "AS5600.h" into your main .c file and lets write some basic code to get stuff working.
to connect the AS5600 to the pico 2, connect the SDA pin on as5600 to GPIO pin 8 on the pico 2 and the SCL pin to GPIO pin 9 on the pico 2. the dir pin can be used to control the direction of rotation of the magnet that should be taken as positive, GND is connected to the ground pin / GND on the pico 2 and power is taken from the 3v3 power output on the pico 2. refer to the pico2 data sheet provided in this guide.
Pictures to Guide You With Wiring and Connections.
Note:- the AS5600 breakout board used in this guide already has pull up resistors integrated for I2C communication
GO Further
You now have the know how to get started with creating your own HALs and interfacing with sensors.
If you want to take your skills further why don't you check out my instructable that use the AS5600 along with a pico 2 to build a FOC like stepper controller.