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