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
Revision 13:ef7a06fa11de, committed 2019-09-29
- Comitter:
- JonFreeman
- Date:
- Sun Sep 29 16:34:37 2019 +0000
- Parent:
- 12:d1d21a2941ef
- Child:
- 14:acaa1add097b
- Commit message:
- Stable code as at end of 2019 running season
Changed in this revision
--- a/24LC64_eeprom.cpp Mon Mar 04 17:51:08 2019 +0000
+++ b/24LC64_eeprom.cpp Sun Sep 29 16:34:37 2019 +0000
@@ -1,5 +1,5 @@
#include "mbed.h"
-#include "DualBLS.h"
+#include "STM3_ESC.h"
#include "BufferedSerial.h"
extern BufferedSerial pc;
extern error_handling_Jan_2019 ESC_Error ; // Provides array usable to store error codes.
@@ -195,7 +195,7 @@
pc.printf ("in wr_24LC64, device thought good, mem addr write worked, failed writing string\r\n");
return false;
}
- pc.printf ("In wr_24LC64 No Errors Found!\r\n");
+// pc.printf ("In wr_24LC64 No Errors Found!\r\n");
return true;
}
--- a/DualBLS.h Mon Mar 04 17:51:08 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-#include "mbed.h"
-
-#ifndef MBED_DUALBLS_H
-#define MBED_DUALBLS_H
-
-//#define USING_DC_MOTORS // Uncomment this to play with Dinosaur DC motors
-
-#include "BufferedSerial.h"
-const int MOTOR_HANDBRAKE = 0,
- MOTOR_FORWARD = 8,
- MOTOR_REVERSE = 16,
- MOTOR_REGENBRAKE = 24;
-
-const int TIMEOUT_SECONDS = 2;
-
-/* Please Do Not Alter these */
-const int 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 ,
- 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);
-
-enum {COM_SOURCES, COM1, COM2, HAND, RC_IN1, RC_IN2,THEEND} ;
-
-enum {MOTADIR, MOTBDIR, MOTAPOLES, MOTBPOLES, ISHUNTA, ISHUNTB, SVO1, SVO2, RCIN1, RCIN2,
- COMM_SRC, BOARD_ID, TOP_SPEED, WHEELDIA, MOTPIN, WHEELGEAR,
- FUT1, FUT2, FUT3, FUT4, FUT5} ; //
-
-enum {
- FAULT_0,
- FAULT_EEPROM,
- FAULT_BOARD_ID,
- FAULT_COM_LINE_LEN,
- FAULT_COM_LINE_NOMATCH,
- FAULT_COM_LINE_LEN_PC,
- FAULT_COM_LINE_LEN_TS,
- FAULT_COM_LINE_NOMATCH_PC,
- FAULT_COM_LINE_NOMATCH_TS,
- FAULT_UNRECOGNISED_STATE,
- FAULT_MAX,
- NUMOF_REPORTABLE_TS_ERRORS
- } ;
-
-class error_handling_Jan_2019
-{
- int32_t ESC_fault[NUMOF_REPORTABLE_TS_ERRORS] ; // Some number of reportable error codes, accessible through set and read members
- public:
- error_handling_Jan_2019 () { // default constructor
- for (int i = 0; i < (sizeof(ESC_fault) / sizeof(int32_t)); i++)
- ESC_fault[i] = 0;
- }
- void set (uint32_t, int32_t) ;
- void clr (uint32_t) ;
- uint32_t read (uint32_t) ;
- bool all_good () ;
- void report_any (bool) ; // retain ? true or false
-} ;
-
-enum {SOURCE_PC, SOURCE_TS} ;
-const int BROADCAST = '\r';
-const int MAX_PARAMS = 20;
-const int MAX_CMD_LEN = 220;
-
-struct parameters {
- 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];
- bool respond, resp_always;
-} ;
-
-class cli_2019 {
- struct kb_command const * commandlist ;
- int 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) {
- a.com = comport ;
- a.command_list = commandlist = list ;
- a.numof_menu_items = list_len ;
- a.source = source ;
- cmdline_ptr = cmdline;
- clindex = 0;
- if (source == SOURCE_PC)
- a.resp_always = true;
- else
- a.resp_always = false;
- } ;
- void core () ;
- void test () ;
-} ;
-
-class eeprom_settings {
- I2C i2c;
- uint32_t errors;
- char settings [36];
- bool rd_24LC64 (int start_addr, char * dest, int length) ;
- bool wr_24LC64 (int start_addr, char * dest, int length) ;
- bool set_24LC64_internal_address (int start_addr) ;
- bool ack_poll () ;
- public:
- eeprom_settings (PinName sda, PinName scl); // Constructor
- char rd (uint32_t) ; // Read one setup char value from private buffer 'settings'
- bool wr (char, uint32_t) ; // Write one setup char value to private buffer 'settings'
- bool save () ; // Write 'settings' buffer to EEPROM
- bool set_defaults (); // Put default settings into EEPROM and local buffer
- uint32_t errs () ; // Return errors
-} ;
-
-
-
-
-#endif
-
--- a/F401RE.h Mon Mar 04 17:51:08 2019 +0000 +++ b/F401RE.h Sun Sep 29 16:34:37 2019 +0000 @@ -1,3 +1,4 @@ +#include "STM3_ESC.h" // Feb 2018 Now using DGD21032 mosfet drivers via 74HC00 pwm gates (low side) - GOOD, works well with auto-tickle of high side drivers // Jan 2019 Trying to add two Radio Control inputs on PC_14 and PC_15, previously connected to unused LF Xtal. @@ -71,8 +72,9 @@ // Pin 1 VBAT NET +3V3 //DigitalIn J3 (PC_13, PullUp);// Pin 2 Jumper pulls to GND, R floats Hi +#ifdef TEMP_SENSOR_ENABLE InterruptIn Temperature_pin (PC_13);// Pin 2 June 2018 - taken for temperature sensor - hard wired to T1 due to wrong thought T1 could be InterruptIn - +#endif // Pin 3 PC14-OSC32_IN NET O32I Xtal chucked off these pins, now needed for RC inputs // Pin 4 PC15-OSC32_OUT NET O32O
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/F411RE.h Sun Sep 29 16:34:37 2019 +0000
@@ -0,0 +1,187 @@
+#include "STM3_ESC.h"
+// Feb 2018 Now using DGD21032 mosfet drivers via 74HC00 pwm gates (low side) - GOOD, works well with auto-tickle of high side drivers
+
+// Jan 2019 Trying to add two Radio Control inputs on PC_14 and PC_15, previously connected to unused LF Xtal.
+// Problem - Appears to conflict with serial port used for comms with controller
+// Earlier efforts to use 'Servo' ports as 'you choose' between I/O failed as pins not capable of use as 'InterruptIn'
+
+// CORRECTION Comms problem with Touch Screen was insufficient pull-up on STM3_ESC opto. Change R12 from 1k to 470R
+
+// Experiment disabling RC inputs to see if clearing serial conflict is possible
+
+
+// Port A -> MotorA, Port B -> MotorB
+const uint16_t
+// This is where port bits get assigned to motor output phase switches.
+// Phases are U, V and W.
+// Each phase uses two bits, one for the low side switch, one for the high side switch.
+//MotorN_port_bits[] = {UL, VL, WL, UH, VH, WH}, // Order must be as shown - 3 low side switches U,V,W followed by 3 high side switches U,V,W
+MotorA_port_bits[] = {0, 6, 4, 1, 7, 8}, // List of port A bits used to drive motor A UL, VL, WL, UH, VH, WH
+MotorB_port_bits[] = {0, 1, 2, 10, 12, 13}, // List of port B bits used to drive motor B UL, VL, WL, UH, VH, WH
+// Using port bit info in the two lines above, the compiler sorts all this into creation of lookup table
+// to provide correct energisation sequencing as motors rotate.
+// You need concern yourself no further about any of this.
+
+
+AUL = (1 << MotorA_port_bits[0]),
+AVL = (1 << MotorA_port_bits[1]), // These are which port bits connect to which mosfet driver
+AWL = (1 << MotorA_port_bits[2]),
+
+AUH = (1 << MotorA_port_bits[3]),
+AVH = (1 << MotorA_port_bits[4]),
+AWH = (1 << MotorA_port_bits[5]),
+
+AUHVL = AUH | AVL, // Each of 6 possible output energisations made up of one hi and one low
+AVHUL = AVH | AUL,
+AUHWL = AUH | AWL,
+AWHUL = AWH | AUL,
+AVHWL = AVH | AWL,
+AWHVL = AWH | AVL,
+
+KEEP_L_MASK_A = AUL | AVL | AWL,
+KEEP_H_MASK_A = AUH | AVH | AWH,
+
+BRA = AUL | AVL | AWL, // All low side switches on (and all high side off) for braking
+
+BUL = (1 << MotorB_port_bits[0]), // Likewise for MotorB but different port bits on different port
+BVL = (1 << MotorB_port_bits[1]),
+BWL = (1 << MotorB_port_bits[2]),
+
+BUH = (1 << MotorB_port_bits[3]),
+BVH = (1 << MotorB_port_bits[4]),
+BWH = (1 << MotorB_port_bits[5]),
+
+BUHVL = BUH | BVL,
+BVHUL = BVH | BUL,
+BUHWL = BUH | BWL,
+BWHUL = BWH | BUL,
+BVHWL = BVH | BWL,
+BWHVL = BWH | BVL,
+
+KEEP_L_MASK_B = BUL | BVL | BWL,
+KEEP_H_MASK_B = BUH | BVH | BWH,
+
+BRB = BUL | BVL | BWL,
+
+PORT_A_MASK = AUL | AVL | AWL | AUH | AVH | AWH, // NEW METHOD FOR DGD21032 MOSFET DRIVERS
+PORT_B_MASK = BUL | BVL | BWL | BUH | BVH | BWH;
+
+//PortOut MotA (PortA, PORT_A_MASK); // Activate output ports to motor drivers
+//PortOut MotB (PortB, PORT_B_MASK);
+
+// Pin 1 VBAT NET +3V3
+
+//DigitalIn J3 (PC_13, PullUp);// Pin 2 Jumper pulls to GND, R floats Hi
+#ifdef TEMP_SENSOR_ENABLE
+InterruptIn Temperature_pin (PC_13);// Pin 2 June 2018 - taken for temperature sensor - hard wired to T1 due to wrong thought T1 could be InterruptIn
+#endif
+
+// Pin 3 PC14-OSC32_IN NET O32I Xtal chucked off these pins, now needed for RC inputs
+// Pin 4 PC15-OSC32_OUT NET O32O
+// Pin 5 PH0-OSC_IN NET PH1
+// Pin 6 PH1-OSC_OUT NET PH1
+// Pin 7 NRST NET NRST
+AnalogIn Ain_DriverPot (PC_0); // Pin 8 Spare Analogue in, net SAIN fitted with external pull-down
+AnalogIn Ain_SystemVolts (PC_1); // Pin 9
+#define MOT_A_I_ADC PC_2
+#define MOT_B_I_ADC PC_3
+//AnalogIn Motor_A_Current (PC_2); // Pin 10
+//AnalogIn Motor_B_Current (PC_3); // Pin 11
+// Pin 12 VSSA/VREF- NET GND
+// Pin 13 VDDA/VREF+ NET +3V3
+// Pin 14 Port_A AUL
+// Pin 15 Port_A AUH
+// Pins 16, 17 BufferedSerial pc
+BufferedSerial pc (PA_2, PA_3, 2048, 4, NULL); // Pins 16, 17 tx, rx to pc via usb lead
+// Pin 18 VSS NET GND
+// Pin 19 VDD NET +3V3
+// Pin 20 Port_A AWL
+// Pin 21 DigitalOut led1(LED1);
+DigitalOut LED (PA_5); // Pin 21
+// Pin 22 Port_A AVL
+// Pin 23 Port_A AVH
+//InterruptIn MBH2 (PC_4); // Pin 24
+//InterruptIn MBH3 (PC_5); // Pin 25
+#define _MBH2 PC_4
+#define _MBH3 PC_5
+// Pin 26 Port_B BUL
+// Pin 27 Port_B BVL
+// Pin 28 Port_B BWL
+// Pin 29 Port_B BUH
+// Pin 30 VCAP1
+// Pin 31 VSS
+// Pin 32 VDD
+// Pin 33 Port_B BVH
+// Pin 34 Port_B BWH
+DigitalOut T4 (PB_14); // Pin 35
+DigitalOut T3 (PB_15); // Pin 36
+// BufferedSerial com2 pins 37 Tx, 38 Rx
+BufferedSerial com2 (PC_6, PC_7); // Pins 37, 38 tx, rx to Touch Screen Controller
+#define APWMV PC_8
+#define APWMI PC_9
+//FastPWM A_MAX_V_PWM (PC_8, PWM_PRESECALER_DEFAULT), // Pin 39 pwm3/3
+// A_MAX_I_PWM (PC_9, PWM_PRESECALER_DEFAULT); // pin 40, prescaler value pwm3/4
+//InterruptIn MotB_Hall (PA_8); // Pin 41
+// Pin 41 Port_A AWH
+// BufferedSerial com3 pins 42 Tx, 43 Rx
+//InterruptIn tryseredge (PA_9);
+BufferedSerial com3 (PA_9, PA_10); // Pins 42, 43 tx, rx to any aux module
+// PA_9 is Tx. I wonder, can we also use InterruptIn on this pin to generate interrupts on tx bit transitions ? Let's find out !
+// No.
+
+// Feb 2018 Pins 44 and 45 now liberated, could use for serial or other uses
+//BufferedSerial extra_ser (PA_11, PA_12); // Pins 44, 45 tx, rx to XBee module
+DigitalOut T2 (PA_11); // Pin 44
+// was DigitalOut T1 (PA_12); // Pin 45
+
+
+//InterruptIn T1 (PA_12); // Pin 45 now input counting pulses from LMT01 temperature sensor
+// InterruptIn DOES NOT WORK ON PA_12. Boards are being made, will have to wire link PA12 to PC13
+DigitalIn T1 (PA_12);
+////InterruptIn T1 (PC_13); // Pin 45 now input counting pulses from LMT01 temperature sensor
+
+
+
+// Pin 46 SWDIO
+// Pin 47 VSS
+// Pin 48 VDD
+// Pin 49 SWCLK
+
+//Was DigitalOut T5 (PA_15); // Pin 50
+DigitalIn T5 (PA_15); // Pin 50 now fwd/rev from remote control box if fitted
+#define _MAH1 PC_10 // Pin 51
+#define _MAH2 PC_11 // Pin 52
+#define _MAH3 PC_12 // Pin 53
+//InterruptIn MBH1 (PD_2); // Pin 54
+#define _MBH1 PD_2
+DigitalOut T6 (PB_3); // Pin 55
+#define BPWMV PB_4
+#define BPWMI PB_5
+//FastPWM B_MAX_V_PWM (PB_4, PWM_PRESECALER_DEFAULT), // Pin 56 pwm3/3
+// B_MAX_I_PWM (PB_5, PWM_PRESECALER_DEFAULT); // pin 57, prescaler value pwm3/4
+
+//I2C i2c (PB_7, PB_6); // Pins 58, 59 For 24LC64 eeprom
+#define SDA_PIN PB_7
+#define SCL_PIN PB_6
+// Pin 60 BOOT0
+
+// Servo pins, 2 off. Configured as Input to read radio control receiver
+// ** Update December 2018 **
+// These pins can not be used as InterruptIn.
+// Can be used as outputs by 'Servo'
+// If used as servo output, code gives pin to 'Servo' - seems to work
+//InterruptIn Servo1_i (PB_8); // Pin 61 to read output from rc rx
+//InterruptIn Servo2_i (PB_9); // Pin 62 to read output from rc rx
+// *** NOTE *** Above InterruptIn Servo using PB pins seems not to work, probably due to other Port B pins used as PortOut (try PortInOut?)
+// Nov 2018 - Yet to try using PC14, PC15, free now as 32k768 xtal not fitted
+
+
+// Pin 63 VSS
+// Pin 64 VDD
+// SYSTEM CONSTANTS
+// December 2018 ** NEED TO PROVE SERVO OUT WORKS ** YES, DONE.
+ Servo Servo1 (PB_8) ;
+// Servos[0] = & Servo1;
+ Servo Servo2 (PB_9) ;
+// Servos[1] = & Servo2;
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM3_ESC.h Sun Sep 29 16:34:37 2019 +0000
@@ -0,0 +1,127 @@
+#include "mbed.h"
+
+#ifndef MBED_DUALBLS_H
+#define MBED_DUALBLS_H
+
+//#define USING_DC_MOTORS // Uncomment this to play with Dinosaur DC motors
+
+//#define TEMP_SENSOR_ENABLE //
+
+#include "BufferedSerial.h"
+const int MOTOR_HANDBRAKE = 0,
+ MOTOR_FORWARD = 8,
+ MOTOR_REVERSE = 16,
+ MOTOR_REGENBRAKE = 24;
+
+const int TIMEOUT_SECONDS = 2;
+
+/* Please Do Not Alter these */
+const int 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 ,
+ 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);
+
+enum {COM_SOURCES, COM1, COM2, HAND, RC_IN1, RC_IN2,THEEND} ;
+
+enum {MOTADIR, MOTBDIR, MOTAPOLES, MOTBPOLES, ISHUNTA, ISHUNTB, SVO1, SVO2, RCIN1, RCIN2,
+ COMM_SRC, BOARD_ID, TOP_SPEED, WHEELDIA, MOTPIN, WHEELGEAR,
+ FUT1, FUT2, FUT3, FUT4, FUT5} ; //
+
+enum {
+ FAULT_0,
+ FAULT_EEPROM,
+ FAULT_BOARD_ID,
+ FAULT_COM_LINE_LEN,
+ FAULT_COM_LINE_NOMATCH,
+ FAULT_COM_LINE_LEN_PC,
+ FAULT_COM_LINE_LEN_TS,
+ FAULT_COM_LINE_NOMATCH_PC,
+ FAULT_COM_LINE_NOMATCH_TS,
+ FAULT_UNRECOGNISED_STATE,
+ FAULT_MAX,
+ NUMOF_REPORTABLE_TS_ERRORS
+ } ;
+
+class error_handling_Jan_2019
+{
+ int32_t ESC_fault[NUMOF_REPORTABLE_TS_ERRORS] ; // Some number of reportable error codes, accessible through set and read members
+ public:
+ error_handling_Jan_2019 () { // default constructor
+ for (int i = 0; i < (sizeof(ESC_fault) / sizeof(int32_t)); i++)
+ ESC_fault[i] = 0;
+ }
+ void set (uint32_t, int32_t) ;
+ void clr (uint32_t) ;
+ uint32_t read (uint32_t) ;
+ bool all_good () ;
+ void report_any (bool) ; // retain ? true or false
+} ;
+
+enum {SOURCE_PC, SOURCE_TS} ;
+const int BROADCAST = '\r';
+const int MAX_PARAMS = 20;
+const int MAX_CMD_LEN = 220;
+
+struct parameters {
+ 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];
+ bool respond, resp_always;
+} ;
+
+class cli_2019 {
+ struct kb_command const * commandlist ;
+ int 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) {
+ a.com = comport ;
+ a.command_list = commandlist = list ;
+ a.numof_menu_items = list_len ;
+ a.source = source ;
+ cmdline_ptr = cmdline;
+ clindex = 0;
+ if (source == SOURCE_PC)
+ a.resp_always = true;
+ else
+ a.resp_always = false;
+ } ;
+ void core () ;
+ void test () ;
+} ;
+
+class eeprom_settings {
+ I2C i2c;
+ uint32_t errors;
+ char settings [36];
+ bool rd_24LC64 (int start_addr, char * dest, int length) ;
+ bool wr_24LC64 (int start_addr, char * dest, int length) ;
+ bool set_24LC64_internal_address (int start_addr) ;
+ bool ack_poll () ;
+ public:
+ eeprom_settings (PinName sda, PinName scl); // Constructor
+ char rd (uint32_t) ; // Read one setup char value from private buffer 'settings'
+ bool wr (char, uint32_t) ; // Write one setup char value to private buffer 'settings'
+ bool save () ; // Write 'settings' buffer to EEPROM
+ bool set_defaults (); // Put default settings into EEPROM and local buffer
+ uint32_t errs () ; // Return errors
+} ;
+
+
+
+
+#endif
+
--- 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;
--- a/brushless_motor.h Mon Mar 04 17:51:08 2019 +0000
+++ b/brushless_motor.h Sun Sep 29 16:34:37 2019 +0000
@@ -6,7 +6,7 @@
#define MBED_BRUSHLESSMOTOR_H
#include "mbed.h"
-#include "DualBLS.h"
+#include "STM3_ESC.h"
#include "FastPWM.h"
class brushless_motor
@@ -15,7 +15,7 @@
uint32_t Hall_index[2], encoder_error_cnt, motor_poles, current_sense_rs_offset;
uint32_t Hall_total, // Incremented on every Hall sensor transition
Hall_previous,
- visible_mode,
+ visible_mode, // One of MOTOR_HANDBRAKE, MOTOR_FORWARD, MOTOR_REVERSE, MOTOR_REGENBRAKE
inner_mode;
uint32_t direction;
int temp_tick;
@@ -39,7 +39,10 @@
uint32_t tickleon;
double Idbl;
double last_V, last_I;
- double dRPM, dMPH, s[8];
+ double dRPM, dMPH,
+ sdbl[8]; // Filter coefficients for filtering RPM and MPH reading stuff, I think!
+ // Used in brushless_motor::speed_monitor_and_control ()
+
// brushless_motor () {} ; // can not use this with exotic elements PortOut, FastPWM etc
brushless_motor (PinName iadc, PinName pwv, PinName pwi, const uint16_t *, PinName h1, PinName h2, PinName h3, PortName, int, uint32_t) ; // Constructor
bool poles (int) ; // Set number of motor poles - 4, 6, or 8
--- a/cli_BLS_nortos.cpp Mon Mar 04 17:51:08 2019 +0000
+++ b/cli_BLS_nortos.cpp Sun Sep 29 16:34:37 2019 +0000
@@ -18,7 +18,7 @@
// Brushless_STM3_Ctrl_2018_11
#include "mbed.h"
#include "BufferedSerial.h"
-#include "DualBLS.h"
+#include "STM3_ESC.h"
#include "brushless_motor.h"
#include <cctype>
@@ -26,8 +26,8 @@
extern eeprom_settings mode ;
extern error_handling_Jan_2019 ESC_Error ; // Provides array usable to store error codes.
-extern int WatchDog;
-extern bool WatchDogEnable;
+extern int WatchDog; // from main
+extern bool WatchDogEnable; // from main
extern double rpm2mph ;
extern brushless_motor MotorA, MotorB; // Controlling two motors together or individually
@@ -202,9 +202,9 @@
break;
case 2: // MotorA_ current sense resistors [1 to 4], MotorB_ current sense resistors [1 to 4]
if (temps[1] > 0 && temps[1] < 5)
- mode.wr(temps[1], MOTADIR);
+ mode.wr(temps[1], ISHUNTA); // Corrected since published
if (temps[2] > 0 && temps[2] < 5)
- mode.wr(temps[2], MOTBDIR);
+ mode.wr(temps[2], ISHUNTB);
break;
case 3: // 2 Servo1 [0 or 1], Servo2 [0 or 1]
if (temps[1] == 0 || temps[1] == 1)
@@ -265,6 +265,16 @@
}
+
+void ssl_cmd (struct parameters & a) { // set speed limit NEW and untested July 2019
+ if (a.dbl[0] > 25.0) a.dbl[0] = 25.0;
+ if (a.dbl[0] < 1.0) a.dbl[0] = 1.0;
+ mode.wr((char)(a.dbl[0] * 10.0), TOP_SPEED);
+ mode.save ();
+}
+
+#ifdef TEMP_SENSOR_ENABLE
+
extern uint32_t last_temperature_count;
/**
* void temperature_cmd (struct parameters & a) {
@@ -275,6 +285,7 @@
a.com->printf ("tem%c %d\r\n", mode.rd(BOARD_ID), (last_temperature_count / 16) - 50);
}
}
+#endif
/**
*void rpm_cmd (struct parameters & a) // to report e.g. RPM 1000 1000 ; speed for both motors
@@ -352,6 +363,10 @@
/**
*void kd_cmd (struct parameters & a) // kick and enable the watch dog
*
+* Brute_TS_Controller or other external controller to issue regular 'kd\r' to come here.
+* WatchDog disabled by default, enabled on first call to here
+* This is where WatchDog timer is reset and reloaded.
+* Timeout may be detected and handled in 8Hz loop in main programme loop
*/
void kd_cmd (struct parameters & a) // kick the watchdog. Reached from TS or pc.
{
@@ -359,6 +374,10 @@
WatchDogEnable = true; // Receipt of this command sufficient to enable watchdog
}
+void wd_report (struct parameters & a) // Reachable always from pc. Only addressed board responds to TS
+{
+ pc.printf ("WatchDog %d\r\n", WatchDog);
+}
/**
*void who_cmd (struct parameters & a) // Reachable always from pc. Only addressed board responds to TS
*
@@ -386,16 +405,16 @@
{
switch ((int)a.dbl[0]) {
case 1:
- MotorA.s[1] = MotorB.s[1] = a.dbl[1];
+ MotorA.sdbl[1] = MotorB.sdbl[1] = a.dbl[1];
break;
case 2:
- MotorA.s[2] = MotorB.s[2] = a.dbl[1];
+ MotorA.sdbl[2] = MotorB.sdbl[2] = a.dbl[1];
break;
case 3:
- MotorA.s[3] = MotorB.s[3] = a.dbl[1];
+ MotorA.sdbl[3] = MotorB.sdbl[3] = a.dbl[1];
break;
case 4:
- MotorA.s[4] = MotorB.s[4] = a.dbl[1];
+ MotorA.sdbl[4] = MotorB.sdbl[4] = a.dbl[1];
break;
case 5:
MotorA.set_speed (a.dbl[1]);
@@ -404,11 +423,12 @@
default:
pc.printf ("Wrong use of scmd %f\r\n", a.dbl[0]);
}
+ pc.printf ("Filter Coefficient Fiddler - used in brushless_motor::speed_monitor_and_control ()");
pc.printf ("Filter Coeffs 1 to 4\r\n");
- pc.printf ("1 %.3f\tPscale 0.01-0.5\r\n", MotorA.s[1]);
- pc.printf ("2 %.3f\tP_gain 1.0-1000.0\r\n", MotorA.s[2]);
- pc.printf ("3 %.3f\tDscale 0.01-0.5\r\n", MotorA.s[3]);
- pc.printf ("4 %.3f\tD_gain 1.0-1000.0\r\n", MotorA.s[4]);
+ pc.printf ("1 %.3f\tPscale 0.01-0.5\r\n", MotorA.sdbl[1]);
+ pc.printf ("2 %.3f\tP_gain 1.0-1000.0\r\n", MotorA.sdbl[2]);
+ pc.printf ("3 %.3f\tDscale 0.01-0.5\r\n", MotorA.sdbl[3]);
+ pc.printf ("4 %.3f\tD_gain 1.0-1000.0\r\n", MotorA.sdbl[4]);
pc.printf ("5 Set target_speed\r\n");
}
@@ -456,8 +476,11 @@
{"?v", "Report system bus voltage", sysV_report},
{"?i", "Report motor both currents", sysI_report},
{"who", "search for connected units, e.g. 3who returs 'who3' if found", who_cmd},
+#ifdef TEMP_SENSOR_ENABLE
{"tem", "report temperature", temperature_cmd},
+#endif
{"mph", "read loco speed miles per hour", mph_cmd},
+ {"ssl", "set speed limit e.g. 10.7", ssl_cmd}, // NEW July 2019
// {"rvi", "read most recent values sent to pwms", rvi_cmd},
// {"rdi", "read motor currents and power voltage", rdi_cmd},
// ***** Endof
@@ -474,7 +497,7 @@
#ifdef USING_DC_MOTORS
{"mtypes", "report types of motors found", mt_cmd},
#endif
- {"s","1-4, filter param", scmd},
+ {"s","1-4, RPM and speed filter param", scmd},
{"pot", "read drivers control pot", pot_cmd},
{"fw", "forward", fw_cmd},
{"re", "reverse", re_cmd},
@@ -485,10 +508,14 @@
{"vi", "set motors V and I percent RANGE 0 to 100", vi_cmd},
{"?v", "Report system bus voltage", sysV_report},
{"?i", "Report motor both currents", sysI_report},
+ {"?w", "show WatchDog timer contents", wd_report},
{"who", "search for connected units, e.g. 3who returs 'who3' if found", who_cmd},
{"mode", "read or set params in eeprom", mode19_cmd}, // Big change Jan 2019
+ {"ssl", "set speed limit e.g. 10.7", ssl_cmd}, // NEW July 2019 ONLY HERE FOR TEST, normal use is from Touch Screen only.
// {"erase", "set eeprom contents to all 0xff", erase_cmd},
+#ifdef TEMP_SENSOR_ENABLE
{"tem", "report temperature", temperature_cmd}, // Reports -50 when sensor not fitted
+#endif
{"kd", "kick the dog, reloads WatchDog", kd_cmd},
{"ver", "Version", ver_cmd},
{"rcin", "Report Radio Control Input stuff", rcin_pccmd},
--- a/error_handler.cpp Mon Mar 04 17:51:08 2019 +0000 +++ b/error_handler.cpp Sun Sep 29 16:34:37 2019 +0000 @@ -1,5 +1,5 @@ #include "mbed.h" -#include "DualBLS.h" +#include "STM3_ESC.h" #include "BufferedSerial.h" extern BufferedSerial pc;
--- a/main.cpp Mon Mar 04 17:51:08 2019 +0000
+++ b/main.cpp Sun Sep 29 16:34:37 2019 +0000
@@ -1,29 +1,34 @@
-// Cloned from 'DualBLS2018_06' on 23 November 2018
+/*
+ STM3_ESC Electronic Speed Controller board, drives Two Brushless Motors, full Four Quadrant Control.
+ Jon Freeman B. Eng Hons
+ 2015 - 2019
+*/
#include "mbed.h"
-//#include "users/mbed_official/code/mbed-dev/file/707f6e361f3e/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/stm32f401xe.h"
-#include "DualBLS.h"
-
-#include "stm32f401xe.h"
+#include "STM3_ESC.h"
#include "BufferedSerial.h"
#include "FastPWM.h"
#include "Servo.h"
#include "brushless_motor.h"
#include "Radio_Control_In.h"
+//#ifdef TARGET_NUCLEO_F401RE //
+//#endif
/*
-Brushless_STM3 board
+Brushless_STM3_ESC board
Jan 2019 * WatchDog implemented. Default is disabled, 'kd' command from TS controller enables and reloads
* Tidied brushless_motor class, parameter passing now done properly
* class RControl_In created. Inputs now routed to new pins, can now use two chans both class RControl_In and Servo out
- (buggery board required for new inputs)
+ (buggery board required for new inputs on June 2018 issue boards)
* Added version string
* Error handler written and included
* Realised Nanotec motors are 6 pole, all others are 8 pole. Modified 'mode' to include 'motor poles' in EEPROM data, now speed reading correct for all
* Reorganised EEPROM data - mode setting now much easier, less error prone
- * Maximum speed now one EEPROM option, range 1.0 to 25.0 MPH
+ * Maximum speed now one EEPROM option, range 1.0 to 25.0 MPH in 0.1 MPH steps
New 29th May 2018 **
LMT01 temperature sensor routed to T1 - and rerouted to PC_13 as InterruptIn on T1 (ports A and B I think) not workable
+ March 2019 temp sensor only included with TEMP_SENSOR_ENABLE defined. Temp reading not essential, LMT01 was not a good choice due to
+ significant loading of interrupts, threatening integrity of Real Time System
*/
@@ -34,7 +39,7 @@
____________________________________________________________________________________
CONTROL PHILOSOPHY
-This Bogie drive board software should ensure sensible control when commands supplied are not sensible !
+This STM3_ESC Bogie drive board software should ensure sensible control when commands supplied are not sensible !
That is, smooth transition between Drive, Coast and Brake to be implemented here.
The remote controller must not be relied upon to deliver sensible command sequences.
@@ -49,17 +54,21 @@
#if defined (TARGET_NUCLEO_F401RE) // CPU in 64 pin LQFP
#include "F401RE.h" // See here for warnings about Servo InterruptIn not working
#endif
+#if defined (TARGET_NUCLEO_F411RE) // CPU in 64 pin LQFP
+#include "F411RE.h" // See here for warnings about Servo InterruptIn not working
+#endif
#if defined (TARGET_NUCLEO_F446ZE) // CPU in 144 pin LQFP
#include "F446ZE.h" // A thought for future version
#endif
/* Global variable declarations */
-char const const_version_string[] = {"1.0.0\0"}; // Version string, readable from serial ports
+char const_version_string[] = {"1.0.y2019.m09.d29\0"}; // Version string, readable from serial ports
volatile uint32_t fast_sys_timer = 0; // gets incremented by our Ticker ISR every VOLTAGE_READ_INTERVAL_US
-int WatchDog = WATCHDOG_RELOAD + 80; // Allow extra few seconds at powerup
+//int WatchDog = WATCHDOG_RELOAD + 80; // Allow extra few seconds at powerup
+int WatchDog = 0; // Set this up in main once pre-flight checks done. Allow extra few seconds at powerup
bool WatchDogEnable = false; // Must recieve explicit instruction from pc or controller to enable
uint32_t volt_reading = 0, // Global updated by interrupt driven read of Battery Volts
driverpot_reading = 0, // Global updated by interrupt driven read of Drivers Pot
- sys_timer = 0, // gets incremented by our Ticker ISR every MAIN_LOOP_REPEAT_TIME_US
+ sys_timer = 0, // gets incremented by our Ticker ISR every MAIN_LOOP_REPEAT_TIME_US, 31250us at Sept 2019
AtoD_Semaphore = 0;
bool loop_flag = false; // made true in ISR_loop_timer, picked up and made false again in main programme loop
@@ -67,15 +76,24 @@
bool temp_sensor_exists = false;
double rpm2mph;
+double Current_Scaler_Sep_2019 = 1.0; // New idea - Sept 2019. Plan is to scale down motor current limit when voltage lower than nom.
+ // See schematic for full details, but cycle-by-cycle current limit has the effect of allowing larger average I
+ // at lower voltages. This is simply because current takes longer to build in motor inductance when voltage
+ // is low. Conversely, at high supply voltages, motor current reaches limit quickly, cutting drive, meaning
+ // similar current flows for shorter times at higher voltages.
+
+#ifdef TEMP_SENSOR_ENABLE
uint32_t temp_sensor_count = 0, // incremented by every rising edge from LMT01
last_temperature_count = 0; // global updated approx every 100ms after each LMT01 conversion completes
+#endif
/* End of Global variable declarations */
Ticker tick_vread; // Device to cause periodic interrupts, used to time voltage readings etc
Ticker loop_timer; // Device to cause periodic interrupts, used to sync iterations of main programme loop
+#ifdef TEMP_SENSOR_ENABLE
Ticker temperature_find_ticker;
Timer temperature_timer;
-
+#endif
#ifdef USING_DC_MOTORS
Timer dc_motor_kicker_timer;
Timeout motors_restore;
@@ -127,6 +145,7 @@
extern cli_2019 pcc, tsc; // command line interpreters from pc and touch screen
// Interrupt Service Routines
+#ifdef TEMP_SENSOR_ENABLE
void ISR_temperature_find_ticker () // every 960 us, i.e. slightly faster than once per milli sec
{
static bool readflag = false;
@@ -139,7 +158,7 @@
if (t == 6)
readflag = false;
}
-
+#endif
/** void ISR_loop_timer ()
* This ISR responds to Ticker interrupts at a rate of (probably) 32 times per second (check from constant declarations above)
* This ISR sets global flag 'loop_flag' used to synchronise passes around main programme control loop.
@@ -164,6 +183,7 @@
fast_sys_timer++; // Just a handy measure of elapsed time for anything to use
}
+#ifdef TEMP_SENSOR_ENABLE
void temp_sensor_isr () // got rising edge from LMT01. ALMOST CERTAIN this misses some
{
int t = temperature_timer.read_us (); // Must be being overrun by something, most likely culprit A-D reading ?
@@ -173,7 +193,7 @@
temp_sensor_count++;
// T2 = !T2; // scope hanger
}
-
+#endif
// End of Interrupt Service Routines
@@ -281,6 +301,24 @@
}
+void Update_Current_Scaler () { // ***NEW Sept 2019*** Called at 8Hz
+const double Vnom = 48.0,
+ Vmin = Vnom / 3.0,
+ Voff = Vnom / 4.0;
+
+ double v = Read_BatteryVolts ();
+ if (v > Vnom)
+ v = Vnom;
+ if (v < Voff)
+ v = Voff;
+ if (v > Vmin) { // In expected normal operating voltage range
+ Current_Scaler_Sep_2019 = v / Vnom; // May need to revisit law
+ }
+ else { // In very low voltage region
+ Current_Scaler_Sep_2019 = 0.5 * (v / Vnom);
+ }
+}
+
void mode_set_both_motors (int mode, double val) // called from cli to set fw, re, rb, hb
{
MotorA.set_mode (mode);
@@ -356,7 +394,7 @@
const int buflen = sizeof(dirbuf) / sizeof(int);
const double Pot_Brake_Range = 0.35; //pow (0.5, SERVOIN_PWR_BENDER); //0.353553 for SERVOIN_PWR_BENDER = 1.5;
- direction_old = direction_new;
+ direction_old = direction_new;
// Test for change in direction switch setting.
// If whole buffer NEWLY filled with all Fwd or all Rev, state = brake_wait
@@ -460,16 +498,16 @@
int main()
{
int eighth_sec_count = 0;
- double servo_angle = 0.0; // For testing servo outs
-
- Temperature_pin.fall (&temp_sensor_isr);
- Temperature_pin.mode (PullUp);
// Setup system timers to cause periodic interrupts to synchronise and automate volt and current readings, loop repeat rate etc
tick_vread.attach_us (&ISR_voltage_reader, VOLTAGE_READ_INTERVAL_US); // Start periodic interrupt generator
loop_timer.attach_us (&ISR_loop_timer, MAIN_LOOP_REPEAT_TIME_US); // Start periodic interrupt generator
+#ifdef TEMP_SENSOR_ENABLE
temperature_find_ticker.attach_us (&ISR_temperature_find_ticker, 960);
+ Temperature_pin.fall (&temp_sensor_isr);
+ Temperature_pin.mode (PullUp);
+ temperature_timer.start ();
+#endif
// Done setting up system interrupt timers
- temperature_timer.start ();
pc.baud (9600); // COM port to pc
com3.baud (1200); // Once had an idea to use this for IR comms, never tried
@@ -495,8 +533,10 @@
// T5 = 0; now input from fw/re on remote control box
T6 = 0;
+#ifdef TEMP_SENSOR_ENABLE
if ((last_temperature_count > 160) && (last_temperature_count < 2400)) // in range -40 to +100 degree C
temp_sensor_exists = true;
+#endif
#ifdef USING_DC_MOTORS
dc_motor_kicker_timer.start ();
#endif
@@ -514,6 +554,10 @@
// pc.printf ("SystemCoreClock=%d, MAX_PWM_TICKS=%d\r\n", SystemCoreClock, MAX_PWM_TICKS);
// pcc.test () ;
// tsc.test () ;
+
+ WatchDog = WATCHDOG_RELOAD + 80; // Allow extra few seconds at powerup
+
+
while (1) { // Loop forever, repeats synchroised by waiting for ticker Interrupt Service Routine to set 'loop_flag' true
while (!loop_flag) { // Most of the time is spent in this loop, repeatedly re-checking for commands from pc port
pcc.core () ; // Proceed beyond here once loop_timer ticker ISR has set loop_flag true
@@ -522,8 +566,8 @@
} // 32Hz original setting for loop repeat rate
loop_flag = false; // Clear flag set by ticker interrupt handler. WHEN LAST CHECKED this was about every 32ms
- RC_chan_1.validate_rx();
- RC_chan_2.validate_rx();
+ RC_chan_1.validate_rx(); // Tests for pulse width and repetition rates being believable signal from radio control
+ RC_chan_2.validate_rx(); // bool return values not noted here, these 2 lines are pointless.
switch (mode.rd(COMM_SRC)) { // Look to selected source of driving command, act on commands from wherever
case 0: // Invalid
@@ -574,14 +618,14 @@
LED = !LED; // Toggle LED on board, should be seen to fast flash
if (WatchDogEnable) {
WatchDog--;
- if (WatchDog == 0) { // Deal with WatchDog timer timeout here
+ if (WatchDog < 1) { // Deal with WatchDog timer timeout here
+ WatchDog = 0;
setVI (0.0, 0.0); // set motor volts and amps to zero
// com2.printf ("TIMEOUT %c\r\n", mode.rd(BOARD_ID)); // Potential problem of multiple units reporting at same time overcome by adding board number to WATCHDOG_RELOAD
pc.printf ("TIMEOUT %c\r\n", mode.rd(BOARD_ID)); // Brute touch screen controller can do nothing with this
} // End of dealing with WatchDog timer timeout
- if (WatchDog < 0)
- WatchDog = 0;
}
+ Update_Current_Scaler ();
eighth_sec_count++;
if (eighth_sec_count > 6) { // Send some status info out of serial port every second and a bit or thereabouts
eighth_sec_count = 0;
@@ -593,8 +637,9 @@
pc.printf ("Temp %.2f\r\n", tmprt);
}*/
}
-#define SERVO_OUT_TEST
+//#define SERVO_OUT_TEST
#ifdef SERVO_OUT_TEST
+ static double servo_angle = 0.0; // For testing servo outs
// servo out test here December 2018
servo_angle += 0.01;
if (servo_angle > TWOPI)