EncoderManager¶
Owns up to four AS5047U magnetic angle encoders. Vortex V1 has a chip select wired for one encoder
(AS5047U_POSITION_ENCODER, GPIO20) and two external chip selects that can each take another, but no encoder is
created automatically: you create each device. Source: EncoderManager.h.
API¶
| Call | Notes |
|---|---|
CreateAs5047uDevice(index, SpiDeviceId, config = default) |
Creates an encoder on one of the board's chip selects; also an overload taking a BaseSpi& |
DeleteDevice(index) |
Removes it |
ReadAngle(index, uint16_t& counts), ReadAngleDegrees(index, double& deg) |
14-bit angle, or degrees |
ReadVelocityRPM(index, double& rpm) |
Velocity from the sensor |
ReadDiagnostics(index, As5047uDiagnostics&) |
Error flags (one ERRFL read) and the manager's counters |
ReadFieldStrength(index, EncoderFieldStrength&) |
AGC value and CORDIC magnitude: how strong the magnet looks |
SetZeroPosition(index, counts) |
Zero offset |
ReadAllAngles(...), ReadAllVelocities(...), CheckAllDevicesHealth() |
Every active device, under the manager lock |
GetAs5047uHandler(index), VisitDriver(index, fn) |
The handler, or fn(driver) on the typed driver under the manager and handler locks, for chip features the manager does not wrap |
IsDeviceValid, GetActiveDeviceIndices, GetAvailableDevices, GetDeviceType |
Device bookkeeping |
GetLastError(), GetSystemDiagnostics(EncoderSystemDiagnostics&), DumpStatistics() |
Counters and the last error |
Example: create the onboard-slot encoder and read it¶
#include "api/Vortex.h"
#include "managers/EncoderManager.h"
auto& enc = Vortex::GetInstance().encoders;
if (enc.CreateAs5047uDevice(0, SpiDeviceId::AS5047U_POSITION_ENCODER)) {
double deg = 0.0;
if (enc.ReadAngleDegrees(0, deg) == EncoderError::SUCCESS) {
// deg is the shaft angle, 0 to 360
}
}
Pitfalls¶
- Nothing to read until you create a device.
EnsureInitialized()succeeds with zero devices. - SPI2 is shared with the TMC9660 (when on SPI) and the external slots.
- Every read takes the manager lock and the handler lock for the SPI exchange, and so does
VisitDriver(); keep the function you pass short, because it blocks every other encoder call. See Threading. - The TMC9660 can use the same encoder. The position benches feed the AS5047U angle to the host while the TMC9660 uses its own ABN input; decide which side owns the feedback before you close a loop on it.