Dual Brushless Motor ESC, 10-62V, up to 50A per motor. Motors ganged or independent, multiple control input methods, cycle-by-cycle current limit, speed mode and torque mode control. Motors tiny to kW. Speed limit and other parameters easily set in firmware. As used in 'The Brushless Brutalist' locomotive - www.jons-workshop.com. See also Model Engineer magazine June-October 2019.
Dependencies: mbed BufferedSerial Servo PCT2075 FastPWM
Update 17th August 2020 Radio control inputs completed
Diff: brushless_motor.cpp
- Revision:
- 13:ef7a06fa11de
- Parent:
- 12:d1d21a2941ef
- Child:
- 14:acaa1add097b
--- a/brushless_motor.cpp Mon Mar 04 17:51:08 2019 +0000
+++ b/brushless_motor.cpp Sun Sep 29 16:34:37 2019 +0000
@@ -1,8 +1,9 @@
// Cloned from 'DualBLS2018_06' on 23 November 2018
#include "mbed.h"
//#include "users/mbed_official/code/mbed-dev/file/707f6e361f3e/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/stm32f401xe.h"
-#include "stm32f401xe.h"
-#include "DualBLS.h"
+//#include "stm32f401xe.h"
+//#include "stm32f411xe.h"
+#include "STM3_ESC.h"
#include "BufferedSerial.h"
#include "FastPWM.h"
#include "Servo.h"
@@ -47,10 +48,10 @@
numof_current_sense_rs = 1.0;
RPM_filter = 0.0;
dv_by_dt = 0.0;
- s[1] = 0.25;
- s[2] = 9.0;
- s[3] = 0.4;
- s[4] = 0.2;
+ sdbl[1] = 0.25; // Remind me. What are these all about ?
+ sdbl[2] = 9.0;
+ sdbl[3] = 0.4;
+ sdbl[4] = 0.2;
dRPM = 0.0;
V_clamp = 1.0 ; // Used to limit top speed
motor_poles = 8; // Default to 8 pole motor
@@ -80,7 +81,7 @@
max_rpm = (uint32_t) (((double)mode.rd(TOP_SPEED) / rpm2mph) / 10.0) ;
target_speed = (double)mode.rd(TOP_SPEED) / 10.0;
numof_current_sense_rs = (double)mode.rd(current_sense_rs_offset);
- pc.printf ("max_rpm=%d, tp speed=%.1f, rpm2mph=%.6f\r\n", max_rpm, target_speed, rpm2mph);
+ pc.printf ("max_rpm=%d, top speed=%.1f, rpm2mph=%.6f\r\n", max_rpm, target_speed, rpm2mph);
}
if (p == 4 || p == 6 || p == 8) {
motor_poles = p;
@@ -152,6 +153,11 @@
}
+extern double Current_Scaler_Sep_2019;
+extern int WatchDog;
+#define DRIVING (visible_mode == MOTOR_FORWARD || visible_mode == MOTOR_REVERSE)
+#define ESTOP (WatchDog == 0 && DRIVING)
+
/**
* void brushless_motor::set_V_limit (double p) // Sets max motor voltage.
*
@@ -159,13 +165,13 @@
*/
void brushless_motor::set_V_limit (double p) // Sets max motor voltage.
{
- if (p < 0.0)
+ if (p < 0.0 || ESTOP)
p = 0.0;
if (p > 1.0)
p = 1.0;
last_V = p; // Retains last voltage limit demanded by driver
- if ((V_clamp < last_V) && (inner_mode == MOTOR_FORWARD || inner_mode == MOTOR_REVERSE)) // Jan 2019 limit top speed when driving
+ if ((V_clamp < last_V) && DRIVING) // Jan 2019 limit top speed when driving
p = V_clamp; // If motor runnable, set voltage limit to lower of last_V and V_clamp
p *= 0.95; // need limit, ffi see MCP1630 data
@@ -173,6 +179,7 @@
maxV.pulsewidth_ticks ((int)(p * MAX_PWM_TICKS)); // PWM output to MCP1630 inverted motor pwm as MCP1630 inverts
}
+
/**void brushless_motor::set_I_limit (double p) // Sets max motor current. pwm integrated to dc ref voltage level
*
* Set motor current limit from zero (p=0.0) to max determined by current sense resistors (p=1.0)
@@ -195,14 +202,22 @@
*
* Board designed to have 1, 2, 3 or 4 0R05 current sense resistors per motor for 10A, 20A, 30A or 40A peak motor currents
*/
+
void brushless_motor::set_I_limit (double p) // Sets max motor current. pwm integrated to dc ref voltage level
{
const uint32_t MPR = ((MAX_PWM_TICKS * 9) / 11); // Scales 3.3v pwm DAC output to 2.7v V_Ref input
- if (p < 0.0)
+ if (p < 0.0 || ESTOP)
p = 0.0;
if (p > 1.0)
p = 1.0;
last_I = p; // Retains last current limit demanded by driver
+ if (DRIVING) {
+ if (Current_Scaler_Sep_2019 > 1.0)
+ Current_Scaler_Sep_2019 = 1.0;
+ if (Current_Scaler_Sep_2019 < 0.0)
+ Current_Scaler_Sep_2019 = 0.0;
+ p *= Current_Scaler_Sep_2019;
+ }
maxI.pulsewidth_ticks ((uint32_t)(p * MPR)); // PWM
}
@@ -226,10 +241,10 @@
#endif
// Feb 2019 - coefficients currently values in ram to allow for tweaking via command line. Will be 'const' once settled upon.
// const double samp_scale = 0.35; // Tweak this value only to tune filter
- double samp_scale = s[1]; // Tweak this value only to tune filter
+ double samp_scale = sdbl[1]; // Tweak this value only to tune filter
double shrink_by = 1.0 - samp_scale;
// const double dv_scale = 0.15;
- double dv_scale = s[3];
+ double dv_scale = sdbl[3];
double dv_shrink = 1.0 - dv_scale;
double speed_error, d, t;
uint32_t Hall_tot_copy = Hall_total; // Copy value for use throughout function as may get changed at any instant during exec !
@@ -253,7 +268,7 @@
if (inner_mode == MOTOR_FORWARD || inner_mode == MOTOR_REVERSE) { // Speed control only makes sense when motor runnable
speed_error = (target_speed - dMPH) / 1000.0; // 'P' Proportional contribution to PID control
- d = V_clamp + (speed_error * s[2]) + ((dv_by_dt / 1000.0) * s[4]); // Apply P+I+D (with I=0) control
+ d = V_clamp + (speed_error * sdbl[2]) + ((dv_by_dt / 1000.0) * sdbl[4]); // Apply P+I+D (with I=0) control
if (d > 1.0) d = 1.0;
if (d < 0.0) d = 0.0;
V_clamp = d;