StickyBotIII has a robust communications bus that allows time-division multiplexed communication between the main board and all peripheral boards. The communication has error-checking to prevent erroneous commands from being executed. Since the data transmitted is motor commands and state variables and the data-rate is so high, we discard any lost information because new motor commands will be provided within a millisecond.

Physical Layer

The network established between all the boards will be a RS-485 half-duplex synchronous link. There will be two pairs of differentials lines, one for clock and one for bi-directional data making a total of four wires. The individual bytes are produced by SPI hardware, but without a SS line. Instead, the software is responsible for determining if the chip is currently transmitting or receiving, and therefore asserts itself on the data bus. We request that all data transceivers on the bus are tolerant of I/O contention.

Here are some of the specifications for our configuration of the SPI and RS-485 systems:

  • Serial output data changes on transition from Idle clock state to active clock state (default on Microchip PICs)
  • Idle state for clock is a low level; active state is a high level (default on Microchip PICs)
  • The clock frequency is set at 1.25 MHz

Half-duplex implementation

While the clock lines are always driven by master, the data lines are driven by each nodes (master and servos) in turn. As a result, each node is required to assert itself on the data bus at the appropriate time. This is accomplished in software using high priority interrupts. Essentially the nodes are counting the number of incoming bytes and each is hard coded to assert itself during a fixed window. This requires a fixed length data packet always, which is achievable since the communication bus simply transmit and receives the robot's servo commands and sensor readings.

Specifically, the master goes first for transmitting, and it executes two sets of DMA transfers (each set actually has two DMA channels, one for writing/read data and another to do dummy read/writes.), The master asserts itself, initiates transmission of data to all peripherals in one burst. Each node is responsible for counting number of bytes from the start of the packet to determine each individual's command. After transmission, the master deasserts itself and initiates a large reception (but transmits the clock signal.) Each node continues to count and asserts itself during it's prescribed window and transmits it's data back to the master.

A python script is responsible for generating the C code that determines each node's transmission and reception windows. It can be found at ~/SB3/Embedded/Scripts/select_servo_id.py

Data/Network Layer

This communication protocol does not support run-time changes to the network data structure. These must be changed at design time. First, the main board transmits N x M + 1bytes, where N is the number of servo nodes, and M is the number of bytes each servo nodes receives. The final byte is a Pearson hash byte in order to maintain data integrity. Second, each servo nodes in turn transmits K + 1 bytes, in order until all servo nodes have transmitted their data. Finally, the main board holds the clock line low for 2 byte times which signals the end of a packet. At this point, the SPI system of all nodes reboot in order to clear buffers and reset any framing problems.

Status LEDs

Each slave node has a green COM LED and a red ERR LED. Upon a fixed number of successful receptions, it will toggle it's green LED. In essences, a flashing green LED indicates a healthy communication link (since all nodes are synchronized, the green LEDs of all nodes should flash in unison.) If a node receives a bad hash, it will illuminate it's red LED briefly. If it loses communication for a protracted period, it will flash its red LED to indicate the processor is still functioning but communication has been lost.

In summary, at least one LED should be flashing, green is good, red is bad. If neither is flashing, the processor itself is not functioning.

Pearson Hashing

First a 256-element 8-bit hash table with a random permutation is generated and hard-coded on all nodes. Then each nodes, receives and data and implements the iterative algorithm for each step:

code(n) = hash[data(n) XOR code(n-1)]

Both the transmitting and receiving nodes perform the hashing, the transmitter sends the hash and the receiver compares it to determine if the transmission is valid. If it isn't the packet is simply dropped and a data loss LED is momentarily illuminated.

Hash map

This is the hash map used by the SB3 communication bus. The code initializes with the 0xAA value. All boards must have this map in order to effective calculate the same hash value. It should be noted that some maps will incorrectly fail to raise an error will a data line at all high or all low. This map will not do so given the lengths of transmission. (Currently this map will generate a hash of 0 with a low data line at byte 168 and a hash of 255 with a high data line at byte 26, neither or which are the length of command or report structures).

#define HSH_INIT_CODE   0xAA

static const unsigned char HSH_hash[256] = {
   245, 120, 250, 87, 252, 116, 12, 2, 114, 68, 181, 151, 54, 100, 85, 129,
   128, 183, 118, 209, 241, 93, 172, 47, 223, 0, 220, 178, 150, 229, 136,
   77, 174, 155, 40, 42, 140, 65, 238, 113, 95, 16, 208, 255, 153, 51, 119,
   29, 243, 170, 173, 75, 199, 143, 44, 125, 90, 35, 122, 253, 41, 66, 202,
   81, 233, 175, 187, 49, 94, 244, 133, 232, 171, 196, 1, 124, 131, 79, 218,
   157, 80, 15, 201, 34, 106, 72, 57, 164, 56, 104, 4, 112, 152, 97, 36,
   240, 22, 217, 126, 162, 139, 205, 226, 89, 141, 14, 99, 76, 5, 69, 70,
   32, 149, 198, 210, 101, 214, 10, 107, 11, 59, 203, 58, 154, 146, 98, 7,
   251, 147, 234, 45, 165, 3, 194, 108, 248, 137, 168, 190, 206, 17, 197,
   195, 74, 111, 27, 8, 135, 169, 215, 185, 163, 110, 48, 82, 211, 53,  63,
   144, 156, 60, 102, 9, 216, 13, 61, 62, 221, 18, 189, 96, 161, 134, 105,
   115, 145, 64, 30, 52, 55, 127, 25, 37, 222, 142, 236, 84, 159, 212, 33,
   186, 177, 50, 6, 26, 213, 160, 38, 86, 78, 192, 200, 123, 148, 227, 230,
   204, 179, 158, 24, 191, 176, 39, 43, 228, 121, 73, 88, 21, 188, 167, 166,
   225, 92, 254, 239, 235, 91, 180, 20, 132, 19, 138, 117, 83, 246, 224, 67,
   109, 23, 207, 247, 28, 237, 242, 71, 130, 31, 219, 231, 193, 182, 249,
   46, 184, 103
};

-- SalomonTrujillo - 29 Mar 2010

 
This site is powered by the TWiki collaboration platformCopyright &© by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback