Some questions about the PCA9685 servo driver.

I am using a PCA9685 board to drive some servo motors. The servo's do work but... I do have some problems with the library. I am using the adafruit library

#1. Every time the arduino board receives a new program, all servo motors shift a bit. How can I prevent this from happening. In the setup I added the reset function

	servoDriver.begin();
	servoDriver.reset() ; // new, would this solve the problem??
	servoDriver.setOscillatorFrequency(27000000);
	servoDriver.setPWMFreq(50);  // Analog servos run at ~50 Hz updates

I have not tried it to see if it solves the problem. I will test it to tomorrow.

The #2 problem is that the values I have to put in the setPWM function do not correspond with the real world situation.

uint16_t us = map( degrees, 0, 180, 120, 490 ); 			// map degrees to pulse lengths, numbers don't make sense but it works
servoDriver.setPWM( ID, 0, us );

I found these values with trial and error approach. They work but they make no sense. 0 degrees should be 1000us and 180 degrees should be 2000us. So why is it that I have to put in 120 and 490 instead of 1000 and 2000?

#3. The last problem is that I do not know how I can turn off a servo individually? For my application I want to kill the PWM signal entirely once the servo reaches it's position. The thing I could come up with is to do

servoDriver.setPWM( ID, 0, 0);

to set the off time to 0 so that the pulse should last... 0us. I do not know at this point if this will work.

Looking at the source code of the library I noticed that there are a sleep and a wakeup function. I do not precisely know how they work. I suppose that the sleep command will simply kill all servo signals (which is fine for my application). But if I call wakeup() I do not know if all channels are enabling PWM. Or that I would have to re-enable each channel manually. I could propably live with enabling all channels at once, but I still prefer not to turn pwm for servo's which don't have to move.

Any answers would be greatly appreciated.

Kind regards,

Bas

EDIT: I see on the website how I can turn off one motor by setting the off time to 4096

I think you are misunderstanding the library. You do not specify time with setPWM, you specify number of ticks from 0..4095 to say when you want the signal high and low. With a PWM frequency of 50Hz, each period is 20msec. You always turn on a 0 and 490 ticks later is~2.4msec.

And what do you suppose happens if you stop sending pulses to the servo?

And what do you suppose happens if you stop sending pulses to the servo?

I get that you are trying to help but you aren't because you are being retorical and as such I find this actually slightly insultive.

First of all I explained perfectly clear that I want the servo's to be turned off when they reach their position. And I said I want to kill the signals. So it is perfectly clear what I "suppose" will happen when I stop sending pulses.

Secondly I do not "suppose" anything. I use my observations. I have currently servo's in place which are driven by an arduino. After I detach() the servo's I can move them freely with my hand.

Third. You are being unconstructive. The one thing you do is implying that I am wrong about something and that's it. I don't mind being wrong about something but a comment like "you are wrong" followed by: no reason what so ever is simply not helpful. What would have been constructive/helpful is something like.

Take note that not every servo powers down when you stop sending pulses.
Are you sure your's do power down like that?

(I have ofcourse no clue if this is actually true or not as I only have cheap analog servos)

I think you are misunderstanding the library. You do not specify time with setPWM, you specify number of ticks from 0..4095 to say when you want the signal high and low. With a PWM frequency of 50Hz, each period is 20msec. You always turn on a 0 and 490 ticks later is~2.4msec.

Thank you! That wasn't clear indeed. Somewhow I was under the assumption that I had to enter the us in setPwm().

I now get that the 20ms period is devided in 4096 ticks. So one tick is 20000 us / 4096 ticks = 4.8828 us / tick.

This would mean that the correct values for 0 degrees (1000 us) and 180 degrees (2000 us) would be 204 and 409 ticks respectively.

The values I found deviate don't deviate that much. I did use a cheap analog oscilloscope. I also know that the range was not exactly 180 degrees. So I'll be trying 204 and 409 from now on.

Kind regards

Bas

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.