Open labreanerds opened 8 months ago
Hi there, thanks for bringing this to our attention!
I took a quick poke around, looks like those messages are being generated by the underlying PCA9685 driver that this is based on. I've only just started looking at the code, so I don't yet know if the root problem is with the PCA9685 driver, or with how this driver is using it.
As for your servo no moving as far as it should, could you please test the code at the bottom of example 2 to see whether that results in your servo moving further than before? Please let me know what you find! If that results in increased range, then a workaround you could use for now is to change the values you're passing to beyond 0 and 180. Obviously that's not ideal, but hopefully that will enable you to use the full range of your servo.
Thank you so much for looking into this. Totally understand the root cause may be in the PCA9685 driver.
[EDIT] Actually, the object on my table was moving around and I wasn't getting good readings on the angle. Both the commented out code in example 2 and the original code seem to give about the same angle. It's less than 90 degrees.
The servo I'm currently using is a HS-422: https://www.sparkfun.com/products/11884
Hmm, that's odd that the servo doesn't rotate more than 90 degrees even with that code uncommented. Was definitely hoping that would make a difference!
Thanks for linking the servo you're using! Once those are back in stock, I'll see if I can grab one and replicate what you're seeing, that'll make debugging a lot easier on my end.
A little more info on this; I got another servo from SF that is still in stock, also listed at 180 degrees: https://www.sparkfun.com/products/11965
This one has the same problem, only does 90 degrees.
My colleague got a servo from Amazon that is listed at 360 degrees and it moves up to 180 degrees.
Thanks for looking into this!
On more update: we got a servo that is listed to be able to do 360 degrees (Feetech FT6335M - https://www.amazon.com/dp/B09F2ZXMXW?ref=ppx_yo2ov_dt_b_product_details&th=1).
This one does do 180 degrees. With the "extended range" code in the example it goes a little beyond 180 degrees. By changing the range from -360 to 360, it will rotate 360 degrees. There are pauses, so that range would have to be tweaked to get it correct, but at least it's doing the full sweep of 360 degrees.
Hi there, apologies for the long delay on this! I became very busy and am finally coming back to this.
I don't have one of the new servo hats to test, but I do happen to have one of the older revision, which I believe are basically the same other than some extra bells and whistles on the new one - both used the PCA9685 for driving the servos. I'm also using a Raspberry Pi 5, on which I ran pip install sparkfun-qwiic
to get the latest version of all Qwiic packages.
I'm running a modified version of example 2:
import pi_servo_hat
import time
channel = 0
minAngle = 0
maxAngle = 180
sweepAngle = 180
test = pi_servo_hat.PiServoHat(debug=1)
test.restart()
while True:
test.move_servo_position(channel, minAngle, sweepAngle)
time.sleep(1)
test.move_servo_position(channel, maxAngle, sweepAngle)
time.sleep(1)
Here is my output:
PWM Frequency: 50
PWM Frequency: 50
Bit number is outside the bounds of the byte length.
Bit number is outside the bounds of the byte length.
Bit number: 4
Byte length: 3
Servo Range: 180
On value: 0
Off value: 205
Total (max. 4096): 205
Bit number is outside the bounds of the byte length.
Bit number is outside the bounds of the byte length.
Bit number: 5
Byte length: 3
Servo Range: 180
On value: 0
Off value: 410
Total (max. 4096): 410
Servo Range: 180
On value: 0
Off value: 205
Total (max. 4096): 205
Servo Range: 180
On value: 0
Off value: 410
Total (max. 4096): 410
So I do get the same error message, but only one the first 2 calls to move_servo_position()
. All subsequent calls do not print any errors.
This is the PWM output when the angle is set to 0:
And when set to 180:
The period should be 20ms (50Hz), but it's actually 18.63ms (53.67Hz). The short pulse should be 1ms, but it's actually 0.932ms. The long pulse should be 2ms, but it's actually 1.865ms. These are all about 93% shorter than what they should be - not enough that I would expect it to cause your servos to have half their normal range, but enough that it could affect fine position values.
I also changed minAngle
and maxAngle
to -90 and 270, which should result in pulse widths of 0.5ms and 2.5ms; I'm getting 0.464ms and 2.328ms, which are again about 93%. So other than the 93% scaling issue, the PWM output is what I expect it to be.
You may have moved on since we last spoke, but if you're able, I'd be very curious if you can hook up an oscilloscope to see what the pulse widths actually are on your end.
I haven't tested with the servos you mentioned, I'm just looking at the PWM output on my scope for now. Though I did notice on the Amazon page for the last servo you linked: "the rotation angle is 360 degrees (at 500→2500μsec)". This library assumes a min/max pulse width of 1-2ms, so that would explain why you were only getting half of the range until you increased the angles beyond 0/180. Although that unfortunately doesn't explain why the 2 servos you got from us have limit range, since the product pages list the required pulse width range as 1.5-1.9ms and 1-2ms respectively for 180 degree rotation. I will grab one of each of those to test for myself.
Assuming those 2 servos can also have the correct rotation range by extending the pulse width range (eg. 0.5-2.5ms), I may see about adding that as a feature to this library - being able to specify the minimum and maximum pulse width.
And none of this addresses the original error (Bit number is outside the bounds of the byte length
), but I'm prioritizing functionality over a spurious error message that doesn't seem to actually be causing a problem (the actual output signal appears to be correct, other than the 93% thing).
I tested the 2 servos you mentioned from our storefront (this and this), and I found they require a pulse width of 0.5-2.5ms to get the full 180 degree range. That contradicts what our product pages say, so I'll forward that on to get the product pages corrected.
I will also see about making the min/max pulse width configurable, so users with servos that need something other than 1-2ms (like yourself) can get the proper pulse periods. Looks like #8 addresses this, so I'll review that. That will not fix the scaling issue I mentioned in my previous comment, nor will it fix the error messages, but IMO it's an important feature regardless.
Now that #8 has been merged, you should be able to adjust your code with:
test = pi_servo_hat.PiServoHat(min_pt=0.5, max_pt=2.5)
Then your servos should have full motion range! You could also tweak min_pt
and max_pt
to fix the scaling issues I mentioned.
Again, this will not fix the error messages when debug=1
, so I will leave this issue open until that is addressed. However since it doesn't appear to be causing any functional problem, it's going to be lower priority, so can't promise if/when we'll get around to that.
When running ex2_full_sweep_with_180_deg_servo.py with debug enabled:
test = pi_servo_hat.PiServoHat(None, 1)
I get this output:
The 'Bit number is outside the bounds of the byte length.' seems like there is a bug somewhere.
We have two servos, one is definitely confirmed to support 180 degrees, but with the above mentioned example, they only do 90 degrees. The above errors makes me wonder if it is related.
The same issue appears in whatever version pip installs, as well as the downloaded master from here @ github (for pi_servo_hat as well as all the qwiic stuff)