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: main.cpp
- Revision:
- 12:d1d21a2941ef
- Parent:
- 11:bfb73f083009
- Child:
- 13:ef7a06fa11de
--- a/main.cpp Sat Jan 19 11:45:01 2019 +0000 +++ b/main.cpp Mon Mar 04 17:51:08 2019 +0000 @@ -12,14 +12,23 @@ /* Brushless_STM3 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) + * 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 + 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 */ /* STM32F401RE - compile using NUCLEO-F401RE -// PROJECT - Dual Brushless Motor Controller - Jon Freeman June 2018. +// PROJECT - STM3_ESC Dual Brushless Motor Controller - Jon Freeman June 2018. AnalogIn to read each motor current @@ -44,6 +53,7 @@ #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 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 bool WatchDogEnable = false; // Must recieve explicit instruction from pc or controller to enable @@ -51,80 +61,31 @@ 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 AtoD_Semaphore = 0; -int IAm; + bool loop_flag = false; // made true in ISR_loop_timer, picked up and made false again in main programme loop bool flag_8Hz = false; // As loop_flag but repeats 8 times per sec bool temp_sensor_exists = false; -bool eeprom_flag; // gets set according to 24LC674 being found or not -bool mode_good_flag = false; -char mode_bytes[36]; +double rpm2mph; uint32_t temp_sensor_count = 0, // incremented by every rising edge from LMT01 - last_temp_count = 0; // global updated approx every 100ms after each LMT01 conversion completes -// struct single_bogie_options bogie; -double rpm2mph = 0.0; // gets calculated from eeprom mode entries if present + last_temperature_count = 0; // global updated approx every 100ms after each LMT01 conversion completes /* 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 Ticker temperature_find_ticker; Timer temperature_timer; + +#ifdef USING_DC_MOTORS Timer dc_motor_kicker_timer; Timeout motors_restore; +#endif + RControl_In RC_chan_1 (PC_14); RControl_In RC_chan_2 (PC_15); // Instantiate two radio control input channels and specify which InterruptIn pin - - -// Interrupt Service Routines -void ISR_temperature_find_ticker () // every 960 us, i.e. slightly faster than once per milli sec -{ - static bool readflag = false; - int t = temperature_timer.read_ms (); - if ((t == 5) && (!readflag)) { - last_temp_count = temp_sensor_count; - temp_sensor_count = 0; - readflag = true; - } - if (t == 6) - readflag = false; -} +error_handling_Jan_2019 ESC_Error ; // Provides array usable to store error codes. -/** 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. -* Increments global 'sys_timer', usable anywhere as general measure of elapsed time -*/ -void ISR_loop_timer () // This is Ticker Interrupt Service Routine - loop timer - MAIN_LOOP_REPEAT_TIME_US -{ - loop_flag = true; // set flag to allow main programme loop to proceed - sys_timer++; // Just a handy measure of elapsed time for anything to use - if ((sys_timer & 0x03) == 0) - flag_8Hz = true; -} - -/** void ISR_voltage_reader () -* This ISR responds to Ticker interrupts every 'VOLTAGE_READ_INTERVAL_US' micro seconds -* -* AtoD_reader() called from convenient point in code to take readings outside of ISRs -*/ - -void ISR_voltage_reader () // This is Ticker Interrupt Service Routine ; few us between readings ; VOLTAGE_READ_INTERVAL_US = 50 -{ - AtoD_Semaphore++; - fast_sys_timer++; // Just a handy measure of elapsed time for anything to use -} - -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 ? - temperature_timer.reset (); - temp_sensor_count++; - if (t > 18) // Yes proved some interrupts get missed, this fixes temperature reading - temp_sensor_count++; -// T2 = !T2; // scope hanger -} - -// End of Interrupt Service Routines +eeprom_settings mode (SDA_PIN, SCL_PIN) ; // This MUST come before Motors setup //uint32_t HAtot = 0, HBtot = 0, A_Offset = 0, B_Offset = 0; /* @@ -159,15 +120,63 @@ KEEP_L_MASK_B, KEEP_H_MASK_B } ; -brushless_motor MotorA (MOT_A_I_ADC, APWMV, APWMI, A_tabl, _MAH1, _MAH2, _MAH3, PortA, PORT_A_MASK); -brushless_motor MotorB (MOT_B_I_ADC, BPWMV, BPWMI, B_tabl, _MBH1, _MBH2, _MBH3, PortB, PORT_B_MASK); +brushless_motor MotorA (MOT_A_I_ADC, APWMV, APWMI, A_tabl, _MAH1, _MAH2, _MAH3, PortA, PORT_A_MASK, ISHUNTA); +brushless_motor MotorB (MOT_B_I_ADC, BPWMV, BPWMI, B_tabl, _MBH1, _MBH2, _MBH3, PortB, PORT_B_MASK, ISHUNTB); -void report_motor_types () // not very good test, shows 'Brushless' if Hall inputs read 1 to 6, 'DC' otherwise +extern cli_2019 pcc, tsc; // command line interpreters from pc and touch screen + +// Interrupt Service Routines +void ISR_temperature_find_ticker () // every 960 us, i.e. slightly faster than once per milli sec +{ + static bool readflag = false; + int t = temperature_timer.read_ms (); + if ((t == 5) && (!readflag)) { + last_temperature_count = temp_sensor_count; + temp_sensor_count = 0; + readflag = true; + } + if (t == 6) + readflag = false; +} + +/** 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. +* Increments global 'sys_timer', usable anywhere as general measure of elapsed time +*/ +void ISR_loop_timer () // This is Ticker Interrupt Service Routine - loop timer - MAIN_LOOP_REPEAT_TIME_US { - pc.printf ("Mot A is %s, Mot B is %s\r\n", MotorA.motor_is_brushless() ? "Brushless":"DC", MotorB.motor_is_brushless() ? "Brushless":"DC"); + loop_flag = true; // set flag to allow main programme loop to proceed + sys_timer++; // Just a handy measure of elapsed time for anything to use + if ((sys_timer & 0x03) == 0) + flag_8Hz = true; } +/** void ISR_voltage_reader () +* This ISR responds to Ticker interrupts every 'VOLTAGE_READ_INTERVAL_US' micro seconds +* +* AtoD_reader() called from convenient point in code to take readings outside of ISRs +*/ +void ISR_voltage_reader () // This is Ticker Interrupt Service Routine ; few us between readings ; VOLTAGE_READ_INTERVAL_US = 50 +{ + AtoD_Semaphore++; + fast_sys_timer++; // Just a handy measure of elapsed time for anything to use +} + +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 ? + temperature_timer.reset (); + temp_sensor_count++; + if (t > 18) // Yes proved some interrupts get missed, this fixes temperature reading + temp_sensor_count++; +// T2 = !T2; // scope hanger +} + +// End of Interrupt Service Routines + + void setVI (double v, double i) { MotorA.set_V_limit (v); // Sets max motor voltage @@ -176,40 +185,18 @@ MotorB.set_I_limit (i); } -void setV (double v) -{ - MotorA.set_V_limit (v); - MotorB.set_V_limit (v); -} - -void setI (double i) -{ - MotorA.set_I_limit (i); - MotorB.set_I_limit (i); -} - /** -void AtoD_reader () // Call to here every VOLTAGE_READ_INTERVAL_US = 50 once loop responds to flag set in isr -Not part of ISR +* void AtoD_reader () // Call to here every VOLTAGE_READ_INTERVAL_US = 50 once loop responds to flag set in isr +* Not part of ISR */ void AtoD_reader () // Call to here every VOLTAGE_READ_INTERVAL_US = 50 once loop responds to flag set in isr { static uint32_t i = 0; -// if (MotorA.dc_motor) { -// MotorA.low_side_on (); -// } -// else { if (MotorA.tickleon) MotorA.high_side_off (); -// } -// if (MotorB.dc_motor) { -// MotorB.low_side_on (); -// } -// else { if (MotorB.tickleon) MotorB.high_side_off (); -// } if (AtoD_Semaphore > 20) { pc.printf ("WARNING - sema cnt %d\r\n", AtoD_Semaphore); AtoD_Semaphore = 20; @@ -227,7 +214,7 @@ driverpot_reading >>= 1; break; case 2: - MotorA.sniff_current (); // Initiate ADC reading into averaging table + MotorA.sniff_current (); // Initiate ADC current reading break; case 3: MotorB.sniff_current (); @@ -238,12 +225,10 @@ i = 0; } // end of while (AtoD_Semaphore > 0) { if (MotorA.tickleon) { -// if (MotorA.dc_motor || MotorA.tickleon) { MotorA.tickleon--; MotorA.motor_set (); // Reactivate any high side switches turned off above } if (MotorB.tickleon) { -// if (MotorB.dc_motor || MotorB.tickleon) { MotorB.tickleon--; MotorB.motor_set (); } @@ -295,11 +280,12 @@ return ((double) volt_reading) / 951.0; // divisor fiddled to make voltage reading correct ! } + void mode_set_both_motors (int mode, double val) // called from cli to set fw, re, rb, hb { MotorA.set_mode (mode); MotorB.set_mode (mode); - if (mode == REGENBRAKE) { + if (mode == MOTOR_REGENBRAKE) { if (val > 1.0) val = 1.0; if (val < 0.0) @@ -310,36 +296,9 @@ } } -extern void setup_comms () ; -extern void command_line_interpreter_pc () ; -extern void command_line_interpreter_loco () ; -extern int check_24LC64 () ; // Call from near top of main() to init i2c bus -extern bool wr_24LC64 (int mem_start_addr, char * source, int length) ; -extern bool rd_24LC64 (int mem_start_addr, char * dest, int length) ; + -/*struct motorpairoptions { // This to be user settable in eeprom, 32 bytes - uint8_t MotA_dir, // 0 or 1 - MotB_dir, // 0 or 1 - gang, // 0 for separate control (robot mode), 1 for ganged loco bogie mode - serv1, // 0, 1, 2 = Not used, Input, Output - serv2, // 0, 1, 2 = Not used, Input, Output - cmd_source, // 0 Invalid, 1 COM1, 2 COM2, 3 Pot, 4 Servo1, 5 Servo2 - last; -} ; -*/ -int I_Am () // Returns boards id number as ASCII char -{ - return IAm; -} - -double mph (int rpm) -{ - if (mode_good_flag) { - return rpm2mph * (double) rpm; - } - return -1.0; -} - +#ifdef USING_DC_MOTORS void restorer () { motors_restore.detach (); @@ -354,6 +313,7 @@ MotorB.motor_set (); } } +#endif void rcin_report () { double c1 = RC_chan_1.normalised(); @@ -429,14 +389,14 @@ case HAND_CONT_BRAKE_WAIT: // Only get here after direction input changed or newly validated at power on pc.printf ("At HAND_CONT_BRAKE_WAIT\r\n"); brake_effort = 0.05; // Apply braking not too fiercely - mode_set_both_motors (REGENBRAKE, brake_effort); // Direction change + mode_set_both_motors (MOTOR_REGENBRAKE, brake_effort); // Direction change hand_controller_state = HAND_CONT_BRAKE_POT; break; case HAND_CONT_BRAKE_POT: // Only get here after one pass through HAND_CONT_BRAKE_WAIT but if (brake_effort < 0.9) { // remain in this state until driver has turned pott fully anticlockwise brake_effort += 0.05; // ramp braking up to max over about one sec after direction change or validation - mode_set_both_motors (REGENBRAKE, brake_effort); // Direction change or testing at power on + mode_set_both_motors (MOTOR_REGENBRAKE, brake_effort); // Direction change or testing at power on pc.printf ("Brake effort %.2f\r\n", brake_effort); } else { // once braking up to quite hard @@ -450,7 +410,7 @@ brake_effort = (Pot_Brake_Range - pot_position) / Pot_Brake_Range; if (brake_effort < 0.0) brake_effort = 0.5; - mode_set_both_motors (REGENBRAKE, brake_effort); + mode_set_both_motors (MOTOR_REGENBRAKE, brake_effort); old_pot_position = pot_position; hand_controller_state = HAND_CONT_STATE_BRAKING; pc.printf ("Brake\r\n"); @@ -463,7 +423,7 @@ if (worth_the_bother(pot_position, old_pot_position)) { old_pot_position = pot_position; brake_effort = (Pot_Brake_Range - pot_position) / Pot_Brake_Range; - mode_set_both_motors (REGENBRAKE, brake_effort); + mode_set_both_motors (MOTOR_REGENBRAKE, brake_effort); // pc.printf ("Brake %.2f\r\n", brake_effort); } } @@ -472,9 +432,9 @@ case HAND_CONT_STATE_INTO_DRIVING: // Only get here after HAND_CONT_STATE_BRAKING pc.printf ("Drive\r\n"); if (direction_new == 1) - mode_set_both_motors (FORWARD, 0.0); // sets both motors + mode_set_both_motors (MOTOR_FORWARD, 0.0); // sets both motors else - mode_set_both_motors (REVERSE, 0.0); + mode_set_both_motors (MOTOR_REVERSE, 0.0); hand_controller_state = HAND_CONT_STATE_DRIVING; break; @@ -502,7 +462,6 @@ 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 @@ -512,83 +471,53 @@ // Done setting up system interrupt timers temperature_timer.start (); - pc.baud (9600); - com3.baud (1200); - com2.baud (19200); - setup_comms (); + pc.baud (9600); // COM port to pc + com3.baud (1200); // Once had an idea to use this for IR comms, never tried + com2.baud (19200); // Opto isolated serial bus connecting 'n' STM3_ESC boards to 1 Brute Touch Screen controller - IAm = '0'; - if (check_24LC64() != 0xa0) { // searches for i2c devices, returns address of highest found - pc.printf ("Check for 24LC64 eeprom FAILED\r\n"); - com2.printf ("Check for 24LC64 eeprom FAILED\r\n"); - eeprom_flag = false; - } else { // Found 24LC64 memory on I2C - eeprom_flag = true; - bool k; - k = rd_24LC64 (0, mode_bytes, 32); - if (!k) - com2.printf ("Error reading from eeprom\r\n"); + rpm2mph = 60.0 // to Motor Revs per hour; + * ((double)mode.rd(MOTPIN) / (double)mode.rd(WHEELGEAR)) // Wheel revs per hour + * PI * ((double)mode.rd(WHEELDIA) / 1000.0) // metres per hour + * 39.37 / (1760.0 * 36.0); // miles per hour -// int err = 0; - for (int i = 0; i < numof_eeprom_options; i++) { - if ((mode_bytes[i] < option_list[i].min) || (mode_bytes[i] > option_list[i].max)) { - com2.printf ("EEROM error with %s\r\n", option_list[i].t); - pc.printf ("EEROM error with %s\r\n", option_list[i].t); - if (i == ID) { // need to force id to '0' - pc.printf ("Bad board ID value %d, forcing to \'0\'\r\n"); - mode_bytes[ID] = '0'; - } -// err++; - } -// else -// com2.printf ("%2x Good %s\r\n", buff[i], option_list[i].t); - } - rpm2mph = 0.0; - if (mode_bytes[WHEELGEAR] == 0) // avoid making div0 error - mode_bytes[WHEELGEAR]++; -// if (err == 0) { - mode_good_flag = true; - MotorA.direction_set (mode_bytes[MOTADIR]); - MotorB.direction_set (mode_bytes[MOTBDIR]); - IAm = mode_bytes[ID]; - rpm2mph = 60.0 // to Motor Revs per hour; - * ((double)mode_bytes[MOTPIN] / (double)mode_bytes[WHEELGEAR]) // Wheel revs per hour - * PI * ((double)mode_bytes[WHEELDIA] / 1000.0) // metres per hour - * 39.37 / (1760.0 * 36.0); // miles per hour -// } - // Alternative ID 1 to 9 -// com2.printf ("Alternative ID = 0x%2x\r\n", buff[6]); - } + MotorA.direction_set (mode.rd(MOTADIR)); // modes all setup in class eeprom_settings {} mode ; constructor + MotorB.direction_set (mode.rd(MOTBDIR)); + MotorA.poles (mode.rd(MOTAPOLES)); // Returns true if poles 4, 6 or 8. Returns false otherwise + MotorB.poles (mode.rd(MOTBPOLES)); // Only two calls are here + MotorA.set_mode (MOTOR_REGENBRAKE); + MotorB.set_mode (MOTOR_REGENBRAKE); + setVI (0.9, 0.5); // Power up with moderate regen braking applied + // T1 = 0; Now WRONGLY hoped to be InterruptIn counting pulses from LMT01 temperature sensor T2 = 0; // T2, T3, T4 As yet unused pins // T3 = 0; // T4 = 0; // T5 = 0; now input from fw/re on remote control box T6 = 0; -// MotPtr[0]->set_mode (REGENBRAKE); - MotorA.set_mode (REGENBRAKE); - MotorB.set_mode (REGENBRAKE); - setVI (0.9, 0.5); - if ((last_temp_count > 160) && (last_temp_count < 2400)) // in range -40 to +100 degree C + if ((last_temperature_count > 160) && (last_temperature_count < 2400)) // in range -40 to +100 degree C temp_sensor_exists = true; -// pc.printf ("Ready to go!, wheel gear in position %d\r\n", WHEELGEAR); +#ifdef USING_DC_MOTORS dc_motor_kicker_timer.start (); +#endif int old_hand_controller_direction = T5; - if (mode_bytes[COMM_SRC] == 3) { // Read fwd/rev switch 'T5', PA15 on 401 + if (mode.rd(COMM_SRC) == 3) { // Read fwd/rev switch 'T5', PA15 on 401 pc.printf ("Pot control\r\n"); if (T5) - mode_set_both_motors (FORWARD, 0.0); // sets both motors + mode_set_both_motors (MOTOR_FORWARD, 0.0); // sets both motors else - mode_set_both_motors (REVERSE, 0.0); + mode_set_both_motors (MOTOR_REVERSE, 0.0); } - pc.printf ("About to start!, mode_bytes[COMM_SRC]= %d\r\n", mode_bytes[COMM_SRC]); - + pc.printf ("About to start %s!, mode_bytes[COMM_SRC]= %d\r\n", const_version_string, mode.rd(COMM_SRC)); + pc.printf ("ESC_Error.all_good() ret'd %s\r\n", ESC_Error.all_good() ? "true" : "false"); +// pc.printf ("SystemCoreClock=%d, MAX_PWM_TICKS=%d\r\n", SystemCoreClock, MAX_PWM_TICKS); +// pcc.test () ; +// tsc.test () ; 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 - command_line_interpreter_pc () ; // Proceed beyond here once loop_timer ticker ISR has set loop_flag true - command_line_interpreter_loco () ; // Proceed beyond here once loop_timer ticker ISR has set loop_flag true + pcc.core () ; // Proceed beyond here once loop_timer ticker ISR has set loop_flag true + tsc.core () ; // Proceed beyond here once loop_timer ticker ISR has set loop_flag true AtoD_reader (); // Performs A to D conversions at rate set by ticker interrupts } // 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 @@ -596,7 +525,7 @@ RC_chan_1.validate_rx(); RC_chan_2.validate_rx(); - switch (mode_bytes[COMM_SRC]) { // Look to selected source of driving command, act on commands from wherever + switch (mode.rd(COMM_SRC)) { // Look to selected source of driving command, act on commands from wherever case 0: // Invalid break; case COM1: // COM1 - Primarily for testing, bypassed by command line interpreter @@ -612,27 +541,33 @@ case RC_IN2: // RC_chan_2 break; default: - pc.printf ("Unrecognised state %d\r\n", mode_bytes[COMM_SRC]); // set error flag instead here + if (ESC_Error.read(FAULT_UNRECOGNISED_STATE)) { + pc.printf ("Unrecognised state %d\r\n", mode.rd(COMM_SRC)); // set error flag instead here + ESC_Error.set (FAULT_UNRECOGNISED_STATE, 1); + } break; } // endof switch (mode_bytes[COMM_SRC]) { +#ifdef USING_DC_MOTORS dc_motor_kicker_timer.reset (); - MotorA.pulses_per_sec (); // Needed to keep table updated to give reading in Hall transitions per second - MotorB.pulses_per_sec (); // Read MotorX.PPS to read pulses per sec or MotorX.RPM to read motor RPM -// T4 = !T4; // toggle to hang scope on to verify loop execution - // do stuff +#endif + MotorA.speed_monitor_and_control (); // Needed to keep table updated to give reading in Hall transitions per second + MotorB.speed_monitor_and_control (); // Read MotorX.PPS to read pulses per sec or MotorX.RPM to read motor RPM + +#ifdef USING_DC_MOTORS if (MotorA.dc_motor) { - MotorA.raw_V_pwm (1); +// MotorA.raw_V_pwm (1); MotorA.low_side_on (); } if (MotorB.dc_motor) { - MotorB.raw_V_pwm (1); +// MotorB.raw_V_pwm (1); MotorB.low_side_on (); } if (MotorA.dc_motor || MotorB.dc_motor) { // motors_restore.attach_us (&restorer, ttime); motors_restore.attach_us (&restorer, 25); } +#endif if (flag_8Hz) { // do slower stuff flag_8Hz = false; @@ -641,7 +576,8 @@ WatchDog--; if (WatchDog == 0) { // Deal with WatchDog timer timeout here setVI (0.0, 0.0); // set motor volts and amps to zero - com2.printf ("TIMEOUT %2x\r\n", (I_Am() & 0x0f)); // Potential problem of multiple units reporting at same time overcome by adding board number to WATCHDOG_RELOAD +// 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; @@ -649,16 +585,13 @@ 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; - MotorA.current_calc (); // Updates readings in MotorA.I.min, MotorA.I.ave and MotorA.I.max - MotorB.current_calc (); + ESC_Error.report_any (false); // retain = false - reset error after reporting once /* if (temp_sensor_exists) { double tmprt = (double) last_temp_count; tmprt /= 16.0; tmprt -= 50.0; pc.printf ("Temp %.2f\r\n", tmprt); }*/ -// com2.printf ("V=%+.2f, Pot=%+.2f, HA %d, HB %d, IAmin %d, IAave %d, IAmax %d, IB %d, Arpm %d, Brpm %d\r\n", Read_BatteryVolts(), Read_DriverPot(), MotorA.read_Halls (), MotorB.read_Halls (), MotorA.I.min, MotorA.I.ave, MotorA.I.max, MotorB.I.ave, (Apps * 60) / 24, (Bpps * 60) / 24); -// com2.printf ("V=%+.2f, Pot=%+.2f, HA %d, HB %d, IAmin %d, IAave %d, IAmax %d, IB %d\r\n", Read_BatteryVolts(), Read_DriverPot(), MotorA.read_Halls (), MotorB.read_Halls (), MotorA.I.min, MotorA.I.ave, MotorA.I.max, MotorB.I.ave); } #define SERVO_OUT_TEST #ifdef SERVO_OUT_TEST