Project update 4 of 11
Good news from PCBWay, the two pre-production boards with the new silkscreen layer are on its way. So hopefully next week I can share some images.
In the meantime, let’s have a look at the AS5048 rotary encoder, one of many choices for having a closed loop BLDC motor implementation. This encoder can be purchased for around \$10-\$15 at Digikey or Mouser in a board/adapter formfactor kit with accompanying magnet.
So, why do we need a rotary encoder? Well, strictly speaking, we don’t. But in my opinion, it is the best choice when starting out experimenting with BLDC motors. It tells your code at which position the motor shaft is at any moment in time. Something that is needed for most commutation approaches. If you don’t know the current position, your code is blind and can only assume the motor shaft is following the commutation pattern you’re sending to it. This is called open-loop operation.
For closed-loop operation you’ll need position information. Besides using a sensor for this task, you can also use a motor property called BEMF (back electromotive force). To put it simply, you can measure the opposing electromotive force the motor coils are producing as a reaction to the changing currents going through them. As every inductor, a motor coil “doesn’t like” change of current and counters these changes by emitting counter voltages.
These BEMF variations, which tell us when each coil is activated or deactivated, can be measured using a resistor in series with the motor coils which produces voltage fluctuations you can pick up using an oscilloscope for instance. For this purpose, SwarmDrive has a sense resistor which is broken out to a test connection to which you can hook-up to a scope. The sense resistor (0.01 Ohm) can handle up to 2W of power and is connected between the sense pin of the L6234 and GND.
So, why not use BEMF then? Because it’s hard. It can be weak and chaotic, so you need very clever circuitry to make it usable somehow. For my research purposes this was just too far fetched, but of course you could give it a try.
Using a rotary encoder is much easier. For the AS5048 you just need to attach a magnet (a special polarized one) to the spinning part of the motor and the sensor will read its position using the Hall Effect principle. The AS5048 is capable of communicating this position information at very fast rates using one of several communication protocols. I choose to use I2C for reading the position from code. For this purpose, a simple API class (the Rotational Position Sensor or RPS class) is included with the SwarmDrive example code.
When initialized you can just read the angle by calling getAngleR(). The “R” is for raw, which means that you will get a number from 0-16384 (the 14-bit resolution of the sensor). If you wish, you can convert this number into any other representation, but for most applications this will not be needed. To start from a known position, the sensor can be zeroed. Also, if you need to alter its orientation to be in line with its physical mounting, you can invert the readings (to clockwise or counter clockwise).
The physical mounting can take some tinkering. Having a 3D printer available can help a lot. Attaching the magnet can be easy or hard depending on the motor used. If it has a hollow shaft it is quite easy to snug fit the magnet into the shaft using some tape or a 3D printed adapter piece. For other motors, a dab of super glue will do.
Then there is the connecting part. For I2C it’s easy, besides 3.3V and GND, you just need two wires for SDA and SCL. The GPIO pins to use for these can be configured during initialization of the RPS class. The standard chip address (0x40) is set by attaching the A1/A2 address pins both to GND. According to figure 11 in the AS5048 datasheet, for 3.3V operation, you should connect both, the 5V and 3.3V pins of the AS5048 to one of the 3.3V pins of SwarmDrive.
An easy way to test the sensor setup is to just repeatedly call getAngleR() and log its return value to the serial monitor.
printf("angle: %d\n", motor.getAngle());
In your commutation code you can use these angle values to adjust the torque related goal positions of each movement step. We will be covering this in a later update.
Brushed motors have their own mechanical position “sensor” on-board in form of the commutator. For simple movement applications like driving a vacuum cleaner around, a brushed motor would be an easy solution. SwarmDrive can handle a pair of brushed motors too. So, for the next update I plan to do a small write-up on that.
Until next time,