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
24LC64_eeprom.cpp@3:ecb00e0e8d68, 2018-03-18 (annotated)
- 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?
User | Revision | Line number | New 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 | } |