Friday, 6 May 2011

USB servo board animation playback

After a late night at BuildBrighton last night, we finally got the PIC microcontroller talking to the Flash-eeprom. It turns out that the first SMT-to-DIP board wasn't soldered up properly. So after a few hours debugging some code (that eventually turned out to have been working all along) we fixed the dodgy lines and managed to read and write data to/from the Flash device.

So now we need to consider how animations will be stored in memory.
The first, and immediate, use of the Flash memory was to store data in a sequence of 4-byte chunks.

  • The first and second bytes represent the time in milliseconds to have elapsed.
  • The second byte is the servo channel number
  • The third byte is the movement value (where 100=1m/s, 200=2m/s etc)

500,09,120
500,10,120
2000,09,050
2000,10,200
4000,09,200
5000,10,060

We started building an app to allow users to write their animations to the eeprom chip. Then, after a cup of tea and a biscuit, we decided to make a DLL to simplify the whole process, allowing end-users to create their own animation software and integrate it with the servo board. The final solution we came up with (and decided to stick to) was to read a simple text file, made up of the 4-byte chunks, and stream this data over USB to the usb-servo board.

Full details of how the servo board works will be published later (once we've agreed on the communication protocols!) so that other users can contribute their own animation-creation software in future.

After a bit of thought, and trying out a few animations, it became apparent that the eeprom chip has massive amounts of storage which likely to go unused. It also became apparent that most robotic animations are actually repetitions of relatively small animations. For example, walking animations are just cycles of simple, smaller movements (irrespective of the number of legs involved!).

Our final animation decision was to increase the chunk-size to five bytes:

  • First and second bytes are time in milliseconds
  • Third byte is a command byte which changes how the fourth and fifth bytes are interpreted
  • If command byte is "move servo", the fourth byte is the servo number and the fifth byte the movement value
  • If the command byte is "jump to timecode", the internal servo timer is updated to a (two-byte) value represented by bytes four and five


The text file containing these values is updated to an easily-understood format:

servo 500,09,120
servo 500,10,120
servo 2000,09,050
servo 2000,10,200
servo 4000,09,200
servo 5000,10,060
tloop 6000,1000

and these commands are translated into the following byte sequence:

1,244,0,9,120 (500 = highbyte 1, lowbyte 244, third byte=command byte)
1,244,0,10,120
7,208,0,9,50
7,208,0,10,200
15,160,0,9,200
19,136,0,10,60
23,112,1,3,232

The last entry is of particular note.
The command tloop is represented by a 1 in the third byte and in this case means "reset the timer as if it were 1 second after the start of the animation".
As a result, the servo board resets the internal timer, starts at the beginning of the list and reads through the commands, until it hits the appropriate one in the sequence. The result, in this case, is that the last five commands in the list are repeated over and over again.