Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Adafruit-PWM-Servo-Driver by
Adafruit_PWMServoDriver.cpp@3:07497eda12c2, 2017-11-14 (annotated)
- Committer:
- fixair
- Date:
- Tue Nov 14 18:06:44 2017 +0000
- Revision:
- 3:07497eda12c2
- Parent:
- 2:88bdd5c4e77b
test spd15
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
syundo0730 | 0:9d01b5d37adc | 1 | /*************************************************** |
syundo0730 | 0:9d01b5d37adc | 2 | This is a library for our Adafruit 16-channel PWM & Servo driver |
syundo0730 | 0:9d01b5d37adc | 3 | |
syundo0730 | 0:9d01b5d37adc | 4 | Pick one up today in the adafruit shop! |
syundo0730 | 0:9d01b5d37adc | 5 | ------> http://www.adafruit.com/products/815 |
syundo0730 | 0:9d01b5d37adc | 6 | |
syundo0730 | 0:9d01b5d37adc | 7 | These displays use I2C to communicate, 2 pins are required to |
syundo0730 | 0:9d01b5d37adc | 8 | interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4 |
syundo0730 | 0:9d01b5d37adc | 9 | |
syundo0730 | 0:9d01b5d37adc | 10 | Adafruit invests time and resources providing this open source code, |
syundo0730 | 0:9d01b5d37adc | 11 | please support Adafruit and open-source hardware by purchasing |
syundo0730 | 0:9d01b5d37adc | 12 | products from Adafruit! |
syundo0730 | 0:9d01b5d37adc | 13 | |
syundo0730 | 0:9d01b5d37adc | 14 | Written by Limor Fried/Ladyada for Adafruit Industries. |
syundo0730 | 0:9d01b5d37adc | 15 | BSD license, all text above must be included in any redistribution |
syundo0730 | 0:9d01b5d37adc | 16 | ****************************************************/ |
syundo0730 | 0:9d01b5d37adc | 17 | |
syundo0730 | 0:9d01b5d37adc | 18 | /***************************** |
syundo0730 | 0:9d01b5d37adc | 19 | This program was ported from https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library. |
syundo0730 | 0:9d01b5d37adc | 20 | I also added some functions. |
syundo0730 | 0:9d01b5d37adc | 21 | Shundo Kishi |
syundo0730 | 0:9d01b5d37adc | 22 | *****************************/ |
syundo0730 | 0:9d01b5d37adc | 23 | |
syundo0730 | 0:9d01b5d37adc | 24 | #include "Adafruit_PWMServoDriver.h" |
syundo0730 | 0:9d01b5d37adc | 25 | |
fixair | 3:07497eda12c2 | 26 | //Adafruit_PWMServoDriver::Adafruit_PWMServoDriver(PinName sda, PinName scl, int addr) : i2c(sda, scl), _i2caddr(addr) {} |
fixair | 3:07497eda12c2 | 27 | |
fixair | 3:07497eda12c2 | 28 | Adafruit_PWMServoDriver::Adafruit_PWMServoDriver(PinName sda, PinName scl, int addr) { |
fixair | 3:07497eda12c2 | 29 | i2c = new I2C(sda, scl); |
fixair | 3:07497eda12c2 | 30 | _i2caddr = addr; |
fixair | 3:07497eda12c2 | 31 | } |
syundo0730 | 0:9d01b5d37adc | 32 | |
syundo0730 | 0:9d01b5d37adc | 33 | void Adafruit_PWMServoDriver::i2c_probe(void) |
syundo0730 | 0:9d01b5d37adc | 34 | { |
fixair | 3:07497eda12c2 | 35 | printf("Probing I2C devices...\n"); |
syundo0730 | 0:9d01b5d37adc | 36 | |
syundo0730 | 0:9d01b5d37adc | 37 | int count = 0; |
fixair | 3:07497eda12c2 | 38 | for (int address=1; address<256; address+=1) { |
fixair | 3:07497eda12c2 | 39 | if (!i2c->write(address, NULL, 0)) { // 0 returned is ok |
syundo0730 | 0:9d01b5d37adc | 40 | printf(" - I2C device found at address 0x%02X\r\n", address); |
syundo0730 | 0:9d01b5d37adc | 41 | count++; |
syundo0730 | 0:9d01b5d37adc | 42 | } |
syundo0730 | 0:9d01b5d37adc | 43 | } |
syundo0730 | 0:9d01b5d37adc | 44 | printf("%d devices found\r\n", count); |
syundo0730 | 0:9d01b5d37adc | 45 | } |
syundo0730 | 0:9d01b5d37adc | 46 | |
syundo0730 | 0:9d01b5d37adc | 47 | void Adafruit_PWMServoDriver::begin(void) { |
syundo0730 | 0:9d01b5d37adc | 48 | reset(); |
syundo0730 | 0:9d01b5d37adc | 49 | } |
syundo0730 | 0:9d01b5d37adc | 50 | |
syundo0730 | 0:9d01b5d37adc | 51 | void Adafruit_PWMServoDriver::setI2Cfreq(int freq) { |
fixair | 3:07497eda12c2 | 52 | i2c->frequency(freq); |
syundo0730 | 0:9d01b5d37adc | 53 | } |
syundo0730 | 0:9d01b5d37adc | 54 | |
syundo0730 | 0:9d01b5d37adc | 55 | void Adafruit_PWMServoDriver::reset(void) { |
syundo0730 | 0:9d01b5d37adc | 56 | write8(PCA9685_MODE1, 0x0); |
syundo0730 | 0:9d01b5d37adc | 57 | } |
syundo0730 | 0:9d01b5d37adc | 58 | |
syundo0730 | 0:9d01b5d37adc | 59 | void Adafruit_PWMServoDriver::setPrescale(uint8_t prescale) { |
syundo0730 | 0:9d01b5d37adc | 60 | uint8_t oldmode = read8(PCA9685_MODE1); |
syundo0730 | 0:9d01b5d37adc | 61 | uint8_t newmode = (oldmode&0x7F) | 0x10; // sleep |
syundo0730 | 0:9d01b5d37adc | 62 | write8(PCA9685_MODE1, newmode); // go to sleep |
syundo0730 | 0:9d01b5d37adc | 63 | wait_ms(5); |
syundo0730 | 0:9d01b5d37adc | 64 | write8(PCA9685_PRESCALE, prescale); // set the prescaler |
syundo0730 | 0:9d01b5d37adc | 65 | write8(PCA9685_MODE1, oldmode); |
syundo0730 | 0:9d01b5d37adc | 66 | wait_ms(5); |
syundo0730 | 0:9d01b5d37adc | 67 | write8(PCA9685_MODE1, oldmode | 0xa1); |
syundo0730 | 0:9d01b5d37adc | 68 | } |
syundo0730 | 0:9d01b5d37adc | 69 | |
syundo0730 | 0:9d01b5d37adc | 70 | void Adafruit_PWMServoDriver::setPWMFreq(float freq) { |
syundo0730 | 0:9d01b5d37adc | 71 | //Serial.print("Attempting to set freq "); |
syundo0730 | 0:9d01b5d37adc | 72 | //Serial.println(freq); |
syundo0730 | 0:9d01b5d37adc | 73 | float prescaleval = 25000000; |
syundo0730 | 0:9d01b5d37adc | 74 | prescaleval /= 4096; |
syundo0730 | 0:9d01b5d37adc | 75 | prescaleval /= freq; |
syundo0730 | 0:9d01b5d37adc | 76 | //Serial.print("Estimated pre-scale: "); Serial.println(prescaleval); |
syundo0730 | 0:9d01b5d37adc | 77 | uint8_t prescale = floor(prescaleval + 0.5) - 1; |
syundo0730 | 0:9d01b5d37adc | 78 | //Serial.print("Final pre-scale: "); Serial.println(prescale); |
syundo0730 | 0:9d01b5d37adc | 79 | setPrescale(prescale); |
syundo0730 | 0:9d01b5d37adc | 80 | } |
syundo0730 | 0:9d01b5d37adc | 81 | |
syundo0730 | 0:9d01b5d37adc | 82 | void Adafruit_PWMServoDriver::setPWM(uint8_t num, uint16_t on, uint16_t off) { |
syundo0730 | 0:9d01b5d37adc | 83 | // hmm doesnt work, whyso? ( Not in AI mode. See line 54 above. ( Works now!! :D ) |
syundo0730 | 0:9d01b5d37adc | 84 | |
syundo0730 | 0:9d01b5d37adc | 85 | char cmd[5]; |
syundo0730 | 0:9d01b5d37adc | 86 | cmd[0] = LED0_ON_L + 4 * num; |
syundo0730 | 0:9d01b5d37adc | 87 | cmd[1] = on; |
syundo0730 | 0:9d01b5d37adc | 88 | cmd[2] = on >> 8; |
syundo0730 | 0:9d01b5d37adc | 89 | cmd[3] = off; |
syundo0730 | 0:9d01b5d37adc | 90 | cmd[4] = off >> 8; |
fixair | 3:07497eda12c2 | 91 | i2c->write(_i2caddr, cmd, 5); |
syundo0730 | 0:9d01b5d37adc | 92 | |
syundo0730 | 0:9d01b5d37adc | 93 | /*write8(LED0_ON_L+4*num, on); |
syundo0730 | 0:9d01b5d37adc | 94 | write8(LED0_ON_H+4*num, on >> 8); |
syundo0730 | 0:9d01b5d37adc | 95 | write8(LED0_OFF_L+4*num, off); |
syundo0730 | 0:9d01b5d37adc | 96 | write8(LED0_OFF_H+4*num, off >> 8);*/ |
syundo0730 | 0:9d01b5d37adc | 97 | } |
syundo0730 | 0:9d01b5d37adc | 98 | |
syundo0730 | 2:88bdd5c4e77b | 99 | // Set pwm duty in us order |
syundo0730 | 1:69033d5e289b | 100 | void Adafruit_PWMServoDriver::setDuty(uint8_t num, uint16_t duty) { |
syundo0730 | 2:88bdd5c4e77b | 101 | float pulselength = 10000; // 10,000 us per second |
syundo0730 | 2:88bdd5c4e77b | 102 | duty = 4094 * duty / pulselength; |
syundo0730 | 1:69033d5e289b | 103 | setPWM(num, 0, duty); |
syundo0730 | 1:69033d5e289b | 104 | } |
syundo0730 | 1:69033d5e289b | 105 | |
syundo0730 | 0:9d01b5d37adc | 106 | uint8_t Adafruit_PWMServoDriver::read8(char addr) { |
fixair | 3:07497eda12c2 | 107 | i2c->write(_i2caddr, &addr, 1); |
syundo0730 | 0:9d01b5d37adc | 108 | char rtn; |
fixair | 3:07497eda12c2 | 109 | i2c->read(_i2caddr, &rtn, 1); |
syundo0730 | 0:9d01b5d37adc | 110 | return rtn; |
syundo0730 | 0:9d01b5d37adc | 111 | } |
syundo0730 | 0:9d01b5d37adc | 112 | |
syundo0730 | 0:9d01b5d37adc | 113 | void Adafruit_PWMServoDriver::write8(char addr, char d) { |
syundo0730 | 0:9d01b5d37adc | 114 | char cmd[2]; |
syundo0730 | 0:9d01b5d37adc | 115 | cmd[0] = addr; |
syundo0730 | 0:9d01b5d37adc | 116 | cmd[1] = d; |
fixair | 3:07497eda12c2 | 117 | i2c->write(_i2caddr, cmd, 2); |
syundo0730 | 0:9d01b5d37adc | 118 | } |