A digital servo protocol
For the Jumbo Servo I’ve looking at the I2C protocol. Like all protocols there are layers to this and I’m looking at the top layer which is often call the application layer. One thing that seems to be common with this layer is the concept of read and write registers. This mirrors with short command sequences and short responses. I think this is a good approach as it means that the servo can spend its time setting the right position rather than on communication. The other thing to note about this protocol is that it is a binary rather than ASCII protocol so we don’t need to convert our numbers to strings.
Wire
The Wire Library wraps up most of the complexities and we can code the application to listen for a couple of events. These need to be configured in your setup.
Wire.begin(slaveAddress); // join i2c bus
Wire.onReceive(receiveEvent); // write data
Wire.onRequest(requestEvent); // requests to read data
The first “receiveEvent” provides a number of bytes as a parameter and you must make the same number of Wire.read() requests otherwise the receive event will no longer fire.
“requestEvent” takes no parameters and the response is typically a Wire.write() to send some data back. So typically a command is sent to select which register to read then the request event sends back the selected value.
Protocol
I’m going to have 4 commands initially. These will each take a two byte int parameter.
Command | Value | Parameter |
Status | 0 | Status register to read |
CmdStop | 1 | Parameter ignored |
CmdAngle | 2 | Angle from 0 to 1023 |
CmdSpeed | 3 | Speed from 0 to 1023 |
For the status I’m also sending a two byte integer back.
Register | Value |
version | 0 |
running | 1 |
target Position | 2 |
speed | 3 |
direction | 4 |
current position | 3 |
However before I finalise this approach I’m going to listen to this week’s “Amp Hour” where they fortuitously are discussing the I2C bus.
So a few tips from the AmpHour.
* Check the address
* If using long lines then use lower valued pullup resistors
* Diagnose first with a scope to check that the waveforms are present and looking nice and square, then with a logic analyser to check the data is as expected.
It would appear I’ve unintentionally ended up with a protocol that’s compatible with https://github.com/alvaroferran/IntelliServo from Alvaro Ferrán Cifuentes the only key differences are that his supports temperature and current sense and uses a PID control rather direct speed input.
He’s also using an off the shelf servo and hence PWM rather than a H-bridge.