On this page
Full FOC Current Control
⏱️ ~30 minutes
This guide shows how to switch from voltage-based to current-based torque control. This enables precise current limiting and the smoothest motor control.
Read more about FOC current torque mode
Prerequisites
Before starting, make sure you already have:
- Working current sensing setup - Current sense setup guide
- D/Q current visualization working and values are correct
- Motor is stable and responsive in voltage torque mode
What Changes?
| Aspect | Voltage Mode | Current Mode |
|---|---|---|
| Control method | TorqueControlType::voltage | TorqueControlType::foc_current |
| Set target as | Volts (ex. 0-12V) | Amps (ex. 0-5A) |
| Behavior | Torque depends on speed | Torque is direct & predictable |
| Protection | Voltage limits | Current limiting |
Step 1: Switch to current control mode
The change is minimal - just one line in your setup:
// Before (voltage control)
motor.torque_controller = TorqueControlType::voltage;
// After (current control)
motor.torque_controller = TorqueControlType::foc_current;
Take your working code from the current sense setup guide and make this change:
void setup() {
// ... sensor, driver, current sense init ...
// Change this line:
motor.torque_controller = TorqueControlType::foc_current; // ← Was: voltage
motor.controller = MotionControlType::torque;
// Everything else stays the same!
motor.useMonitoring(Serial);
if(!motor.init()) { /* ... */ }
if(!motor.initFOC()) { /* ... */ }
motor.target = 0; // Now in Amps instead of Volts!
// ... rest of setup ...
}
void loop() {
motor.loopFOC();
motor.move();
motor.monitor();
command.run();
}
I using the code from the previous step you can change the torque mode using the Commander interface without re-uploading:
MT2
Step 2: Validate current control
Test that the motor responds correctly to current commands.
Expected behavior
- Motor responds immediately to current commands
- Torque is proportional to the current command (e.g., 0.5A should feel like half the torque of 1A)
- At zero current motor feel like disconnected (no resistance)
- D-axis current stays at 0 the whole time
Validation procedure
- Visualise currents
- Use Arduino Serial Plotter or the serial monitor (should be stable and responsive to commands)
- Set target to zero current:
- Type
M0: Motor should feel free to spin (no resistance). - More or less the same as disconnected.
- Type
- Set small current:
- Type
M0.2: Motor should feel light resistance, - Current \(Iq\) should stabilize around 0.2 Amps in the serial output.
- Type
- Increase current:
- Type
M0.5: Should feel stronger resistance.
- Type
- Try negative current:
- Type
M-0.2: Motor should resist in the opposite direction
- Type
- Let motor spin
- Release motor shaft and set current target:
M0.5 - Motor should accelerate to a certain speed
- Then current drops as motor can’t keep up (this is normal)
- Change current magnitude and direction to observe that
- The higher the current, the higher the acceleration
- The current magnitude does not affect the top speed, just how quickly it gets there
- Release motor shaft and set current target:
- Check D-axis current:
- D-axis current \(Id\) should stay close to zero the whole time
- Back to zero current:
- While motor is spinning, set
M0again - Motor should decelerate and come to the full stop
- It should feel like it’s disconnected again (no resistance)
- While motor is spinning, set
Quick Troubleshooting
Current control feels jerky or unstable?
- Check that
motor.initFOC()completed successfully - Ensure current sensing is working well (from Step 5)
- Reduce serial output frequency (e.g.,
motor.monitor_downsampling = 500;or in commander:MMD500) - If none of the other troubleshooting steps work, the issue are probably PID parameters
- Quick fix: Try lowering
motor.PID_current_q.Pand ``motor.PID_current_q.Pvalues (e.g., 5.0, 3.0, etc.) - using commandeMQP5andMDP5` - For detailed tuning, see the Current loop PID tuning guide
- Quick fix: Try lowering
For more details about FOC control parameters, see the FOC current control mode documentation.
Step 3. Use Velocity or Angle Control with FOC
Now that you have current control working, you can switch to velocity or angle control modes for motion control. The current control will still be active in the background, but now the library will automatically calculate the required current to achieve your velocity or angle targets.
// Switch to velocity control mode
motor.controller = MotionControlType::velocity;
// Switch to angle control mode
motor.controller = MotionControlType::angle;
or you can switch modes on the fly using the Commander interface:
MC1 // Velocity mode
MC2 // Angle mode
MC0 // Torque mode (current control)
Once in these modes, you can set velocity or angle targets as usual (e.g., M100 for 100 rad/s or M3.14 for 180 degrees) and the current control will ensure the motor delivers the required torque to achieve those targets. You will likely need to tune your PID parameters for velocity and angle control to get the best performance, but the current control will provide a solid foundation for smooth and responsive motion.
See the velocity loop tuning guide See the angle loop tuning guide See more practical guides
For general motion control tips, see the motion control documentation
💡 Commander Interface
You can use the Commander interface to easily switch between modes:
MT2- Switch to current control (foc_current)M0.5- Set current target to 0.5 AmpsMC1- Switch to velocity mode - target will be set to 0M100- Set velocity target to 100 rad/sMC2- Switch to angle mode - target will be set to current angleM3.14- Set angle target to 3.14 radians (180 degrees)See the Commander interface guide for more commands.
What’s Next?
You now have a fully functional FOC control system! Depending on your needs:
For Robotics/Automation
- See Motion Control docs
- Implement feedback loops in your application code
For Precision Applications
- Tune PID parameters for your motor
- Use angle mode for position control
- See PID tuning guide
For Learning
- Explore the SimpleFOC library examples
- Read about FOC theory and source code
- For debugging, monitoring, and communication docs, see Communication and Debugging sections