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 14:acaa1add097b, committed 2019-11-30
- Comitter:
- JonFreeman
- Date:
- Sat Nov 30 16:34:58 2019 +0000
- Parent:
- 13:ef7a06fa11de
- Child:
- 15:2591e2008323
- Commit message:
- Proved inverter board for radio control inputs work.
Changed in this revision
--- a/24LC64_eeprom.cpp Sun Sep 29 16:34:37 2019 +0000
+++ b/24LC64_eeprom.cpp Sat Nov 30 16:34:58 2019 +0000
@@ -6,8 +6,8 @@
// Code for 24LC64 8k x 8 bit eeprom
// Code based on earlier work using memory FM24W256, also at i2c address 0xa0;
-const int addr_rd = 0xa1; // set bit 0 for read, clear bit 0 for write
-const int addr_wr = 0xa0; // set bit 0 for read, clear bit 0 for write
+const int addr_rd = 0xa1; // set bit 0 for read, clear bit 0 for write 24LC64
+const int addr_wr = 0xa0; // set bit 0 for read, clear bit 0 for write 24LC64
const int ACK = 1;
struct optpar {
@@ -47,6 +47,8 @@
class eeprom_settings {
I2C i2c;
uint32_t errors;
+ uint32_t i2c_device_count;
+ uint32_t i2c_device_list[12]; // 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) ;
@@ -54,6 +56,7 @@
bool ack_poll () ;
public:
eeprom_settings (PinName sda, PinName scl); // Constructor
+ bool do_we_have_i2c (uint32_t x) ;
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
@@ -71,31 +74,44 @@
return errors;
}
+bool eeprom_settings::do_we_have_i2c (uint32_t x) {
+ for (int i = 0; i < i2c_device_count; i++) {
+ if (i2c_device_list[i] == x)
+ return true;
+ }
+ return false;
+}
+
// Use : eeprom_settings (SDA_PIN, SCL_PIN);
eeprom_settings::eeprom_settings (PinName sda, PinName scl) : i2c(sda, scl) // Constructor
{
- errors = 0;
+ errors = i2c_device_count = 0;
for (int i = 0; i < 36; i++)
settings[i] = 0;
+ for (int i = 0; i < 12; i++)
+ i2c_device_list[i] = 0;
i2c.frequency(400000); // Speed 400000 max.
- int last_found = 0, q; // Note address bits 3-1 to match addr pins on device
+// int last_found = 0, q; // Note address bits 3-1 to match addr pins on device
+ int q;
for (int i = 0; i < 255; i += 2) { // Search for devices at all possible i2c addresses
i2c.start();
q = i2c.write(i); // may return error code 2 when no start issued
switch (q) {
case ACK:
pc.printf ("I2C device found at 0x%x\r\n", i);
- last_found = i;
+// last_found = i;
+ i2c_device_list[i2c_device_count++] = i;
case 2: // Device not seen at this address
break;
default:
- pc.printf ("Unknown error %d in check_24LC64\r\n", q);
+ pc.printf ("Unknown error %d from i2c.write while looking for i2c devices\r\n", q);
errors |= 512;
break;
}
}
i2c.stop();
- if (errors || last_found != 0xa0) {
+// if (errors || last_found != 0xa0) {
+ if (errors || !do_we_have_i2c(0xa0)) {
pc.printf ("Error - EEPROM not seen %d\r\n", errors);
errors |= 0xa0;
ESC_Error.set (FAULT_EEPROM, errors); // Set FAULT_EEPROM bits if 24LC64 problem
--- a/Radio_Control_In.cpp Sun Sep 29 16:34:37 2019 +0000
+++ b/Radio_Control_In.cpp Sat Nov 30 16:34:58 2019 +0000
@@ -64,14 +64,14 @@
return norm;
}
-void RControl_In::RadC_rise () // December 2018 - Could not make Servo port bidirectional, fix by using PC_14 and 15 as inputs
-{
+void RControl_In::RadC_fall () // December 2018 - Could not make Servo port bidirectional, fix by using PC_14 and 15 as inputs
+{ // 30th November 2019 - Swapped _rise and _fall as now using Schmitt inverters on input
period_us = t.read_us ();
t.reset ();
t.start ();
}
-void RControl_In::RadC_fall ()
+void RControl_In::RadC_rise ()
{
pulse_width_us = t.read_us ();
pulse_count++;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SB1602E.lib Sat Nov 30 16:34:58 2019 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/okano/code/SB1602E/#baf578069dfc
--- a/STM3_ESC.h Sun Sep 29 16:34:37 2019 +0000
+++ b/STM3_ESC.h Sat Nov 30 16:34:58 2019 +0000
@@ -1,11 +1,16 @@
+/*
+ STM3_ESC Electronic Speed Controller board, drives Two Brushless Motors, full Four Quadrant Control.
+ Jon Freeman B. Eng Hons
+ 2015 - 2019
+*/
#include "mbed.h"
#ifndef MBED_DUALBLS_H
#define MBED_DUALBLS_H
-//#define USING_DC_MOTORS // Uncomment this to play with Dinosaur DC motors
+//#define USING_DC_MOTORS // Uncomment this to play with Dinosaur DC motors - WARNING deprecated feature
-//#define TEMP_SENSOR_ENABLE //
+//#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,
@@ -35,7 +40,7 @@
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} ; //
+ FUT1, FUT2, FUT3, FUT4, FUT5} ; // These represent address offsets in 24LC64 rom user settable firmware settings
enum {
FAULT_0,
@@ -50,7 +55,7 @@
FAULT_UNRECOGNISED_STATE,
FAULT_MAX,
NUMOF_REPORTABLE_TS_ERRORS
- } ;
+ } ; // List of fault numbers currently dealt with by error handler
class error_handling_Jan_2019
{
@@ -72,7 +77,7 @@
const int MAX_PARAMS = 20;
const int MAX_CMD_LEN = 220;
-struct parameters {
+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;
@@ -80,7 +85,7 @@
bool respond, resp_always;
} ;
-class cli_2019 {
+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];
@@ -106,6 +111,8 @@
class eeprom_settings {
I2C i2c;
uint32_t errors;
+ uint32_t i2c_device_count;
+ uint32_t i2c_device_list[12]; // 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) ;
@@ -113,6 +120,7 @@
bool ack_poll () ;
public:
eeprom_settings (PinName sda, PinName scl); // Constructor
+ bool do_we_have_i2c (uint32_t x) ;
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
--- a/brushless_motor.cpp Sun Sep 29 16:34:37 2019 +0000
+++ b/brushless_motor.cpp Sat Nov 30 16:34:58 2019 +0000
@@ -1,4 +1,8 @@
-// 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 "stm32f401xe.h"
@@ -61,7 +65,7 @@
}
/**
-* void brushless_motor::sniff_current () { // Initiate ADC current reading
+* void brushless_motor::sniff_current () { // Initiate ADC current reading of approx motor average current
* This to be called in response to ticker timebase interrupt.
* As designed, called at 200 micro second intervals (Feb 2019)
* Updates double I.dbl current measured in milliamps
@@ -235,7 +239,7 @@
*/
void brushless_motor::speed_monitor_and_control () // call this once per 'MAIN_LOOP_REPEAT_TIME_US= 31250' main loop pass to keep count = edges per sec
{
-#ifdef USING_DC_MOTORS
+#ifdef USING_DC_MOTORS // deprecated
if (dc_motor)
return 0;
#endif
--- a/brushless_motor.h Sun Sep 29 16:34:37 2019 +0000
+++ b/brushless_motor.h Sat Nov 30 16:34:58 2019 +0000
@@ -33,7 +33,7 @@
double V_clamp ; // Used to limit top speed
double numof_current_sense_rs;
public:
-#ifdef USING_DC_MOTORS
+#ifdef USING_DC_MOTORS // deprecated
bool dc_motor;
#endif
uint32_t tickleon;
--- a/cli_BLS_nortos.cpp Sun Sep 29 16:34:37 2019 +0000
+++ b/cli_BLS_nortos.cpp Sat Nov 30 16:34:58 2019 +0000
@@ -446,7 +446,7 @@
void menucmd (struct parameters & a)
{
if (a.respond) {
- a.com->printf("\r\n\nDual BLDC ESC type STM3 2018\r\nAt menucmd function - listing commands, source %s:-\r\n", a.source == SOURCE_PC ? "PC" : "TS");
+ a.com->printf("\r\n\nDual BLDC ESC type STM3 2018-20, Ver %s\r\nAt menucmd function - listing commands, source %s:-\r\n", const_version_string, a.source == SOURCE_PC ? "PC" : "TS");
for(int i = 0; i < a.numof_menu_items; i++)
a.com->printf("[%s]\t\t%s\r\n", a.command_list[i].cmd_word, a.command_list[i].explan);
a.com->printf("End of List of Commands\r\n");
--- a/error_handler.cpp Sun Sep 29 16:34:37 2019 +0000 +++ b/error_handler.cpp Sat Nov 30 16:34:58 2019 +0000 @@ -1,3 +1,8 @@ +/* + 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 "STM3_ESC.h" #include "BufferedSerial.h"