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/
Locked
User avatar
mikejr88
 
Posts: 36
Joined: Sat Jul 25, 2009 9:46 am

Adafruit 16ch PWM in cpp

Post by mikejr88 »

I have been working on converting Adafruit python code to cpp. Here is my progress so far.
PCA9685.tar
(30 KiB) Downloaded 112 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

User avatar
mikejr88
 
Posts: 36
Joined: Sat Jul 25, 2009 9:46 am

Re: Adafruit 16ch PWM in cpp

Post by mikejr88 »

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

User avatar
mikejr88
 
Posts: 36
Joined: Sat Jul 25, 2009 9:46 am

Re: Adafruit 16ch PWM in cpp

Post by mikejr88 »

Two new PCA9685 functions

Code: Select all

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

User avatar
mikejr88
 
Posts: 36
Joined: Sat Jul 25, 2009 9:46 am

Re: Adafruit 16ch PWM in cpp

Post by mikejr88 »

It appears you can't set the restart bit unless it is already set. Strange!
Changed my reset function.

Code: Select all

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

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.

Locked
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/

Return to “Adafruit Raspberry Pi® accessories”