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

Committer:
JonFreeman
Date:
Sun Aug 16 14:13:19 2020 +0000
Revision:
17:cc9b854295d6
Parent:
16:d1e4b9ad3b8b
August 2020. Checked Radio Control input ops.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JonFreeman 13:ef7a06fa11de 1 #include "STM3_ESC.h"
JonFreeman 10:e40d8724268a 2 // Feb 2018 Now using DGD21032 mosfet drivers via 74HC00 pwm gates (low side) - GOOD, works well with auto-tickle of high side drivers
JonFreeman 10:e40d8724268a 3
JonFreeman 10:e40d8724268a 4 // Jan 2019 Trying to add two Radio Control inputs on PC_14 and PC_15, previously connected to unused LF Xtal.
JonFreeman 10:e40d8724268a 5 // Problem - Appears to conflict with serial port used for comms with controller
JonFreeman 10:e40d8724268a 6 // Earlier efforts to use 'Servo' ports as 'you choose' between I/O failed as pins not capable of use as 'InterruptIn'
JonFreeman 10:e40d8724268a 7
JonFreeman 11:bfb73f083009 8 // CORRECTION Comms problem with Touch Screen was insufficient pull-up on STM3_ESC opto. Change R12 from 1k to 470R
JonFreeman 10:e40d8724268a 9
JonFreeman 15:2591e2008323 10 // Update November 2019 - Radio Control Inputs good.
JonFreeman 10:e40d8724268a 11
JonFreeman 7:6deaeace9a3e 12
JonFreeman 7:6deaeace9a3e 13 // Port A -> MotorA, Port B -> MotorB
JonFreeman 7:6deaeace9a3e 14 const uint16_t
JonFreeman 10:e40d8724268a 15 // This is where port bits get assigned to motor output phase switches.
JonFreeman 10:e40d8724268a 16 // Phases are U, V and W.
JonFreeman 10:e40d8724268a 17 // Each phase uses two bits, one for the low side switch, one for the high side switch.
JonFreeman 10:e40d8724268a 18 //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
JonFreeman 10:e40d8724268a 19 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
JonFreeman 10:e40d8724268a 20 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
JonFreeman 10:e40d8724268a 21 // Using port bit info in the two lines above, the compiler sorts all this into creation of lookup table
JonFreeman 10:e40d8724268a 22 // to provide correct energisation sequencing as motors rotate.
JonFreeman 10:e40d8724268a 23 // You need concern yourself no further about any of this.
JonFreeman 10:e40d8724268a 24
JonFreeman 7:6deaeace9a3e 25
JonFreeman 10:e40d8724268a 26 AUL = (1 << MotorA_port_bits[0]),
JonFreeman 10:e40d8724268a 27 AVL = (1 << MotorA_port_bits[1]), // These are which port bits connect to which mosfet driver
JonFreeman 10:e40d8724268a 28 AWL = (1 << MotorA_port_bits[2]),
JonFreeman 7:6deaeace9a3e 29
JonFreeman 10:e40d8724268a 30 AUH = (1 << MotorA_port_bits[3]),
JonFreeman 10:e40d8724268a 31 AVH = (1 << MotorA_port_bits[4]),
JonFreeman 10:e40d8724268a 32 AWH = (1 << MotorA_port_bits[5]),
JonFreeman 10:e40d8724268a 33
JonFreeman 10:e40d8724268a 34 AUHVL = AUH | AVL, // Each of 6 possible output energisations made up of one hi and one low
JonFreeman 10:e40d8724268a 35 AVHUL = AVH | AUL,
JonFreeman 10:e40d8724268a 36 AUHWL = AUH | AWL,
JonFreeman 10:e40d8724268a 37 AWHUL = AWH | AUL,
JonFreeman 10:e40d8724268a 38 AVHWL = AVH | AWL,
JonFreeman 10:e40d8724268a 39 AWHVL = AWH | AVL,
JonFreeman 7:6deaeace9a3e 40
JonFreeman 7:6deaeace9a3e 41 KEEP_L_MASK_A = AUL | AVL | AWL,
JonFreeman 7:6deaeace9a3e 42 KEEP_H_MASK_A = AUH | AVH | AWH,
JonFreeman 7:6deaeace9a3e 43
JonFreeman 7:6deaeace9a3e 44 BRA = AUL | AVL | AWL, // All low side switches on (and all high side off) for braking
JonFreeman 7:6deaeace9a3e 45
JonFreeman 10:e40d8724268a 46 BUL = (1 << MotorB_port_bits[0]), // Likewise for MotorB but different port bits on different port
JonFreeman 10:e40d8724268a 47 BVL = (1 << MotorB_port_bits[1]),
JonFreeman 10:e40d8724268a 48 BWL = (1 << MotorB_port_bits[2]),
JonFreeman 7:6deaeace9a3e 49
JonFreeman 10:e40d8724268a 50 BUH = (1 << MotorB_port_bits[3]),
JonFreeman 10:e40d8724268a 51 BVH = (1 << MotorB_port_bits[4]),
JonFreeman 10:e40d8724268a 52 BWH = (1 << MotorB_port_bits[5]),
JonFreeman 7:6deaeace9a3e 53
JonFreeman 10:e40d8724268a 54 BUHVL = BUH | BVL,
JonFreeman 10:e40d8724268a 55 BVHUL = BVH | BUL,
JonFreeman 10:e40d8724268a 56 BUHWL = BUH | BWL,
JonFreeman 10:e40d8724268a 57 BWHUL = BWH | BUL,
JonFreeman 10:e40d8724268a 58 BVHWL = BVH | BWL,
JonFreeman 10:e40d8724268a 59 BWHVL = BWH | BVL,
JonFreeman 7:6deaeace9a3e 60
JonFreeman 7:6deaeace9a3e 61 KEEP_L_MASK_B = BUL | BVL | BWL,
JonFreeman 7:6deaeace9a3e 62 KEEP_H_MASK_B = BUH | BVH | BWH,
JonFreeman 7:6deaeace9a3e 63
JonFreeman 7:6deaeace9a3e 64 BRB = BUL | BVL | BWL,
JonFreeman 7:6deaeace9a3e 65
JonFreeman 7:6deaeace9a3e 66 PORT_A_MASK = AUL | AVL | AWL | AUH | AVH | AWH, // NEW METHOD FOR DGD21032 MOSFET DRIVERS
JonFreeman 7:6deaeace9a3e 67 PORT_B_MASK = BUL | BVL | BWL | BUH | BVH | BWH;
JonFreeman 7:6deaeace9a3e 68
JonFreeman 11:bfb73f083009 69 //PortOut MotA (PortA, PORT_A_MASK); // Activate output ports to motor drivers
JonFreeman 11:bfb73f083009 70 //PortOut MotB (PortB, PORT_B_MASK);
JonFreeman 7:6deaeace9a3e 71
JonFreeman 7:6deaeace9a3e 72 // Pin 1 VBAT NET +3V3
JonFreeman 7:6deaeace9a3e 73
JonFreeman 7:6deaeace9a3e 74 //DigitalIn J3 (PC_13, PullUp);// Pin 2 Jumper pulls to GND, R floats Hi
JonFreeman 13:ef7a06fa11de 75 #ifdef TEMP_SENSOR_ENABLE
JonFreeman 7:6deaeace9a3e 76 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
JonFreeman 13:ef7a06fa11de 77 #endif
JonFreeman 7:6deaeace9a3e 78
JonFreeman 10:e40d8724268a 79 // Pin 3 PC14-OSC32_IN NET O32I Xtal chucked off these pins, now needed for RC inputs
JonFreeman 7:6deaeace9a3e 80 // Pin 4 PC15-OSC32_OUT NET O32O
JonFreeman 7:6deaeace9a3e 81 // Pin 5 PH0-OSC_IN NET PH1
JonFreeman 7:6deaeace9a3e 82 // Pin 6 PH1-OSC_OUT NET PH1
JonFreeman 7:6deaeace9a3e 83 // Pin 7 NRST NET NRST
JonFreeman 7:6deaeace9a3e 84 AnalogIn Ain_DriverPot (PC_0); // Pin 8 Spare Analogue in, net SAIN fitted with external pull-down
JonFreeman 7:6deaeace9a3e 85 AnalogIn Ain_SystemVolts (PC_1); // Pin 9
JonFreeman 11:bfb73f083009 86 #define MOT_A_I_ADC PC_2
JonFreeman 11:bfb73f083009 87 #define MOT_B_I_ADC PC_3
JonFreeman 11:bfb73f083009 88 //AnalogIn Motor_A_Current (PC_2); // Pin 10
JonFreeman 11:bfb73f083009 89 //AnalogIn Motor_B_Current (PC_3); // Pin 11
JonFreeman 7:6deaeace9a3e 90 // Pin 12 VSSA/VREF- NET GND
JonFreeman 7:6deaeace9a3e 91 // Pin 13 VDDA/VREF+ NET +3V3
JonFreeman 7:6deaeace9a3e 92 // Pin 14 Port_A AUL
JonFreeman 7:6deaeace9a3e 93 // Pin 15 Port_A AUH
JonFreeman 7:6deaeace9a3e 94 // Pins 16, 17 BufferedSerial pc
JonFreeman 16:d1e4b9ad3b8b 95 BufferedSerial pc (PA_2, PA_3, 5000, 4, NULL); // Pins 16, 17 tx, rx to pc via usb lead
JonFreeman 7:6deaeace9a3e 96 // Pin 18 VSS NET GND
JonFreeman 7:6deaeace9a3e 97 // Pin 19 VDD NET +3V3
JonFreeman 7:6deaeace9a3e 98 // Pin 20 Port_A AWL
JonFreeman 7:6deaeace9a3e 99 // Pin 21 DigitalOut led1(LED1);
JonFreeman 7:6deaeace9a3e 100 DigitalOut LED (PA_5); // Pin 21
JonFreeman 7:6deaeace9a3e 101 // Pin 22 Port_A AVL
JonFreeman 7:6deaeace9a3e 102 // Pin 23 Port_A AVH
JonFreeman 11:bfb73f083009 103 //InterruptIn MBH2 (PC_4); // Pin 24
JonFreeman 11:bfb73f083009 104 //InterruptIn MBH3 (PC_5); // Pin 25
JonFreeman 11:bfb73f083009 105 #define _MBH2 PC_4
JonFreeman 11:bfb73f083009 106 #define _MBH3 PC_5
JonFreeman 7:6deaeace9a3e 107 // Pin 26 Port_B BUL
JonFreeman 7:6deaeace9a3e 108 // Pin 27 Port_B BVL
JonFreeman 7:6deaeace9a3e 109 // Pin 28 Port_B BWL
JonFreeman 7:6deaeace9a3e 110 // Pin 29 Port_B BUH
JonFreeman 7:6deaeace9a3e 111 // Pin 30 VCAP1
JonFreeman 7:6deaeace9a3e 112 // Pin 31 VSS
JonFreeman 7:6deaeace9a3e 113 // Pin 32 VDD
JonFreeman 7:6deaeace9a3e 114 // Pin 33 Port_B BVH
JonFreeman 7:6deaeace9a3e 115 // Pin 34 Port_B BWH
JonFreeman 7:6deaeace9a3e 116 DigitalOut T4 (PB_14); // Pin 35
JonFreeman 7:6deaeace9a3e 117 DigitalOut T3 (PB_15); // Pin 36
JonFreeman 7:6deaeace9a3e 118 // BufferedSerial com2 pins 37 Tx, 38 Rx
JonFreeman 11:bfb73f083009 119 BufferedSerial com2 (PC_6, PC_7); // Pins 37, 38 tx, rx to Touch Screen Controller
JonFreeman 11:bfb73f083009 120 #define APWMV PC_8
JonFreeman 11:bfb73f083009 121 #define APWMI PC_9
JonFreeman 11:bfb73f083009 122 //FastPWM A_MAX_V_PWM (PC_8, PWM_PRESECALER_DEFAULT), // Pin 39 pwm3/3
JonFreeman 11:bfb73f083009 123 // A_MAX_I_PWM (PC_9, PWM_PRESECALER_DEFAULT); // pin 40, prescaler value pwm3/4
JonFreeman 7:6deaeace9a3e 124 //InterruptIn MotB_Hall (PA_8); // Pin 41
JonFreeman 7:6deaeace9a3e 125 // Pin 41 Port_A AWH
JonFreeman 7:6deaeace9a3e 126 // BufferedSerial com3 pins 42 Tx, 43 Rx
JonFreeman 7:6deaeace9a3e 127 //InterruptIn tryseredge (PA_9);
JonFreeman 7:6deaeace9a3e 128 BufferedSerial com3 (PA_9, PA_10); // Pins 42, 43 tx, rx to any aux module
JonFreeman 7:6deaeace9a3e 129 // 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 !
JonFreeman 7:6deaeace9a3e 130 // No.
JonFreeman 7:6deaeace9a3e 131
JonFreeman 7:6deaeace9a3e 132 // Feb 2018 Pins 44 and 45 now liberated, could use for serial or other uses
JonFreeman 7:6deaeace9a3e 133 //BufferedSerial extra_ser (PA_11, PA_12); // Pins 44, 45 tx, rx to XBee module
JonFreeman 7:6deaeace9a3e 134 DigitalOut T2 (PA_11); // Pin 44
JonFreeman 7:6deaeace9a3e 135 // was DigitalOut T1 (PA_12); // Pin 45
JonFreeman 7:6deaeace9a3e 136
JonFreeman 7:6deaeace9a3e 137
JonFreeman 7:6deaeace9a3e 138 //InterruptIn T1 (PA_12); // Pin 45 now input counting pulses from LMT01 temperature sensor
JonFreeman 7:6deaeace9a3e 139 // InterruptIn DOES NOT WORK ON PA_12. Boards are being made, will have to wire link PA12 to PC13
JonFreeman 7:6deaeace9a3e 140 DigitalIn T1 (PA_12);
JonFreeman 7:6deaeace9a3e 141 ////InterruptIn T1 (PC_13); // Pin 45 now input counting pulses from LMT01 temperature sensor
JonFreeman 7:6deaeace9a3e 142
JonFreeman 7:6deaeace9a3e 143
JonFreeman 7:6deaeace9a3e 144
JonFreeman 7:6deaeace9a3e 145 // Pin 46 SWDIO
JonFreeman 7:6deaeace9a3e 146 // Pin 47 VSS
JonFreeman 7:6deaeace9a3e 147 // Pin 48 VDD
JonFreeman 7:6deaeace9a3e 148 // Pin 49 SWCLK
JonFreeman 7:6deaeace9a3e 149
JonFreeman 7:6deaeace9a3e 150 //Was DigitalOut T5 (PA_15); // Pin 50
JonFreeman 7:6deaeace9a3e 151 DigitalIn T5 (PA_15); // Pin 50 now fwd/rev from remote control box if fitted
JonFreeman 12:d1d21a2941ef 152 #define _MAH1 PC_10 // Pin 51
JonFreeman 12:d1d21a2941ef 153 #define _MAH2 PC_11 // Pin 52
JonFreeman 12:d1d21a2941ef 154 #define _MAH3 PC_12 // Pin 53
JonFreeman 11:bfb73f083009 155 //InterruptIn MBH1 (PD_2); // Pin 54
JonFreeman 11:bfb73f083009 156 #define _MBH1 PD_2
JonFreeman 7:6deaeace9a3e 157 DigitalOut T6 (PB_3); // Pin 55
JonFreeman 11:bfb73f083009 158 #define BPWMV PB_4
JonFreeman 11:bfb73f083009 159 #define BPWMI PB_5
JonFreeman 11:bfb73f083009 160 //FastPWM B_MAX_V_PWM (PB_4, PWM_PRESECALER_DEFAULT), // Pin 56 pwm3/3
JonFreeman 11:bfb73f083009 161 // B_MAX_I_PWM (PB_5, PWM_PRESECALER_DEFAULT); // pin 57, prescaler value pwm3/4
JonFreeman 7:6deaeace9a3e 162
JonFreeman 12:d1d21a2941ef 163 //I2C i2c (PB_7, PB_6); // Pins 58, 59 For 24LC64 eeprom
JonFreeman 12:d1d21a2941ef 164 #define SDA_PIN PB_7
JonFreeman 12:d1d21a2941ef 165 #define SCL_PIN PB_6
JonFreeman 7:6deaeace9a3e 166 // Pin 60 BOOT0
JonFreeman 7:6deaeace9a3e 167
JonFreeman 7:6deaeace9a3e 168 // Servo pins, 2 off. Configured as Input to read radio control receiver
JonFreeman 10:e40d8724268a 169 // ** Update December 2018 **
JonFreeman 10:e40d8724268a 170 // These pins can not be used as InterruptIn.
JonFreeman 10:e40d8724268a 171 // Can be used as outputs by 'Servo'
JonFreeman 7:6deaeace9a3e 172 // If used as servo output, code gives pin to 'Servo' - seems to work
JonFreeman 10:e40d8724268a 173 //InterruptIn Servo1_i (PB_8); // Pin 61 to read output from rc rx
JonFreeman 10:e40d8724268a 174 //InterruptIn Servo2_i (PB_9); // Pin 62 to read output from rc rx
JonFreeman 9:ac2412df01be 175 // *** NOTE *** Above InterruptIn Servo using PB pins seems not to work, probably due to other Port B pins used as PortOut (try PortInOut?)
JonFreeman 9:ac2412df01be 176 // Nov 2018 - Yet to try using PC14, PC15, free now as 32k768 xtal not fitted
JonFreeman 9:ac2412df01be 177
JonFreeman 7:6deaeace9a3e 178
JonFreeman 7:6deaeace9a3e 179 // Pin 63 VSS
JonFreeman 7:6deaeace9a3e 180 // Pin 64 VDD
JonFreeman 7:6deaeace9a3e 181 // SYSTEM CONSTANTS
JonFreeman 11:bfb73f083009 182 // December 2018 ** NEED TO PROVE SERVO OUT WORKS ** YES, DONE.
JonFreeman 11:bfb73f083009 183 Servo Servo1 (PB_8) ;
JonFreeman 11:bfb73f083009 184 // Servos[0] = & Servo1;
JonFreeman 11:bfb73f083009 185 Servo Servo2 (PB_9) ;
JonFreeman 11:bfb73f083009 186 // Servos[1] = & Servo2;
JonFreeman 7:6deaeace9a3e 187