Scribbler Wire Protocol
From IPRE Wiki
This documentation is based upon the contents of the scribbler server code located here.
Contents |
Overview:
Messages to the Scribbler are a constant 9 bytes long. Messages from the Scribbler are variable length depending on the message type. See below for details.
On startup, the robot repeatedly sends its name preceded by "IPRE" every 'TIMEOUT milliseconds. This allows the PC to find it and connect. After the Scribbler receives a command, this name broadcasting stops.
All "SET" messages have a return type of "GET_ALL".
Messages TO robot:
- The first byte is the message type
- The next bytes are the command data (if any)
- The rest of the message is filled with null characters until a total of 9 bytes.
Messages FROM robot:
- The first bytes are the message data
- The last byte is the message type
- If the message is a GET type message, just the requested data is sent
- If the message is a SET type message, the binary state of the robot is sent
Commands
| name | values | notes |
|---|---|---|
| SOFT_RESET | 33 | Format: 33 0 0 0 0 0 0 0 0, Notes: Performs a software reset of robot. (turns name broadcast back on) |
GET Commands
| name | values | notes |
|---|---|---|
| GET_ALL | 65 | leftIR rightIR LeftLightHighyte LeftLightLowByte CenterLightHighByte CenterLightLowByte RightLightHighByte RightLightLowByte LineLeft LineRight Stall 65 |
| GET_ALL_BINARY | 66 | BinaryData 66, Notes: where the individual bits of BinaryData are: 0x000 IRLeft IRRight Stall LineLeft LineRight |
| GET_LIGHT_LEFT | 67 | HighByte LowByte 67 |
| GET_LIGHT_CENTER | 68 | HighByte LowByte 68 |
| GET_LIGHT_RIGHT | 69 | HighByte LowByte 69 |
| GET_LIGHT_ALL | 70 | LeftHighyte LeftLowByte CenterHighByte CenterLowByte RightHighByte RightLowByte 70 |
| GET_IR_LEFT | 71 | leftIR 71, Notes: IR is 1 when there is no obstacle to the left of robot |
| GET_IR_RIGHT | 72 | rightIR 72, Notes: IR is 1 when there is no obstacle to the left of robot |
| GET_IR_ALL | 73 | LeftIR RightIR 73, Notes: IR is 1 when there is no obstacle to the left of robot |
| GET_LINE_LEFT | 74 | lineLeft 74 |
| GET_LINE_RIGHT | 75 | lineRight 75 |
| GET_LINE_ALL | 76 | LineLeft LineRight 76 |
| GET_STATE | 77 | inPins outPins 77, Notes: inPins is the state of all the input pins (0-7), and outPins is the state of all the output pins (8-15) as defined in the I/O Pin Declarations. |
| GET_NAME1 | 78 | char1 char2 char3 char4 char5 char6 char7 char8 78 |
| GET_NAME2 | 64 | char9 char10 char11 char12 char13 char14 char15 char16 87 |
| GET_STALL | 79 | stall 79 |
| GET_INFO | 80 | "information on version robot, etc" 10 80 |
| GET_DATA | 81 | data from flash memory 81 |
| GET_PASS1 | 50 | 16 bytes from flash memory |
| GET_PASS2 | 51 | 16 bytes from flash memory |
SET Commands
| name | values | notes |
|---|---|---|
| SET_SINGLE_DATA | 96 | Sets a single byte of data in flash memory' |
| SET_DATA | 97 | Sets 8 bytes of data in flash memory |
| SET_ECHO_MODE | 98 | Set the echo mode on or off; if off, no echo is made after command |
| SET_LED_LEFT_ON | 99 | |
| SET_LED_LEFT_OFF | 100 | |
| SET_LED_CENTER_ON | 101 | |
| SET_LED_CENTER_OFF | 102 | |
| SET_LED_RIGHT_ON | 103 | |
| SET_LED_RIGHT_OFF | 104 | |
| SET_LED_ALL_ON | 105 | |
| SET_LED_ALL_OFF | 106 | |
| SET_LED_ALL | 107 | 107 LeftLEDstate CenterLEDstate RightLEDstate 0 0 0 0 0 |
| SET_MOTORS_OFF | 108 | 108 0 0 0 0 0 0 0 0 |
| SET_MOTORS | 109 | 109 rightmotor leftmotor 0 0 0 0 0 0, Notes: 0 = full speed backwards, 100 = stop, 200 = full speed forward |
| SET_NAME1 | 110 | 110 char1 char2 char3 char4 char5 char6 char7 char8 |
| SET_NAME2 | 119 | 119 char9 char10 char11 char12 char13 char14 char15 char16 |
| SET_LOUD | 111 | |
| SET_QUIET | 112 | |
| SET_SPEAKER | 113 | 113 DurationHighByte DurationLowByte FreqHighByte FreqLowByte |
| SET_SPEAKER_2 | 114 | 114 DurationHighByte DurationLowByte Freq1HighByte Freq1LowByte Freq2HighByte Freq2LowByte |
| SET_PASS1 | 55 | 55 PASS1 PASS2 ... PASS8 |
| SET_PASS2 | 56 | 56 PASS9 PASS2 ... PASS16 |
Commands As Issued By Myro
When commands are issued via Myro, they are sent to the Fluke board, which in turn sends them to the Scribbler robot. Typical Myro commands send one or more sets of Scribbler wire commands to the Scribbler. For example the forward() function actually calls SET_MOTORS followed by SET_MOTORS_OFF. By turning on debugging within Myro, these bytes can be observed as follows:
>>> myro.globvars.robot.debug = 1 >>> forward(1, 1) _write: mÈÈ 9 data: ['0x6d', '0xc8', '0xc8', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0'] _read (9) ['0x6d', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0'] _read (11) ['0x1', '0x1', '0x7', '0x3e', '0x12', '0x92', '0x3b', '0xa9', '0x0', '0x0', '0x0'] _write: l�������� 9 data: ['0x6c', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0'] _read (9) ['0x6c', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0'] _read (11) ['0x1', '0x1', '0xb', '0x13', '0xe', '0x8f', '0x39', '0xf3', '0x0', '0x0', '0x0']
From the output within IDLE, we can see that two sets of "write" commands are performed. The bytes written are in accordance with the previously listed byte layout. 0x6D = 109, which is SET_MOTORS, 0x6C = 108, which is SET_MOTORS_OFF. 0xC8 = 200 which is given as the 2nd and 3rd paramters to SET_MOTORS, which indicates full speed on both wheels.
We also see that for each set of bytes written out, two sets of reads are performed. This is due to the fact that the Fluke sits between Myro and the scribbler. The Fluke actually intercepts the commands are performs its communication with the Scribbler in addition to the bytes issued directly from Myro.
Response As Read By Myro
The latter of the two sets of "read" bytes are interpreted by the Myro framework and made available to the user. The 11 bytes returned are unpacked in getLastSensors:
def getLastSensors(self):
retval = self._lastSensors
return {"light": [retval[2] << 8 | retval[3], retval[4] << 8 | retval[5], retval[6] << 8 | retval[7]],
"ir": [retval[0], retval[1]], "line": [retval[8], retval[9]], "stall": retval[10]}
This method is called periodically and provides the latest values of various sensor values: light, ir, line, and stall.
In the code above, some sensor values are taken as two bytes. For example, the "light" sensor is computed as:
[retval[2] << 8 | retval[3]
Which bit shifts the 3rd byte to the left a whole byte taking the value from:
0x13
to
0x1300
We then logically OR the 4th byte
0x0E
Leaving us the 16-bit value
0x130E
