EternityForest.Com

JavaScript is disabled or not working. Turn On JavaScript and get awesome text here with every click.





The Gazebo Embedded Networking Protocol

NOTE: I Consider this project mostly a failure because of how complex it is compared to alternatives, and the linked sources may of may not work at all, however this page is here for historical interest. The pseudo-sucessor WBTV however, has been used in several projects.

Gazebo is a project I have been working on for a few years on and off that allows devices to communicate over serial links. The key feature here is that devices are discoverable and self-describing. Gazebo is Master/Slave and works over TTL,USB, or RS485. As of now, gazebo consists of a protocol document(subject to non-backwards compatible change until version 1), A reference implementation in C called SpookyCastle which allows a computer to take control of an Arduino's IO pins, and a reference implementation of a master  in Python that is already quite functional.

The protocol nativly supports units of measure, and data types such as uint8,uint16,int8,etc, and also arrays, nested arrays,strings, enumerations, floats, function calls, and FIFO queues.

There is also native support for error handing.

Nodes are identified with 128 bit UUIDs, so there is no need for "Vendor IDs"(Don't worry, we assign 16 bit temporary IDs to avoid the overhead of such long IDs)

Devices can be found by a binary search, which only takes a few seconds per device.

The total compiled code size of the current SpookyCastle is around 11k on the Arduino Leonardo.

Since this is all still a work in progress, code and documentation is hosted here at GitHub.


A Code Example


  1. Python 3.2 (r32:88445, Feb 20 2011, 21:30:00) [MSC v.1500 64 bit (AMD64)] on win32
  2. Type "copyright", "credits" or "license()" for more information.
  3. >>> ================================ RESTART ================================
  4. >>>
  5. >>> manager = NetworkManager('com6') #using serial port com6
  6. >>> manager.EnumerateSlaves() #Search the "bus"( not rs486 at the moment)
  7. >>> manager.slaves #after 15s per device or so it populates the list
  8. {'Z3RoczR2bG9nZmVk': <Gazebo Slave SpookyCastle for Arduino I/O board with ID Z3RoczR2bG9nZmVk>}
  9. >>> s = manager.slaves['Z3RoczR2bG9nZmVk']
  10. >>> s.params #lets take a look at the parameters the slave exposes
  11. {'AnalogWrite': <Parameter Object AnalogWrite of type void with interpretation void>, 'DigitalWrite': <Parameter Object DigitalWrite of type void with interpretation void>, 'AnalogRead': <Parameter Object AnalogRead of type uint16 with interpretation Volts*204.8>, 'TheRaven': <Parameter Object TheRaven of type UTF-8[0:80] with interpretation GrimUngainlyGhastlyGauntAndOminousBirdOfYore>, 'DigitalRead': <Parameter Object DigitalRead of type uint8 with interpretation boolean>, 'PinMode': <Parameter Object PinMode of type void with interpretation void>}
  12. >>> analogWrite = s.params['AnalogWrite']
  13. >>>analogWrite.pinfo()

  14. Readable parameter of type void to be interpreted as void
  15. This parameter plays role none in group none of type none
  16. The following arguments are required when reading from this parameter(in first to last order):
  17. GazeboReadArgument(name='pin', type='uint8', interpretation='number')
  18. GazeboReadArgument(name='value', type='uint8', interpretation='duty*255')
  19. Reads are idempotent(two succesive reads will produce the same data absent external changes).


  20. The slave provides the following description of ths parameter:Use ~460Hz PWM to write an analog value to a pin.
  21. >>> analogWrite(3,127)
  22. True
  23. >>> #It returned true because the slave sent an ACK
  24. >>> digitalRead = s.params['DigitalRead']
  25. >>> digitalRead.read(1)
  26. 0
  27. >>> #Parameters are callable objects, not functions. calling the param() directly
  28. >>> #is an alias for param.read()

  29. >>> #in Gazebo, function calls are read operations with arguments. Gazebo parameters also may support write operations, which are what the sound like.
  30. >>> digitalRead.read(1)
  31. 1
  32. >>> #After connecting voltage to Arduino input 1, we see that we read a 1 from it.
  33. >>> digitalWrite = s.params['DigitalWrite']
  34. >>> digitalWrite(2,'high')
  35. True
  36. >>> #Gazebo supports enumeration types
  37. >>> digitalWrite(2,0)
  38. True
  39. >>> #Which are compatible with simple numbers
  40. >>>master.close() #Otherwise pyserial sits around hogging the port till you restart or close from task manager