plus court
Fork of Adafruit-PWM-Servo-Driver by
AFPSD.cpp
- Committer:
- llarquere
- Date:
- 2017-11-16
- Revision:
- 4:b439851f9d20
File content as of revision 4:b439851f9d20:
/*************************************************** This is a library for our Adafruit 16-channel PWM & Servo driver Pick one up today in the adafruit shop! ------> http://www.adafruit.com/products/815 These displays use I2C to communicate, 2 pins are required to interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4 Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution ****************************************************/ /***************************** This program was ported from https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library. I also added some functions. Shundo Kishi *****************************/ #include "AFPSD.h" AFPSD::AFPSD( const int addr, I2C* i2c ) { _i2c = i2c; _devaddr = addr; } void AFPSD::setPrescale( const uint8_t prescale ) { uint8_t oldmode = _read8(PCA9685_MODE1); uint8_t newmode = (oldmode & 0x7F) | 0x10; // sleep #ifdef DEBUGI2C printf("ps %02X : %02d\n", _devaddr, prescale); #endif _write8(PCA9685_MODE1, newmode); // go to sleep wait_ms(5); _write8(PCA9685_PRESCALE, prescale); // set the prescaler _write8(PCA9685_MODE1, oldmode); wait_ms(5); _write8(PCA9685_MODE1, oldmode | 0xA1); } void AFPSD::setPWMFreq( const float freq ) { //Serial.print("Attempting to set freq "); //Serial.println(freq); float prescaleval = 25000000; prescaleval /= 4096; prescaleval /= freq; //Serial.print("Estimated pre-scale: "); Serial.println(prescaleval); uint8_t prescale = floor(prescaleval + 0.5f) - 1; //Serial.print("Final pre-scale: "); Serial.println(prescale); setPrescale(prescale); } void AFPSD::setPWM( const uint8_t pin, const uint16_t on, const uint16_t off ) { // hmm doesnt work, whyso? ( Not in AI mode. See line 54 above. ( Works now!! :D ) char cmd[5]; cmd[0] = LED0_ON_L + 4 * pin; cmd[1] = on; cmd[2] = on >> 8; cmd[3] = off; cmd[4] = off >> 8; _i2c->write(_devaddr, cmd, 5); #ifdef DEBUGI2C printf("pwm %02X : %02X %02X %02X %02X %02X\n", _devaddr, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); #endif /*write8(LED0_ON_L+4*num, on); write8(LED0_ON_H+4*num, on >> 8); write8(LED0_OFF_L+4*num, off); write8(LED0_OFF_H+4*num, off >> 8);*/ } // Set pwm duty in us order void AFPSD::setDuty( const uint8_t pin, uint16_t duty ) { float pulselength = 10000; // 10,000 us per second duty = 4094 * duty / pulselength; setPWM(pin, 0, duty); } uint8_t AFPSD::_read8( const char pin ) { _i2c->write(_devaddr, &pin, 1); #ifdef DEBUGI2C printf("r8w %02X : %02X\n", _devaddr, pin); #endif char rtn; _i2c->read(_devaddr, &rtn, 1); #ifdef DEBUGI2C printf("r8r %02X : %02X\n", _devaddr, rtn); #endif return rtn; } void AFPSD::_write8( const char pin, const char d ) { char cmd[2]; cmd[0] = pin; cmd[1] = d; _i2c->write(_devaddr, cmd, 2); #ifdef DEBUGI2C printf("w8 %02X : %02X %02X\n", _devaddr, cmd[0], cmd[1]); #endif }