Library for using the TLC5940 as a servo controller.

Dependencies:   FastPWM

Dependents:   TLC5940ServoTest

Committer:
dudanian
Date:
Tue Oct 21 06:04:24 2014 +0000
Revision:
2:1d2251574d35
Parent:
0:9fc434ff7a03
Child:
5:56daa8c0697d
Big changes to the code. Removed Servo files and made an inner class inside TLC5940Servo.

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 // used source code, but converted pwm pulse to 12 bit value
dudanian 2:1d2251574d35 91 // assuming 20ms period, divide to get percentage and multiply to get value
dudanian 2:1d2251574d35 92 void TLC5940Servo::Servo::write(float percent) {
dudanian 2:1d2251574d35 93 float offset = _range * 2.0 * (percent - 0.5);
dudanian 2:1d2251574d35 94 _pw = (int)(4095 - ((0.0015 + clamp(offset, -_range, _range))/0.02 * 4096.0));
dudanian 2:1d2251574d35 95 _p = clamp(percent, 0.0, 1.0);
dudanian 2:1d2251574d35 96 }
dudanian 2:1d2251574d35 97
dudanian 2:1d2251574d35 98 void TLC5940Servo::Servo::calibrate(float range, float degrees) {
dudanian 2:1d2251574d35 99 _range = range;
dudanian 2:1d2251574d35 100 _degrees = degrees;
dudanian 2:1d2251574d35 101 }
dudanian 2:1d2251574d35 102
dudanian 2:1d2251574d35 103 float TLC5940Servo::Servo::read() {
dudanian 2:1d2251574d35 104 return _p;
dudanian 2:1d2251574d35 105 }
dudanian 2:1d2251574d35 106
dudanian 2:1d2251574d35 107 int TLC5940Servo::Servo::pulsewidth() {
dudanian 2:1d2251574d35 108 return _pw;
dudanian 2:1d2251574d35 109 }
dudanian 2:1d2251574d35 110
dudanian 2:1d2251574d35 111 TLC5940Servo::Servo& TLC5940Servo::Servo::operator= (float percent) {
dudanian 2:1d2251574d35 112 write(percent);
dudanian 2:1d2251574d35 113 return *this;
dudanian 2:1d2251574d35 114 }
dudanian 2:1d2251574d35 115
dudanian 2:1d2251574d35 116 TLC5940Servo::Servo::operator float() {
dudanian 2:1d2251574d35 117 return read();
dudanian 2:1d2251574d35 118 }