Memorial day is 05/25/2015 – Orders will ship out on May 26th. There will not be any deliveries or shipping on Monday. Any order placed after 11am ET on Friday May 22nd will not start to ship out until Tuesday May 26th.

Adafruit 16ch PWM in cpp
Moderators: adafruit_support_bill, adafruit

Forum rules
Talk about Adafruit Raspberry Pi® accessories! Please do not ask for Linux support, this is for Adafruit products only! For Raspberry Pi help please visit: http://www.raspberrypi.org/phpBB3/

Adafruit 16ch PWM in cpp

by mikejr88 on Wed Nov 21, 2012 12:39 pm

I have been working on converting Adafruit python code to cpp. Here is my progress so far.
PCA9685.tar
(30 KiB) Downloaded 56 times

I don't know what "reset" does. I would like to stop sending a signal to the servos when my program ends. I guess I need to read the PCA9685 pdf a few more times. :-)

Hopefully this helps someone. However, I am an amateur.
Mike
mikejr88
 
Posts: 35
Joined: Sat Jul 25, 2009 9:46 am

Re: Adafruit 16ch PWM in cpp

by mikejr88 on Sat Nov 24, 2012 1:03 pm

OK. The reset function is not actually resetting the PCA9685. More like a setup function. Setting MODE1 from the default(0x11) to 0x00 starts the internal oscillator and disables ALLCALL functions of the PCA9685. Not sure I need ALLCALL functions, especially since I have a mixed I2C bus. i.e. different I2C devices.
I'm thinking function to:
reset
turn all LED's off
sleep
turn oscillator off

Thanks,
Mike
mikejr88
 
Posts: 35
Joined: Sat Jul 25, 2009 9:46 am

Re: Adafruit 16ch PWM in cpp

by mikejr88 on Sat Nov 24, 2012 5:32 pm

Two new PCA9685 functions
Code: Select all | TOGGLE FULL SIZE
void PCA9685::reset() {
   // Turn off all LED's
   I2Cdev::writeByte(devAddr, ALLLED_ON_L, 0x00);
   I2Cdev::writeByte(devAddr, ALLLED_ON_H, 0x00);
   I2Cdev::writeByte(devAddr, ALLLED_OFF_L, 0x00);
   I2Cdev::writeByte(devAddr, ALLLED_OFF_H, 0x10);
   // oscillator off,ALLCALL off and restart PCA9685
   I2Cdev::writeByte(devAddr, PCA9685_MODE1, 0x90);
}

/**
 * Stop the internal oscillator by
 * Changing bit 4 to a 1
 */
bool PCA9685::sleepMode() {
   uint8_t oldmode;
   I2Cdev::readByte(devAddr, PCA9685_MODE1, &oldmode);
   // bitwise OR (|) if bit4 = 0 or 1 then bit4 = 1
   oldmode |= 0x10;
   return I2Cdev::writeByte(devAddr, PCA9685_MODE1, oldmode);
}


Thanks,
Mike
mikejr88
 
Posts: 35
Joined: Sat Jul 25, 2009 9:46 am

Re: Adafruit 16ch PWM in cpp

by mikejr88 on Sat Nov 24, 2012 9:28 pm

It appears you can't set the restart bit unless it is already set. Strange!
Changed my reset function.
Code: Select all | TOGGLE FULL SIZE
void PCA9685::reset() {
   // Turn off all LED's
   I2Cdev::writeByte(devAddr, ALLLED_ON_L, 0x00);
   I2Cdev::writeByte(devAddr, ALLLED_ON_H, 0x00);
   I2Cdev::writeByte(devAddr, ALLLED_OFF_L, 0x00);
   I2Cdev::writeByte(devAddr, ALLLED_OFF_H, 0x10);
   // oscillator off and ALLCALL off
   I2Cdev::writeByte(devAddr, PCA9685_MODE1, 0x10);
}

Changed setPWMFreq function
Code: Select all | TOGGLE FULL SIZE
void PCA9685::setPWMFreq(float freq) {
   float prescaleval = 25000000;
   prescaleval /= 4096;
   prescaleval /= freq;
   prescaleval -= 1;
   uint8_t prescale = floor(prescaleval + 0.5);

   uint8_t oldmode;
   I2Cdev::readByte(devAddr, PCA9685_MODE1, &oldmode);
   uint8_t newmode = (oldmode&0x7F) | 0x10; // sleep
   I2Cdev::writeByte(devAddr, PCA9685_MODE1, newmode); // go to sleep
   I2Cdev::writeByte(devAddr, PCA9685_PRESCALE, prescale); // set the prescaler
   I2Cdev::writeByte(devAddr, PCA9685_MODE1, oldmode & 0x6F); // Oscillator on
   sleep(0.005);
   //I2Cdev::writeByte(devAddr, PCA9685_MODE1, oldmode | 0x80);
}


Thanks,
Mike
P.S. Trying to give back to Adafruit. Hopefully I am helping someone.
mikejr88
 
Posts: 35
Joined: Sat Jul 25, 2009 9:46 am