-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
2+ servos can't handle .to method frequently #1340
Comments
Hi @under24 Can you tell us more about your project? What environment is your host server on? Can you share the complete code? A video of the behavior could also be really helpful. I'm sure you should be able to control that many servos. I have a project that uses 18 servos and each updates about 60 times per second (with a whole ton of other stuff going on). I will admit that I haven't done it with a PCA9685 so maybe this is an issue with I2C communications. |
Hello @dtex. Here's a video: https://youtu.be/TJq6XeNXwZY |
I've got the code running, but need to run to the lab an pick up a couple of servos so I can test. Assuming I get the same behavior the first thing I'm going to try is bypassing the PCA9685 and see if the behavior still occurs (just hooking the servos up to pins on the Arduino). |
@dtex do you have any news on it? |
Sorry, no I haven't been able to get to the servos but I will be at the lab tomorrow. |
@dtex actually, I've already found a solution for it.
|
Oh wow, that's really interesting. I had a project where I was seeing the same kind of servo jankiness on a Tessel 2 with a PCA9685. I had assumed that the T2 just couldn't handle the IK calculations and that was my limiting factor, but I was updating 18 servos and each one was updated with a separate I2C message... This changes my assumption about what the problem was. I propose that we rename and reopen this issue. |
@dtex What do i rename it to? The problem seems to be in the low computing power of the controllers or in the transfer speed of the I2C protocol. I am not really sure in any of this Here's my solution for this kind of bottleneck with servos: servo.js.zip So you just add it to every servo instance and push the data as frequently as you want and it will automatically be throttled down to 20ms per data batch allowing your expander boards to work perfectly responsive. servo init example:
|
Hello @dtex. Could you please review/include my solution to the framework? I think this is pretty neat if you work with sockets and multiple servos. I have the file attached in the prev post. Or do I make a pull request and do it myself? |
I'm not sure this is something that should be fixed in Johnny-Five. It might belong in firmtata.js or firmata itself. To know where requires truly knowing where the bottleneck actually lies. Are you certain it is a limitation of I2C, the PCA9685, or maybe it's something higher up the chain? My assumption would be that socket-io is much more of a bottleneck than I2C. Do you have the same problem when the commands are not sent over socket-io? Can we solve the problem in a better way. For example, should we update the Servos (note the plural) class and add the ability to pipe down multiple values in a single I2C data push instead of a separate push for each servo spaced out over time? |
@dtex How do we implement it with multiple values? How do we know when to expect multiple values? Do we send a batch and then collect a new batch in a span of some ms? As I understood it's the same idea that I had with my throttler. Can you sketch some pseudo code? |
To see if writing multiple values in one push even works I would build a test case that requires only firmata.js and sends an I2C message that writes 64 consecutive register values (16 servos * 4 per servo) at once vs just the 4 we need for a single servo. This is the part of Johnny-Five that handles communication with the PCA-9685 and you can see here where we are only writing to four register values. You can crib code from here and modify it to support writing for N servos at once (this.io is an instance of firmata.js in your case). If all that works, we would need to modify Johnny-Five Servos so that it has an awareness of situations where writing multiple servo values at once makes sense. I could even see adding a command to the firmata protocol to support this for non-I2C connected servos. We could modify Servos.to so it would handle this new message style and not just delegate to Servo.to. This is not a trivial investigation so I totally understand if you don't want to take it on. I'm interested in getting to the bottom of it for my own projects, but I can't imagine that I will get around to it anytime soon. Practical Alternatives: |
Hi @under24 , One of the things that came out of this discussion was the realization that it would be helpful to send multiple servo writes in a single i2c message. It's one of those features that will require a fair amount of work and we just haven't gotten to it yet. Rather than leave this languishing as an open issue we have created a Requested Features page and added the request for bulk servo writes there. |
I have a nodejs server and 3 servos.
I init the servos like this:
I push values via socketio from front-end to the back-end where I set the values like this:
My problem is that the servos get laggy and unresponsive (in other words they begin to pile up the queue).
The issue can be observed only with 2+ servos. If I use it with 1 servo there's no delay and it's perfectly responsive no matter how frequently I push new data from the front-end.
P.S. I also tried like this and it doesn't help:
The text was updated successfully, but these errors were encountered: