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 Mar 18 08:17:56 2018 +0000
Revision:
3:ecb00e0e8d68
Parent:
1:0fabe6fdb55b
Child:
12:d1d21a2941ef
Starting motors requires high-side mosfet drivers being enabled. Auto tickleup functions now included to switch high sides off and on again to charge high side supply capacitors (now 2u2, up from 100n)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JonFreeman 0:435bf84ce48a 1 #include "mbed.h"
JonFreeman 0:435bf84ce48a 2 //#include "rtos.h"
JonFreeman 0:435bf84ce48a 3 #include "BufferedSerial.h"
JonFreeman 0:435bf84ce48a 4 extern BufferedSerial pc;
JonFreeman 0:435bf84ce48a 5 extern I2C i2c;
JonFreeman 3:ecb00e0e8d68 6 // Code for 24LC64 8k x 8 bit eeprom
JonFreeman 0:435bf84ce48a 7 // Code based on earlier work using memory FM24W256, also at i2c address 0xa0;
JonFreeman 0:435bf84ce48a 8
JonFreeman 0:435bf84ce48a 9 const int addr_rd = 0xa1; // set bit 0 for read, clear bit 0 for write
JonFreeman 0:435bf84ce48a 10 const int addr_wr = 0xa0; // set bit 0 for read, clear bit 0 for write
JonFreeman 0:435bf84ce48a 11 const int ACK = 1;
JonFreeman 0:435bf84ce48a 12
JonFreeman 0:435bf84ce48a 13 bool ack_poll () { // wait short while for any previous memory operation to complete
JonFreeman 0:435bf84ce48a 14 const int poll_tries = 40;
JonFreeman 0:435bf84ce48a 15 int poll_count = 0;
JonFreeman 0:435bf84ce48a 16 bool i2cfree = false;
JonFreeman 0:435bf84ce48a 17 while (poll_count++ < poll_tries && !i2cfree) {
JonFreeman 0:435bf84ce48a 18 i2c.start ();
JonFreeman 0:435bf84ce48a 19 if (i2c.write(addr_wr) == ACK)
JonFreeman 0:435bf84ce48a 20 i2cfree = true;
JonFreeman 0:435bf84ce48a 21 else
JonFreeman 0:435bf84ce48a 22 // Thread::wait(1); // 1ms
JonFreeman 3:ecb00e0e8d68 23 wait_ms (1);
JonFreeman 0:435bf84ce48a 24 }
JonFreeman 0:435bf84ce48a 25 // pc.printf ("ack_poll, count = %d, i2cfree = %s\r\n", poll_count, i2cfree ? "true" : "false");
JonFreeman 0:435bf84ce48a 26 return i2cfree;
JonFreeman 0:435bf84ce48a 27 }
JonFreeman 0:435bf84ce48a 28
JonFreeman 0:435bf84ce48a 29 bool set_24LC64_internal_address (int start_addr) {
JonFreeman 0:435bf84ce48a 30 if (!ack_poll())
JonFreeman 0:435bf84ce48a 31 {
JonFreeman 0:435bf84ce48a 32 pc.printf ("Err in set_24LC64_internal_address, no ACK writing device address byte\r\n");
JonFreeman 0:435bf84ce48a 33 i2c.stop();
JonFreeman 0:435bf84ce48a 34 return false;
JonFreeman 0:435bf84ce48a 35 }
JonFreeman 0:435bf84ce48a 36 int err = 0;
JonFreeman 0:435bf84ce48a 37 if (i2c.write(start_addr >> 8) != ACK) err++;
JonFreeman 0:435bf84ce48a 38 if (i2c.write(start_addr & 0xff) != ACK) err++;
JonFreeman 0:435bf84ce48a 39 if (err) {
JonFreeman 0:435bf84ce48a 40 pc.printf ("In set_24LC64_internal_address, Believe Device present, failed in writing 2 mem addr bytes %d\r\n", err);
JonFreeman 0:435bf84ce48a 41 i2c.stop();
JonFreeman 0:435bf84ce48a 42 return false;
JonFreeman 0:435bf84ce48a 43 }
JonFreeman 0:435bf84ce48a 44 return true;
JonFreeman 0:435bf84ce48a 45 }
JonFreeman 0:435bf84ce48a 46
JonFreeman 0:435bf84ce48a 47 bool wr_24LC64 (int start_addr, char * source, int length) {
JonFreeman 0:435bf84ce48a 48 int err = 0;
JonFreeman 0:435bf84ce48a 49 if(length < 1 || length > 32) {
JonFreeman 0:435bf84ce48a 50 pc.printf ("Length out of range %d in wr_24LC64\r\n", length);
JonFreeman 0:435bf84ce48a 51 return false;
JonFreeman 0:435bf84ce48a 52 }
JonFreeman 3:ecb00e0e8d68 53 ack_poll ();
JonFreeman 0:435bf84ce48a 54 if (!set_24LC64_internal_address (start_addr)) {
JonFreeman 0:435bf84ce48a 55 pc.printf ("In wr_24LC64, Believe Device present, failed in writing 2 mem addr bytes %d\r\n", err);
JonFreeman 0:435bf84ce48a 56 return false;
JonFreeman 0:435bf84ce48a 57 }
JonFreeman 0:435bf84ce48a 58 while(length--)
JonFreeman 0:435bf84ce48a 59 err += ACK - i2c.write(*source++);
JonFreeman 0:435bf84ce48a 60 i2c.stop();
JonFreeman 0:435bf84ce48a 61 if (err) {
JonFreeman 0:435bf84ce48a 62 pc.printf ("in wr_24LC64, device thought good, mem addr write worked, failed writing string\r\n");
JonFreeman 0:435bf84ce48a 63 return false;
JonFreeman 0:435bf84ce48a 64 }
JonFreeman 0:435bf84ce48a 65 pc.printf ("In wr_24LC64 No Errors Found!\r\n");
JonFreeman 0:435bf84ce48a 66 return true;
JonFreeman 0:435bf84ce48a 67 }
JonFreeman 0:435bf84ce48a 68
JonFreeman 0:435bf84ce48a 69 bool rd_24LC64 (int start_addr, char * dest, int length) {
JonFreeman 0:435bf84ce48a 70 int acknak = ACK;
JonFreeman 0:435bf84ce48a 71 if(length < 1)
JonFreeman 0:435bf84ce48a 72 return false;
JonFreeman 0:435bf84ce48a 73 if (!set_24LC64_internal_address (start_addr)) {
JonFreeman 0:435bf84ce48a 74 pc.printf ("In rd_24LC64, failed to set_ramaddr\r\n");
JonFreeman 0:435bf84ce48a 75 return false;
JonFreeman 0:435bf84ce48a 76 }
JonFreeman 0:435bf84ce48a 77 i2c.start();
JonFreeman 0:435bf84ce48a 78 if (i2c.write(addr_rd) != ACK) {
JonFreeman 0:435bf84ce48a 79 pc.printf ("Errors in rd_24LC64 sending addr_rd\r\n");
JonFreeman 0:435bf84ce48a 80 return false;
JonFreeman 0:435bf84ce48a 81 }
JonFreeman 0:435bf84ce48a 82 while(length--) {
JonFreeman 0:435bf84ce48a 83 if(length == 0)
JonFreeman 0:435bf84ce48a 84 acknak = 0;
JonFreeman 0:435bf84ce48a 85 *dest++ = i2c.read(acknak);
JonFreeman 0:435bf84ce48a 86 }
JonFreeman 0:435bf84ce48a 87 i2c.stop();
JonFreeman 0:435bf84ce48a 88 return true;
JonFreeman 0:435bf84ce48a 89 }
JonFreeman 0:435bf84ce48a 90
JonFreeman 0:435bf84ce48a 91 int check_24LC64 () { // Call from near top of main() to init i2c bus
JonFreeman 1:0fabe6fdb55b 92 // i2c.frequency(400000); // Speed 400000 max.
JonFreeman 0:435bf84ce48a 93 i2c.frequency(400000); // Speed 400000 max.
JonFreeman 0:435bf84ce48a 94 int last_found = 0, q; // Note address bits 3-1 to match addr pins on device
JonFreeman 0:435bf84ce48a 95 for (int i = 0; i < 255; i += 2) { // Search for devices at all possible i2c addresses
JonFreeman 0:435bf84ce48a 96 i2c.start();
JonFreeman 0:435bf84ce48a 97 q = i2c.write(i); // may return error code 2 when no start issued
JonFreeman 0:435bf84ce48a 98 switch (q) {
JonFreeman 0:435bf84ce48a 99 case ACK:
JonFreeman 0:435bf84ce48a 100 pc.printf ("I2C device found at 0x%x\r\n", i);
JonFreeman 0:435bf84ce48a 101 last_found = i;
JonFreeman 0:435bf84ce48a 102 case 2: // Device not seen at this address
JonFreeman 0:435bf84ce48a 103 break;
JonFreeman 0:435bf84ce48a 104 default:
JonFreeman 0:435bf84ce48a 105 pc.printf ("Unknown error %d in check_24LC64\r\n", q);
JonFreeman 0:435bf84ce48a 106 break;
JonFreeman 0:435bf84ce48a 107 }
JonFreeman 0:435bf84ce48a 108 }
JonFreeman 0:435bf84ce48a 109 i2c.stop();
JonFreeman 0:435bf84ce48a 110 return last_found;
JonFreeman 0:435bf84ce48a 111 }