Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error messages (Bit number is outside the bounds of the byte length) from qwiic_pca9685 #10

Open
labreanerds opened this issue Feb 29, 2024 · 8 comments

Comments

@labreanerds
Copy link

When running ex2_full_sweep_with_180_deg_servo.py with debug enabled:

test = pi_servo_hat.PiServoHat(None, 1)

I get this output:

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
Bit number is outside the bounds of the byte length.
Bit number: 5
Byte length: 3
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
...

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)

@sfe-SparkFro
Copy link
Contributor

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.

@labreanerds
Copy link
Author

labreanerds commented Mar 2, 2024

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

@sfe-SparkFro
Copy link
Contributor

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.

@labreanerds
Copy link
Author

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!

@labreanerds
Copy link
Author

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.

@sfe-SparkFro
Copy link
Contributor

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:

image

And when set to 180:

image

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).

@sfe-SparkFro
Copy link
Contributor

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.

@sfe-SparkFro
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants