A simple I2C library for ESCs using the Blue Robotics version of SimonK's TGY firmware (https://github.com/bluerobotics/tgy). This library supports the BlueESC, but also the Afro Nfet 30A. I2C is an alternative interface for micro-controllers, rather than using PWM (as a servo) -- this provides some additional features like temperature level, RPM, etc.

Dependents:   SimonK_I2C_ESC_Example

Example program here:

Import programSimonK_I2C_ESC_Example

Simple example for the SimonK_I2C_ESC. Tested on the FRDM K64F.

Additional guidance is provided in the Wiki

Committer:
azazeal88
Date:
Sat Apr 02 11:44:14 2016 +0000
Revision:
4:014606ea57a3
Parent:
1:7efb04a9c0dd
Fixed RPM overflow issue because of timer

Who changed what in which revision?

UserRevisionLine numberNew contents of line
azazeal88 0:41ddae212f64 1 #include "SimonK_I2C_ESC.h"
azazeal88 0:41ddae212f64 2
azazeal88 0:41ddae212f64 3 namespace {
azazeal88 0:41ddae212f64 4 char _buffer[9];
azazeal88 0:41ddae212f64 5 }
azazeal88 0:41ddae212f64 6
azazeal88 0:41ddae212f64 7 SimonK_I2C_ESC::SimonK_I2C_ESC(I2C &i2c, char address, char poleCount) : _i2c(i2c){
azazeal88 1:7efb04a9c0dd 8 _address = address << 1;
azazeal88 0:41ddae212f64 9 _poleCount = poleCount;
azazeal88 0:41ddae212f64 10 // A timer is needed to calculate the RPM.
azazeal88 0:41ddae212f64 11 mbed_rpm_timer.start();
azazeal88 0:41ddae212f64 12 _rpmTimer = mbed_rpm_timer.read_ms();
azazeal88 0:41ddae212f64 13 }
azazeal88 0:41ddae212f64 14
azazeal88 0:41ddae212f64 15 // Read the incoming data buffer from an ESC
azazeal88 0:41ddae212f64 16 void SimonK_I2C_ESC::readBuffer(char buffer[]) {
azazeal88 0:41ddae212f64 17 char readStartAddress = 0x02;
azazeal88 0:41ddae212f64 18 _i2c.write(_address,&readStartAddress,1,false);
azazeal88 0:41ddae212f64 19 _i2c.read(_address,buffer,9);
azazeal88 0:41ddae212f64 20 }
azazeal88 0:41ddae212f64 21
azazeal88 0:41ddae212f64 22 // Send motor speed command to ESC
azazeal88 0:41ddae212f64 23 void SimonK_I2C_ESC::set(short throttle) {
azazeal88 0:41ddae212f64 24 char throttleData[3];
azazeal88 0:41ddae212f64 25 throttleData[0] = 0x00; // Throttle Start Address
azazeal88 0:41ddae212f64 26 throttleData[1] = throttle>>8;
azazeal88 0:41ddae212f64 27 throttleData[2] = throttle;
azazeal88 1:7efb04a9c0dd 28 _i2c.write(_address, throttleData, 3, false);
azazeal88 0:41ddae212f64 29 }
azazeal88 0:41ddae212f64 30
azazeal88 0:41ddae212f64 31 // Send motor speed command to ESC
azazeal88 0:41ddae212f64 32 void SimonK_I2C_ESC::setPWM(short pwm) {
azazeal88 0:41ddae212f64 33 set((pwm - 1100) * (32767 - -32767) / (1900 - 1100) + -32767);
azazeal88 0:41ddae212f64 34 }
azazeal88 0:41ddae212f64 35
azazeal88 0:41ddae212f64 36 void SimonK_I2C_ESC::update() {
azazeal88 0:41ddae212f64 37 _buffer[8] = 0x00; // Reset last byte so we can check for alive
azazeal88 0:41ddae212f64 38 readBuffer(_buffer);
azazeal88 0:41ddae212f64 39 _rpm = (_buffer[0] << 8) | _buffer[1];
azazeal88 0:41ddae212f64 40 _voltage_raw = (_buffer[2] << 8) | _buffer[3];
azazeal88 0:41ddae212f64 41 _temp_raw = (_buffer[4] << 8) | _buffer[5];
azazeal88 0:41ddae212f64 42 _current_raw = (_buffer[6] << 8) | _buffer[7];
azazeal88 0:41ddae212f64 43 _identifier = _buffer[8];
azazeal88 4:014606ea57a3 44 _rpm = float(_rpm) / (abs( mbed_rpm_timer.read_ms() -_rpmTimer)/1000.0f)*60/ float(_poleCount);
azazeal88 0:41ddae212f64 45 _rpmTimer = mbed_rpm_timer.read_ms();
azazeal88 0:41ddae212f64 46 }
azazeal88 0:41ddae212f64 47
azazeal88 0:41ddae212f64 48 bool SimonK_I2C_ESC::isAlive() {
azazeal88 0:41ddae212f64 49 return (_identifier == 0xab);
azazeal88 0:41ddae212f64 50 }
azazeal88 0:41ddae212f64 51
azazeal88 0:41ddae212f64 52 float SimonK_I2C_ESC::voltage() {
azazeal88 0:41ddae212f64 53 return float(_voltage_raw)/65536.0f*5.0f*6.45f;
azazeal88 0:41ddae212f64 54 }
azazeal88 0:41ddae212f64 55
azazeal88 0:41ddae212f64 56 float SimonK_I2C_ESC::current() {
azazeal88 0:41ddae212f64 57 return (float(_current_raw)-32767)/65535.0f*5.0f*14.706f;
azazeal88 0:41ddae212f64 58 }
azazeal88 0:41ddae212f64 59
azazeal88 0:41ddae212f64 60 float SimonK_I2C_ESC::temperature() {
azazeal88 0:41ddae212f64 61 // This code was taken from an Adafruit
azazeal88 0:41ddae212f64 62 float resistance = SERIESRESISTOR/(65535/float(_temp_raw)-1);
azazeal88 0:41ddae212f64 63
azazeal88 0:41ddae212f64 64 float steinhart;
azazeal88 0:41ddae212f64 65 steinhart = resistance / THERMISTORNOMINAL; // (R/Ro)
azazeal88 0:41ddae212f64 66 steinhart = log(steinhart); // ln(R/Ro)
azazeal88 0:41ddae212f64 67 steinhart /= BCOEFFICIENT; // 1/B * ln(R/Ro)
azazeal88 0:41ddae212f64 68 steinhart += float(1.0) / (TEMPERATURENOMINAL + 273.15); // + (1/To)
azazeal88 0:41ddae212f64 69 steinhart = float (1.0) / steinhart; // Invert
azazeal88 0:41ddae212f64 70 steinhart -= float(273.15); // convert to C
azazeal88 0:41ddae212f64 71
azazeal88 0:41ddae212f64 72 return steinhart;
azazeal88 0:41ddae212f64 73 }
azazeal88 0:41ddae212f64 74
azazeal88 0:41ddae212f64 75 short SimonK_I2C_ESC::rpm() {
azazeal88 0:41ddae212f64 76 return _rpm;
azazeal88 0:41ddae212f64 77 }