Suggestions on enabling the use of RS-485 to control jrks

Hello all,

I’m working on a robotics project that uses 12 actuators and so I’ve purchased 12 jrk 21v3s to control each one. The challenge I’m currently facing is in connecting the jrks together so that I can communicate with them over a bus. Unfortunately, the suggested method of daisy-chaining the modules together using AND gates isn’t suitable for long distances and isn’t particularly noise tolerant. Since the jrks communicate using TTL-level serial, I’ve decided to try and connect the jrks and my PC controller over a half-duplex RS-485 bus. However, the implementation of the Pololu protocol is making this more complicated than I anticipated.

I’ve designed a board that plugs into the two headers on the jrk and contains an RS-485 transceiver, wired as shown below:

The receiver on the transceiver is always enabled, while Q1 ensures that the transmitter is active when the D input goes low. I also have an auxiliary microcontroller on the board that performs some additional functions and implements its own commands using the Pololu protocol. The above circuit allows both the jrk and the auxiliary microcontroller to transmit data over the RS-485 bus, but they will also simultaneously receive any data they transmit. This is where the complication lies.

The Pololu protocol is implemented so that the start of a command is indicated by a byte having its most significant bit set. All other data bytes attached to that command must have their MSBs clear. Unfortunately, the jrks do not follow this rule when transmitting data back to the host and use all 8-bits per byte. When communicating with a single jrk over TTL UART, or using the AND-gate chaining method, this is not a problem since only the host will receive the bytes transmitted by the jrk (and I acknowledge that they work as designed). However, on the RS-485 bus, when one of the jrks transmits a response, all the devices on the line will receive it and it is possible for the transmitted data to be interpreted as the beginning of a command.

Let’s consider the following scenario: a jrk has a target value of 0x01AA and the host would like to read that value and so transmits the following using the Pololu protocol:

0xAA 0x01 0x23

The jrk will respond with

0xAA 0x01

However, since all jrks on the bus will receive those two bytes, the jrk whose device ID is 1 will process those bytes as the start of a command and will be expecting the next byte to be the command byte. If the host were to send 0x23 after that, then jrk 1 would respond with its target value.

Now, in practice this doesn’t actually pose a problem because all of the variable reading commands transmit no more than two bytes and the Pololu protocol needs a minimum of 3 bytes for a full command. However, the jrks also use the compact protocol which only requires a minimum command size of one byte. It is therefore very possible that data transmitted by a jrk will be processed by other jrks using the compact protocol. For example, if a jrk’s target had 0xFF as its lower byte and it transmitted that value to the host, all other jrks on the bus would process that 0xFF as a Motor Off command.

In order to overcome this problem, I can think of the following options, along with how practical they are to implement:

  • Hide each jrk behind another controller that translates data between it and the RS-485 bus: Yuk!
  • Use a full duplex RS-485 bus with all the receivers connected together and all the transmitters connected together: possible, but is a waste of extra components and cabling for no increase in data throughput since the Pololu protocol is half-duplex.
  • Modify the jrks so that they ensure the MSB is clear when transmitting data: probably quite involved as the response format of every variable reading command needs to be changed. Also breaks compatibility with existing hosts, unless the jrks can be configured to transmit using either the old or the new formats.
  • Disable the compact protocol: I think this is the most plausible solution. I’ve had to implement the Pololu protocol myself on the auxiliary microcontroller I mentioned earlier and if my state machine is similar to what’s on the jrks, it would take less time to implement this change than it would to recompile the source. Since the compact protocol is useful in being able to quickly send a command to all jrks simultaneously, the Pololu protocol could be modified so that as well responding to their individual addresses, the jrks could also respond to a fixed global address, such as 0x00 or 0x7F. To seal the deal, disabling the compact protocol could be made as a setting that can be configured over USB so that compatibility would be retained with existing hosts.

I would like to suggest the last option as a feature to be added to the jrks and I think that it would add a lot of value to the product by allowing them to be fully controllable on a long range, noise tolerant communication system, while allowing third party devices to share the same bus and communication protocol.

Finally, would Pololu be willing to modify their firmware to just disable the compact protocol for me? I’d hope that such a software change wouldn’t take that long to implement and it would really help my project.

Amr

Great suggestion

Up…up…

db

Hello, Amr.

I have prepared an alternate version of the jrk firmware where compact serial commands are disabled:

umc01a_v1.03_nocompact.pgm (33.8 KB)
( EDIT: This firmware has a problem; see below. )

I tested to make sure that a Pololu Protocol command still worked while the equivalent compact one doesn’t work, but I haven’t tested much else about it. Let me know if you run in to any problems!

–David

Hi David,

Thank you very much for taking the time to modify the firmware for me. I’ve tested the new firmware alongside another jrk with the existing firmware and everything looks fine - the compact protocol is disabled while the Pololu protocol remains active. I can now connect the jrks on an RS-485 bus without them executing unwanted commands by processes echoed bytes.

Once again, thanks for your time on this.

Amr

Hi David,

Unfortunately, I seem to have run into a bug with the modified firmware. Sometimes when setting the motor’s target, the controller will very often suddenly apply full power to the motor in the opposite direction to that required. It will stay like that, despite new targets being sent to the jrk, until all of a sudden it resumes tracking the target value correctly. The default firmware works fine using exactly the same settings. I’ve been testing this using the slider in the configuration utility and by sending commands directly using the serial interface.

I’ve uploaded a couple of screenshots of the variable plots that should hopefully illustrate what I mean. Notice how the feedback will be following the target and then suddenly shoots off in the opposite direction.









Once again, I thank you for taking the time out to make this modification for me.

Amr

Hello, Amr.

I am sorry you are having trouble with the modified jrk firmware. I sent you the modified firmware four months ago: how long have you been using it, and did it always behave this way?

Could you save a settings file using the jrk configuration utility and post it here so I can check it for any potential problems?

Could you please try to get another plot of the bad behavior, but this time display the Target, Feedback, Error, Integral, Duty Cycle Target, and Duty Cycle on the graph? This will give us a better chance of seeing where the computation of the duty cycle goes wrong.

–David

Hi David,

Thanks for your reply. My apologies for not bringing this up earlier. Unfortunately, the new program has had this problem since day one. When I first tried the new firmware, the design of my robot was in its early stages and so I only tested the new software to make sure that the compact protocol was disabled and that the controller still functioned. I recall noticing this problem then, but thought that it could be related to my choice of settings and planned to look into it later. Now that the robot is complete and I’ve had the chance to test the controllers more extensively, the problem has become very apparent.

The problem seems to be more easily triggered when swinging the target value between the maximum and minimum values. I feel that small changes to the target value don’t seem to trigger the issue, but large changes do. The same settings work perfectly fine with the controller programmed with the stock firmware.

Attached to this post are the settings I’m currently using to test out the controller. Several screenshots of the requested traces can be found below.

The controller is exhibiting the bug in this screenshot. The target value is alternating between 0 and approximately 4000. When the target is set to 4000, the motor moves to the correct position, which is shown by the feedback and target traces lining up. When the target value is set to 0, the controller moves the motor in the opposite direction.

Following on from the previous screenshot, I then tried moving the target value slowly up from 0. As you can see, it started picking it up correctly at 50%.

The following two screenshots show the same behaviour as the ones above. I’m alternating the target between 0 and approx 4000. The motor is in its fully retracted position at a feedback value of approx 400. When I switch the target to 4000, the controller continues to energise the motor in the wrong direction, as can be seen by the Duty cycle traces at -100%.

As with the previous example, I slowly decreased the target value and the controller started responding correctly when the target was at 60%.


test settings.txt (1.39 KB)

Thank you for the additional information. I looked into it and it turns out that when I compiled the firmware for you back in February I accidentally had an option enabled that changes the way the jrk calculates the error term. Here is recompiled firmware that should work better for you:

umc01a_v1.3nocompact_try2.pgm (33.8 KB)

Please try it and let me know if the problem is solved!

–David

Hi David,

Thanks for taking the time to look into this. I’ve only just seen your new post - I must have accidentally turned off email notifications. I’ll try the new code as soon as I can and let you know how it goes.

Amr