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: STM3_ESC.h
- Revision:
- 16:d1e4b9ad3b8b
- Parent:
- 14:acaa1add097b
--- a/STM3_ESC.h Sat Nov 30 18:40:30 2019 +0000 +++ b/STM3_ESC.h Tue Jun 09 09:20:19 2020 +0000 @@ -1,48 +1,51 @@ /* STM3_ESC Electronic Speed Controller board, drives Two Brushless Motors, full Four Quadrant Control. Jon Freeman B. Eng Hons - 2015 - 2019 + 2015 - 2020 */ #include "mbed.h" #ifndef MBED_DUALBLS_H #define MBED_DUALBLS_H -//#define USING_DC_MOTORS // Uncomment this to play with Dinosaur DC motors - WARNING deprecated feature +//#define USING_DC_MOTORS // NO LONGER SUPPORTED Uncomment this to play with Dinosaur DC motors - WARNING deprecated feature //#define TEMP_SENSOR_ENABLE // - WARNING deprecated feature, sensor chosen imposed heavy burden on cpu, future looks to simpler analogue type #include "BufferedSerial.h" -const int MOTOR_HANDBRAKE = 0, - MOTOR_FORWARD = 8, - MOTOR_REVERSE = 16, - MOTOR_REGENBRAKE = 24; +const uint32_t MOTOR_HANDBRAKE = 0, + MOTOR_FORWARD = 8, + MOTOR_REVERSE = 16, + MOTOR_REGENBRAKE = 24; -const int TIMEOUT_SECONDS = 2; +const uint32_t TIMEOUT_SECONDS = 2, /* Please Do Not Alter these */ -const int PWM_PRESECALER_DEFAULT = 2, + PWM_PRESECALER_DEFAULT = 2, VOLTAGE_READ_INTERVAL_US = 50, // Interrupts timed every 50 micro sec, runs around loop performing 1 A-D conversion per pass MAIN_LOOP_REPEAT_TIME_US = 31250, // 31250 us, with TACHO_TAB_SIZE = 32 means tacho_ticks_per_time is tacho_ticks_per_second MAIN_LOOP_ITERATION_Hz = 1000000 / MAIN_LOOP_REPEAT_TIME_US, -// CURRENT_SAMPLES_AVERAGED = 100, // Current is spikey. Reading smoothed by using average of this many latest current readings PWM_HZ = 15000, // chosen to be above cutoff frequency of average human ear // PWM_HZ = 8000, // chosen to be above cutoff frequency of average human ear - clearly audible annoying noise MAX_PWM_TICKS = (SystemCoreClock / (PWM_HZ * PWM_PRESECALER_DEFAULT)), - TICKLE_TIMES = 100 , +// TICKLE_TIMES = 100 , + TICKLE_TIMES = 10 , // Massively reduced May 2020 in connection with handbrake implementation. WATCHDOG_RELOAD = (TIMEOUT_SECONDS * 8); // WatchDog counter ticked down in 8Hz loop -/* End of Please Do Not Alter these */ const double PI = 4.0 * atan(1.0), TWOPI = 8.0 * atan(1.0); +/* End of Please Do Not Alter these */ -enum {COM_SOURCES, COM1, COM2, HAND, RC_IN1, RC_IN2,THEEND} ; +enum {COM_SOURCES, COM1, COM2, HAND, RC_IN1, RC_IN2, RC_IN_BOTH, THEEND} ; // RC_IN_BOTH new Dec 2019 -enum {MOTADIR, MOTBDIR, MOTAPOLES, MOTBPOLES, ISHUNTA, ISHUNTB, SVO1, SVO2, RCIN1, RCIN2, + // List user settable firmware bytes in EEROM +enum {MOTADIR, MOTBDIR, MOTAPOLES, MOTBPOLES, ISHUNTA, ISHUNTB, POT_REGBRAKE_RANGE, SVO1, SVO2, RCIN1, RCIN2, COMM_SRC, BOARD_ID, TOP_SPEED, WHEELDIA, MOTPIN, WHEELGEAR, - FUT1, FUT2, FUT3, FUT4, FUT5} ; // These represent address offsets in 24LC64 rom user settable firmware settings + RCI1_TRIM, RCI2_TRIM, RCIN_REGBRAKE_RANGE, RCIN_STICK_ATTACK, // RC in trims new Dec 2019 + RCIN1REVERSE, RCIN2REVERSE, NOM_SYSTEM_VOLTS, BRAKE_EFFECTIVENESS, BAUD, FUT11, + FUT12, FUT13, FUT14, FUT16,} ; // These represent byte address offsets in 24LC64 rom user settable firmware settings -enum { +enum { // List of fault numbers currently dealt with by error handler FAULT_0, FAULT_EEPROM, FAULT_BOARD_ID, @@ -73,26 +76,45 @@ } ; enum {SOURCE_PC, SOURCE_TS} ; -const int BROADCAST = '\r'; -const int MAX_PARAMS = 20; +const int BROADCAST = '\r'; +const int MAX_CLI_PARAMS = 12; const int MAX_CMD_LEN = 220; struct parameters { // Used in serial comms with pc and other controller (e.g. touch-screen) struct kb_command const * command_list; BufferedSerial * com; // pc or com2 int32_t position_in_list, numof_dbls, target_unit, source, numof_menu_items; - double dbl[MAX_PARAMS]; + double dbl[MAX_CLI_PARAMS]; bool respond, resp_always; } ; +enum {ZONE_BRAKE, ZONE_COAST, ZONE_DRIVE} ; +class RC_stick_info { // info read concerning stick positions +public: + double raw, // range 0.0 to 1.0 after clipping and correction + deflection; // how far from centre or min positon + double brake_effort, // braking effort + drive_effort; // driving effort + uint32_t zone; // in drive, coast or braking zone (if drive, direction in 'stick_implied_motor_direction') + uint32_t chan_mode; + int32_t stick_implied_motor_direction; // -1, 0, +1 but could be in drive, coast or brake regions + bool active; + RC_stick_info () { + active = false; + chan_mode = 0; + zone = ZONE_COAST; + drive_effort = brake_effort = 0.0; + } +} ; + class cli_2019 { // cli Command Line Interpreter, two off, 1 for pc comms, other touch-screen controller comms struct kb_command const * commandlist ; - int clindex; - char cmdline[MAX_CMD_LEN + 8]; - char * cmdline_ptr; + uint32_t clindex; + char cmdline[MAX_CMD_LEN + 8]; + char * cmdline_ptr; parameters a ; public: - cli_2019 (BufferedSerial * comport, kb_command const * list, int list_len, int source) { + cli_2019 (BufferedSerial * comport, kb_command const * list, uint32_t list_len, uint32_t source) { a.com = comport ; a.command_list = commandlist = list ; a.numof_menu_items = list_len ; @@ -104,20 +126,24 @@ else a.resp_always = false; } ; - void core () ; - void test () ; + void core () ; + void flush () ; // Used to clear startup transient garbage } ; +const uint32_t MAX_I2C_DEVICES = 6; + class eeprom_settings { I2C i2c; uint32_t errors; uint32_t i2c_device_count; - uint32_t i2c_device_list[12]; // max 12 i2c devices + uint32_t i2c_device_list[MAX_I2C_DEVICES+1]; // max 12 i2c devices char settings [36]; - bool rd_24LC64 (int start_addr, char * dest, int length) ; - bool wr_24LC64 (int start_addr, char * dest, int length) ; + double rpm2mphdbl, user_brake_rangedbl, Vnomdbl, brake_eff, top_speeddbl; + bool rd_24LC64 (uint32_t start_addr, char * dest, uint32_t length) ; + bool wr_24LC64 (uint32_t start_addr, char * dest, uint32_t length) ; bool set_24LC64_internal_address (int start_addr) ; bool ack_poll () ; + void update_dbls () ; public: eeprom_settings (PinName sda, PinName scl); // Constructor bool do_we_have_i2c (uint32_t x) ; @@ -126,10 +152,24 @@ bool save () ; // Write 'settings' buffer to EEPROM bool set_defaults (); // Put default settings into EEPROM and local buffer uint32_t errs () ; // Return errors + const char * t (uint32_t); + uint32_t min (uint32_t) ; + uint32_t max (uint32_t) ; + uint32_t def (uint32_t) ; + bool in_range (char val, uint32_t p) ; + void edit (double * dbl, uint32_t numof_dbls) ; + double user_brake_range () ; + double brake_effectiveness () ; + double top_speed () ; + double Vnom () ; + double rpm2mph () ; + double rpm2mph (double) ; + uint32_t baud (); } ; - - +struct optpar { + int32_t min, max, de_fault; // min, max, default + const char * txt; // description +} ; #endif -