Library for using the TLC5940 as a servo controller.

Dependencies:   FastPWM

Dependents:   TLC5940ServoTest

Committer:
dudanian
Date:
Tue Oct 21 06:26:25 2014 +0000
Revision:
5:56daa8c0697d
Parent:
2:1d2251574d35
Child:
6:b001282e967b
Added mbed official docs for the Server inner class as well as support for the position(float degrees) function from the official mbed class.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudanian 0:9fc434ff7a03 1 #include "TLC5940Servo.h"
dudanian 0:9fc434ff7a03 2
dudanian 2:1d2251574d35 3 TLC5940Servo::TLC5940Servo(PinName MOSI, PinName SCLK, PinName XLAT, PinName BLANK,
dudanian 2:1d2251574d35 4 PinName GSCLK, const int number) : number(number), spi(MOSI, NC, SCLK), gsclk(GSCLK),
dudanian 2:1d2251574d35 5 blank(BLANK), xlat(XLAT), newData(false), need_xlat(false) {
dudanian 0:9fc434ff7a03 6 spi.format(12, 0);
dudanian 0:9fc434ff7a03 7 spi.frequency(SPI_SPEED);
dudanian 2:1d2251574d35 8
dudanian 0:9fc434ff7a03 9 xlat = 0;
dudanian 0:9fc434ff7a03 10 blank = 1;
dudanian 2:1d2251574d35 11
dudanian 0:9fc434ff7a03 12 reset_ticker.attach_us(this, &TLC5940Servo::reset, (1000000.0/GSCLK_SPEED) * 4096.0);
dudanian 2:1d2251574d35 13
dudanian 0:9fc434ff7a03 14 gsclk.period_us(1000000.0/GSCLK_SPEED);
dudanian 0:9fc434ff7a03 15 gsclk.write(.5);
dudanian 0:9fc434ff7a03 16
dudanian 2:1d2251574d35 17 servos = new Servo[16 * number];
dudanian 0:9fc434ff7a03 18 }
dudanian 0:9fc434ff7a03 19
dudanian 2:1d2251574d35 20 TLC5940Servo::~TLC5940Servo() {
dudanian 2:1d2251574d35 21 delete[] servos;
dudanian 2:1d2251574d35 22 }
dudanian 2:1d2251574d35 23
dudanian 2:1d2251574d35 24 void TLC5940Servo::calibrate(int index, float range, float degrees) {
dudanian 2:1d2251574d35 25 servos[index].calibrate(range, degrees);
dudanian 0:9fc434ff7a03 26 }
dudanian 0:9fc434ff7a03 27
dudanian 2:1d2251574d35 28 void TLC5940Servo::calibrate(float range, float degrees) {
dudanian 2:1d2251574d35 29 for (int i = 0; i < 16 * number; i++)
dudanian 2:1d2251574d35 30 servos[i].calibrate(range, degrees);
dudanian 0:9fc434ff7a03 31 }
dudanian 0:9fc434ff7a03 32
dudanian 2:1d2251574d35 33 TLC5940Servo::Servo& TLC5940Servo::operator[](int index) {
dudanian 2:1d2251574d35 34 newData = true;
dudanian 2:1d2251574d35 35 return servos[index];
dudanian 2:1d2251574d35 36 }
dudanian 2:1d2251574d35 37
dudanian 2:1d2251574d35 38 // most complicated method, heavily commented
dudanian 2:1d2251574d35 39 void TLC5940Servo::reset() {
dudanian 0:9fc434ff7a03 40 gsclk.write(0); // turn off gsclk
dudanian 0:9fc434ff7a03 41 blank = 1; // start reset
dudanian 2:1d2251574d35 42
dudanian 0:9fc434ff7a03 43 // latch data if new data was written
dudanian 0:9fc434ff7a03 44 if (need_xlat) {
dudanian 0:9fc434ff7a03 45 xlat = 1;
dudanian 0:9fc434ff7a03 46 xlat = 0;
dudanian 2:1d2251574d35 47
dudanian 0:9fc434ff7a03 48 need_xlat = false;
dudanian 0:9fc434ff7a03 49 }
dudanian 2:1d2251574d35 50
dudanian 0:9fc434ff7a03 51 blank = 0; // turn off reset
dudanian 0:9fc434ff7a03 52 gsclk.write(.5); // restart gsclk
dudanian 0:9fc434ff7a03 53
dudanian 0:9fc434ff7a03 54 if (newData) {
dudanian 2:1d2251574d35 55
dudanian 2:1d2251574d35 56 // Send data backwards - this makes servos[0] index correspond to OUT0
dudanian 2:1d2251574d35 57 for (int i = (16 * number) - 1; i >= 0; i--) {
dudanian 0:9fc434ff7a03 58 // Get the lower 12 bits of the buffer and send
dudanian 2:1d2251574d35 59 spi.write(servos[i].pulsewidth() & 0xFFF);
dudanian 0:9fc434ff7a03 60 }
dudanian 2:1d2251574d35 61
dudanian 0:9fc434ff7a03 62 // Latch after current GS data is done being displayed
dudanian 0:9fc434ff7a03 63 need_xlat = true;
dudanian 2:1d2251574d35 64
dudanian 0:9fc434ff7a03 65 // No new data to send (we just sent it!)
dudanian 0:9fc434ff7a03 66 newData = false;
dudanian 0:9fc434ff7a03 67 }
dudanian 2:1d2251574d35 68 }
dudanian 2:1d2251574d35 69
dudanian 2:1d2251574d35 70 /**
dudanian 2:1d2251574d35 71 * TLC5940 Inner Servo class
dudanian 2:1d2251574d35 72 *
dudanian 2:1d2251574d35 73 * Helps to abstract some of the details away
dudanian 2:1d2251574d35 74 */
dudanian 2:1d2251574d35 75 static float clamp(float value, float min, float max) {
dudanian 2:1d2251574d35 76 if(value < min) {
dudanian 2:1d2251574d35 77 return min;
dudanian 2:1d2251574d35 78 } else if(value > max) {
dudanian 2:1d2251574d35 79 return max;
dudanian 2:1d2251574d35 80 } else {
dudanian 2:1d2251574d35 81 return value;
dudanian 2:1d2251574d35 82 }
dudanian 2:1d2251574d35 83 }
dudanian 2:1d2251574d35 84
dudanian 2:1d2251574d35 85 TLC5940Servo::Servo::Servo() {
dudanian 2:1d2251574d35 86 calibrate();
dudanian 2:1d2251574d35 87 write(0.5);
dudanian 2:1d2251574d35 88 }
dudanian 2:1d2251574d35 89
dudanian 2:1d2251574d35 90 void TLC5940Servo::Servo::write(float percent) {
dudanian 2:1d2251574d35 91 float offset = _range * 2.0 * (percent - 0.5);
dudanian 2:1d2251574d35 92 _pw = (int)(4095 - ((0.0015 + clamp(offset, -_range, _range))/0.02 * 4096.0));
dudanian 2:1d2251574d35 93 _p = clamp(percent, 0.0, 1.0);
dudanian 2:1d2251574d35 94 }
dudanian 2:1d2251574d35 95
dudanian 5:56daa8c0697d 96 void TLC5940Servo::Servo::position(float degrees) {
dudanian 5:56daa8c0697d 97 float offset = _range * (degrees / _degrees);
dudanian 5:56daa8c0697d 98 _pw = (int)(4095 - ((0.0015 + clamp(offset, -_range, _range))/0.02 * 4096.0));
dudanian 5:56daa8c0697d 99 }
dudanian 5:56daa8c0697d 100
dudanian 2:1d2251574d35 101 void TLC5940Servo::Servo::calibrate(float range, float degrees) {
dudanian 2:1d2251574d35 102 _range = range;
dudanian 2:1d2251574d35 103 _degrees = degrees;
dudanian 2:1d2251574d35 104 }
dudanian 2:1d2251574d35 105
dudanian 2:1d2251574d35 106 float TLC5940Servo::Servo::read() {
dudanian 2:1d2251574d35 107 return _p;
dudanian 2:1d2251574d35 108 }
dudanian 2:1d2251574d35 109
dudanian 2:1d2251574d35 110 int TLC5940Servo::Servo::pulsewidth() {
dudanian 2:1d2251574d35 111 return _pw;
dudanian 2:1d2251574d35 112 }
dudanian 2:1d2251574d35 113
dudanian 2:1d2251574d35 114 TLC5940Servo::Servo& TLC5940Servo::Servo::operator= (float percent) {
dudanian 2:1d2251574d35 115 write(percent);
dudanian 2:1d2251574d35 116 return *this;
dudanian 2:1d2251574d35 117 }
dudanian 2:1d2251574d35 118
dudanian 5:56daa8c0697d 119 TLC5940Servo::Servo& TLC5940Servo::Servo::operator= (TLC5940Servo::Servo& rhs) {
dudanian 5:56daa8c0697d 120 write(rhs.read());
dudanian 5:56daa8c0697d 121 return *this;
dudanian 5:56daa8c0697d 122 }
dudanian 5:56daa8c0697d 123
dudanian 2:1d2251574d35 124 TLC5940Servo::Servo::operator float() {
dudanian 2:1d2251574d35 125 return read();
dudanian 2:1d2251574d35 126 }