On this page
Generic current sense definition
The CurrentSense base class defines the interface for all current sensing implementations in the SimpleFOClibrary. It is intentionally small and focuses on the minimum requirements needed by the FOC control loop.
Implementations must provide:
init()to configure ADCs, triggers, and calibrationgetPhaseCurrents()to return phase currents in amps
The base class handles DQ transformations, DC current magnitude computation, and alignment helpers.
class CurrentSense {
public:
/** Initialize ADC hardware and synchronization */
virtual int init() = 0;
/** Link current sense to driver (sync if needed) */
void linkDriver(FOCDriver *driver);
/** Read phase currents (A, B, C) */
virtual PhaseCurrent_s getPhaseCurrents() = 0;
/** Read total DC current magnitude (for dc_current torque mode) */
virtual float getDCCurrent(float angle_el = 0);
/** Read d-q currents (for foc_current torque mode) */
DQCurrent_s getFOCCurrents(float angle_el);
/** Align current sense with motor driver */
virtual int driverAlign(float align_voltage, bool modulation_centered = false);
};
Supporting additional current sensing v2.4.0
To add a new current sensing method, extend CurrentSense and implement the required methods.
Step 1. Header file MyCurrentSense.h
#include <SimpleFOC.h>
class MyCurrentSense : public CurrentSense {
public:
MyCurrentSense(...);
// Initialize ADCs and hardware
int init() override;
// Read phase currents in amps
PhaseCurrent_s getPhaseCurrents() override;
};
Step 2. Class implementation file MyCurrentSense.cpp
#include "MyCurrentSense.h"
MyCurrentSense::MyCurrentSense(...) {
// Store pins, gains, or hardware parameters
}
int MyCurrentSense::init() {
// Configure ADCs, GPIOs, DMA, or sampling triggers
// Optionally measure offsets
return 1; // 1 = success, 0 = failure
}
PhaseCurrent_s MyCurrentSense::getPhaseCurrents() {
PhaseCurrent_s c;
c.a = ...; // phase A current [A]
c.b = ...; // phase B current [A]
c.c = ...; // phase C current [A] (set to 0 if not measured)
return c;
}
Step 3. Arduino program
#include <SimpleFOC.h>
#include "MyCurrentSense.h"
// motor + driver
BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 10, 11, 8);
// current sense
MyCurrentSense current_sense = MyCurrentSense(...);
void setup(){
// driver config
driver.voltage_power_supply = 12;
driver.init();
motor.linkDriver(&driver);
// init current sense
current_sense.init();
current_sense.linkDriver(&driver);
motor.linkCurrentSense(¤t_sense);
// enable current control mode
motor.torque_controller = TorqueControlType::foc_current;
// get ready for FOC
motor.init();
motor.initFOC();
}
void loop(){
motor.loopFOC();
motor.move();
}
(Optional) Arduino program - stand-alone current sensing
#include <SimpleFOC.h>
#include "MyCurrentSense.h"
MyCurrentSense current_sense = MyCurrentSense(...);
void setup(){
Serial.begin(115200);
current_sense.init();
}
void loop(){
PhaseCurrent_s currents = current_sense.getPhaseCurrents();
float current_magnitude = current_sense.getDCCurrent();
Serial.print(currents.a);
Serial.print("\t");
Serial.print(currents.b);
Serial.print("\t");
Serial.print(currents.c);
Serial.print("\t");
Serial.println(current_magnitude);
}
Notes and best practices
- Units:
getPhaseCurrents()must return values in amps. - Two shunts: If only two phases are measured, set the third to
0. - Alignment:
initFOC()runs current-sense alignment unlessskip_alignis set. - Synchronization: For low-side or high-side sensing, ensure ADC sampling is synchronized to PWM switching.
For built-in implementations, see:
Inline Current Sense Low-Side Current Sense High-Side Current Sense Generic Current Sense Guide