plus court
Fork of Adafruit-PWM-Servo-Driver by
AFPSD.cpp@4:b439851f9d20, 2017-11-16 (annotated)
- Committer:
- llarquere
- Date:
- Thu Nov 16 18:42:52 2017 +0000
- Revision:
- 4:b439851f9d20
Import
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
llarquere | 4:b439851f9d20 | 1 | /*************************************************** |
llarquere | 4:b439851f9d20 | 2 | This is a library for our Adafruit 16-channel PWM & Servo driver |
llarquere | 4:b439851f9d20 | 3 | Pick one up today in the adafruit shop! |
llarquere | 4:b439851f9d20 | 4 | ------> http://www.adafruit.com/products/815 |
llarquere | 4:b439851f9d20 | 5 | These displays use I2C to communicate, 2 pins are required to |
llarquere | 4:b439851f9d20 | 6 | interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4 |
llarquere | 4:b439851f9d20 | 7 | Adafruit invests time and resources providing this open source code, |
llarquere | 4:b439851f9d20 | 8 | please support Adafruit and open-source hardware by purchasing |
llarquere | 4:b439851f9d20 | 9 | products from Adafruit! |
llarquere | 4:b439851f9d20 | 10 | Written by Limor Fried/Ladyada for Adafruit Industries. |
llarquere | 4:b439851f9d20 | 11 | BSD license, all text above must be included in any redistribution |
llarquere | 4:b439851f9d20 | 12 | ****************************************************/ |
llarquere | 4:b439851f9d20 | 13 | /***************************** |
llarquere | 4:b439851f9d20 | 14 | This program was ported from https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library. |
llarquere | 4:b439851f9d20 | 15 | I also added some functions. |
llarquere | 4:b439851f9d20 | 16 | Shundo Kishi |
llarquere | 4:b439851f9d20 | 17 | *****************************/ |
llarquere | 4:b439851f9d20 | 18 | |
llarquere | 4:b439851f9d20 | 19 | #include "AFPSD.h" |
llarquere | 4:b439851f9d20 | 20 | |
llarquere | 4:b439851f9d20 | 21 | AFPSD::AFPSD( const int addr, I2C* i2c ) { |
llarquere | 4:b439851f9d20 | 22 | _i2c = i2c; |
llarquere | 4:b439851f9d20 | 23 | _devaddr = addr; |
llarquere | 4:b439851f9d20 | 24 | } |
llarquere | 4:b439851f9d20 | 25 | |
llarquere | 4:b439851f9d20 | 26 | void AFPSD::setPrescale( const uint8_t prescale ) { |
llarquere | 4:b439851f9d20 | 27 | uint8_t oldmode = _read8(PCA9685_MODE1); |
llarquere | 4:b439851f9d20 | 28 | uint8_t newmode = (oldmode & 0x7F) | 0x10; // sleep |
llarquere | 4:b439851f9d20 | 29 | #ifdef DEBUGI2C |
llarquere | 4:b439851f9d20 | 30 | printf("ps %02X : %02d\n", _devaddr, prescale); |
llarquere | 4:b439851f9d20 | 31 | #endif |
llarquere | 4:b439851f9d20 | 32 | _write8(PCA9685_MODE1, newmode); // go to sleep |
llarquere | 4:b439851f9d20 | 33 | wait_ms(5); |
llarquere | 4:b439851f9d20 | 34 | _write8(PCA9685_PRESCALE, prescale); // set the prescaler |
llarquere | 4:b439851f9d20 | 35 | _write8(PCA9685_MODE1, oldmode); |
llarquere | 4:b439851f9d20 | 36 | wait_ms(5); |
llarquere | 4:b439851f9d20 | 37 | _write8(PCA9685_MODE1, oldmode | 0xA1); |
llarquere | 4:b439851f9d20 | 38 | } |
llarquere | 4:b439851f9d20 | 39 | |
llarquere | 4:b439851f9d20 | 40 | void AFPSD::setPWMFreq( const float freq ) { |
llarquere | 4:b439851f9d20 | 41 | //Serial.print("Attempting to set freq "); |
llarquere | 4:b439851f9d20 | 42 | //Serial.println(freq); |
llarquere | 4:b439851f9d20 | 43 | float prescaleval = 25000000; |
llarquere | 4:b439851f9d20 | 44 | prescaleval /= 4096; |
llarquere | 4:b439851f9d20 | 45 | prescaleval /= freq; |
llarquere | 4:b439851f9d20 | 46 | //Serial.print("Estimated pre-scale: "); Serial.println(prescaleval); |
llarquere | 4:b439851f9d20 | 47 | uint8_t prescale = floor(prescaleval + 0.5f) - 1; |
llarquere | 4:b439851f9d20 | 48 | //Serial.print("Final pre-scale: "); Serial.println(prescale); |
llarquere | 4:b439851f9d20 | 49 | setPrescale(prescale); |
llarquere | 4:b439851f9d20 | 50 | } |
llarquere | 4:b439851f9d20 | 51 | |
llarquere | 4:b439851f9d20 | 52 | void AFPSD::setPWM( const uint8_t pin, const uint16_t on, const uint16_t off ) { |
llarquere | 4:b439851f9d20 | 53 | // hmm doesnt work, whyso? ( Not in AI mode. See line 54 above. ( Works now!! :D ) |
llarquere | 4:b439851f9d20 | 54 | char cmd[5]; |
llarquere | 4:b439851f9d20 | 55 | cmd[0] = LED0_ON_L + 4 * pin; |
llarquere | 4:b439851f9d20 | 56 | cmd[1] = on; |
llarquere | 4:b439851f9d20 | 57 | cmd[2] = on >> 8; |
llarquere | 4:b439851f9d20 | 58 | cmd[3] = off; |
llarquere | 4:b439851f9d20 | 59 | cmd[4] = off >> 8; |
llarquere | 4:b439851f9d20 | 60 | _i2c->write(_devaddr, cmd, 5); |
llarquere | 4:b439851f9d20 | 61 | #ifdef DEBUGI2C |
llarquere | 4:b439851f9d20 | 62 | printf("pwm %02X : %02X %02X %02X %02X %02X\n", _devaddr, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); |
llarquere | 4:b439851f9d20 | 63 | #endif |
llarquere | 4:b439851f9d20 | 64 | /*write8(LED0_ON_L+4*num, on); |
llarquere | 4:b439851f9d20 | 65 | write8(LED0_ON_H+4*num, on >> 8); |
llarquere | 4:b439851f9d20 | 66 | write8(LED0_OFF_L+4*num, off); |
llarquere | 4:b439851f9d20 | 67 | write8(LED0_OFF_H+4*num, off >> 8);*/ |
llarquere | 4:b439851f9d20 | 68 | } |
llarquere | 4:b439851f9d20 | 69 | |
llarquere | 4:b439851f9d20 | 70 | // Set pwm duty in us order |
llarquere | 4:b439851f9d20 | 71 | void AFPSD::setDuty( const uint8_t pin, uint16_t duty ) { |
llarquere | 4:b439851f9d20 | 72 | float pulselength = 10000; // 10,000 us per second |
llarquere | 4:b439851f9d20 | 73 | duty = 4094 * duty / pulselength; |
llarquere | 4:b439851f9d20 | 74 | setPWM(pin, 0, duty); |
llarquere | 4:b439851f9d20 | 75 | } |
llarquere | 4:b439851f9d20 | 76 | |
llarquere | 4:b439851f9d20 | 77 | uint8_t AFPSD::_read8( const char pin ) { |
llarquere | 4:b439851f9d20 | 78 | _i2c->write(_devaddr, &pin, 1); |
llarquere | 4:b439851f9d20 | 79 | #ifdef DEBUGI2C |
llarquere | 4:b439851f9d20 | 80 | printf("r8w %02X : %02X\n", _devaddr, pin); |
llarquere | 4:b439851f9d20 | 81 | #endif |
llarquere | 4:b439851f9d20 | 82 | char rtn; |
llarquere | 4:b439851f9d20 | 83 | _i2c->read(_devaddr, &rtn, 1); |
llarquere | 4:b439851f9d20 | 84 | #ifdef DEBUGI2C |
llarquere | 4:b439851f9d20 | 85 | printf("r8r %02X : %02X\n", _devaddr, rtn); |
llarquere | 4:b439851f9d20 | 86 | #endif |
llarquere | 4:b439851f9d20 | 87 | return rtn; |
llarquere | 4:b439851f9d20 | 88 | } |
llarquere | 4:b439851f9d20 | 89 | |
llarquere | 4:b439851f9d20 | 90 | void AFPSD::_write8( const char pin, const char d ) { |
llarquere | 4:b439851f9d20 | 91 | char cmd[2]; |
llarquere | 4:b439851f9d20 | 92 | cmd[0] = pin; |
llarquere | 4:b439851f9d20 | 93 | cmd[1] = d; |
llarquere | 4:b439851f9d20 | 94 | _i2c->write(_devaddr, cmd, 2); |
llarquere | 4:b439851f9d20 | 95 | #ifdef DEBUGI2C |
llarquere | 4:b439851f9d20 | 96 | printf("w8 %02X : %02X %02X\n", _devaddr, cmd[0], cmd[1]); |
llarquere | 4:b439851f9d20 | 97 | #endif |
llarquere | 4:b439851f9d20 | 98 | } |