A set of sensor and actuator modules for mobile robots. The modules are build using AVR ATMega microcontrollers and use a minimum of external component. The microcontrollers are programmed in C (GCC) to allow for easy modification of the code. I2C is used to communicate between the modules, the modules are interconnected with only 4 wires. The i2cMaster module can be used to control the modules via a serial interface. The actual module code and the bus interface code are split in two separate source files, it is also possible to rebuild the code for use with a different communicatio interface.


This project is under the GPL license, see the LICENSE.txt file for details.


Click here to download OpenSense.

Available modules

Module Status Description
I2cMaster Works Acts as a interface between the i2c module bus and the external serial bus.
Servo Works Actuator for up to 16 hobby servos inclusive speed control.
Sonar Works Sonar distance sensor for up to 8 sonar units.
Motor Works Synchonized and PID speed controlled actuator for a two DC motor differential drive robot with encoders.
DockTx Works Docking station IR transmitter.
DockRx Works Docking station IR receiver.
RcReceiver Works Decodes signals from a RC-Receiver.
RcReceiverMaster Works I2c bus master, decodes RC-Receiver signals and drives DC motor and servos. Mainly for demostration purposes: it digitize the RC-Receiver servo PWM signals, sends them via i2c to the servo module which converts them back to servo PWM signals. Easier is of course to directly connect the servo to the RC-Receiver.
LCD Works Drives a character LCD display. Currently integrated in modI2cMaster, not individual i2c module yet.
Battery Planned Monitoring of discharge/charge current, voltage and Ah.
IrDistance Planned Drives up to 5 Sharp GP2D12 (10-80cm) / GP2Y0A02YK (20-150cm) / GP2D120 (4-30cm) IR distance sensors.
IrRemote Planned Receive commands from a IR remote control.
Radio Planned Receive/Transmit via low cost 433 MHz radio modules.

Files and Directories

doc The documentation is in the ‘doc’ directory.

modXXX contain the source code and Makefile for a specific module. Run ‘make’ in a mod subdirectory to compile the source code and program the microcontroller.

lib contains shared libraries. The libraries are the actual workhorses of the modules, each module is actually a i2c wrapper around the library code. It’s is therefor possible to combine several libraries into a single module, as long as the libraries don’t exclusively use the same resources such as timers or interrupts. For example the i2cMaster module includes the lcd.c library to implement a lcd driver as well.
vb_HexTerm Contains a terminal program written in VB6 to communicate with i2cMaster. Functioning but needs some cleanup work. In the send box type ‘s’ and hit enter to scan the i2c bus. Note: all input is decimal, so ‘r 170 10 4′ reads 4 bytes from slave AA (=170) command 0A (=10).

Software and Hardware Setup

  • Download OpenSense and WinAVR.
  • If you do not have a programmer, solder together this very simple STK200 compatible parallel port programmer:
    Wire Par-Port Pin ATMega Signal AtMega8 (DIP) Pin AtMega16 and 32 (DIP) Pin
    1 25 Grd 8 11
    2 8 SCK 19 8
    3 4 MISO 18 7
    4 7 MOSI 17 6
    5 10 /Reset 1 9
      connect 2 to 12      
      connect 3 to 11      
  • Connect the programmer to an ATMega8 and apply VCC.
  • Run “avrdude -p m8 -c stk200 -t” from a DOS prompt.
  • For 8Mhz internal oscillator enter commands: “write lfuse 0 0x0d1″ and “write hfuse 0 0xe4″
  • Or, for external crystal oscillator enter commands: “write lfuse 0 0x0d1″ and “write hfuse 0 0xef”
  • Type “quit” to exit avrdude
  • cd to one of the pq-module directories
  • Type “make” and the module will be compiled and programmed on the microcontroller.

    Why AVR ATMega?

  • Low cost: 8k flash 1k ram for less than $4 each.
  • Availability: Can be easily procured in small quantities.
  • DIP versions for easy prototyping (bread board).
  • Low cost programmers available.
  • Opensource C compiler (GCC) available.
  • Opensource development toolchaing (WinAVR) available.
  • Large developer community with loads of examples.
  • C-friendly architecture: stack, single linear RAM and Flash spaces.
  • Full range of periphirals: on-chip oscillator, timers, uart, i2c, adc, hardware 8x8bit multipicator, etc.
  • High speed processing: up to 24 MIPS with ATMega8x devices.

    Programming Style

    The programs are designed for small devices, usually 8k flash. I tried both to keep the number of files to a minimum and the Makefiles as uniform and simple as possible. I opted to directly include the library c files in the code usually without using header files. Precompiler #define directives and macros are used to steer the properties of the individual modules. Read the library source file to get a list of the available options. All functions, macros and defines in a library are prefixed with a 3-5 character prefix followed by an underscore. For example all mot_XXX functions are in the motor.c library.

    I2C interface

    One address (0xFF) has been reserved for default functionalty in each module:

  • Set the I2C SLA address
  • Set the I2C bus speed
  • Enable/disable interrupts.
  • Reset
  • Read module configuration and save the configuration to eeprom
    I2C Command Description
    r ff 00 00 Get 16 char device string (shortcut= r ff)
    r ff 01 00 Get 2 byte twipq library verson (major,minor) (shortcut=r ff 01)
    w ff 02 00 <newsla> Set slave i2c address to newsla
    r ff 02 01 Get interrupts status : 1=send interrupts to busmaster, 0=disable interrupts
    w ff 02 01 <0|1> Set interrupts status : 1=send interrupts to busmaster, 0=disable interrupts
    r ff 02 02 Get i2c speed as multiple of 10kbaud
    w ff 02 02 <speed> set i2c speed as multiple of 10kbaud
    r ff 03 <adr> Read user eeprom, see module documentation for details.
    w ff 03 <adr> <val> Write user eeprom, see module documentation for details.
    w ff 04 Reset device (required after changed in configuration)
    w ff 05 Clear eeprom + reset + load defaults
  • Converts commands received on the serial interface to i2c commands. The HexTerm program in the vb_HexTerm directory is a simple client for the I2cMaster serial protocol. Default setup is for an ATMega8-16 with an 14.7456MHz crystal, serial port at 8-N-1 115200 baud.

    Serial Transmission Protocol

    Each message is terminiated with an 0x0a byte, 0x0a is a newline character (‘\n’, decimal 10). The backslash (‘\’) character is used as escape character. Unlike normal c-style escaping the second character needs to be the inverse of the character to be transmitted. So, if 0x0a appears in the message itself it is escaped as: 0x5c 0xf5. Here is 0x5c the backslash character (‘\’, decimal 92) and 0xf5 the bit inverse of 0x0a. The backslash character is escaped as 0x5c 0xa3, a backslash followed by the bit inverse of a backslash.

    This protocol was chosen because it can be easily encoded and decoded and it allows for quick resync when a transmission got corrupted. For the sake keeping things simple and for saving processor time no error checking was included.

    Serial commands

    The following commands can be sent over the serial interface.

    Perform a i2c bus scan, returns an ‘s’ message for each device found on the i2c bus.

    Example: i2c bus scan
    Transmit serial data to i2cMaster: 73 0A
    73 is ‘s’, instructs i2cMaster do a i2c bus scan.
    0A terminates the message.

    Received reply from i2cMaster: 73 AC 53 65 72 76 6F 31 36 20 20 32 2E 30 30 33 0A
    In ascii: 73=’s’ AC=slave-address “Servo16 1.003″ 0A=end-of-message
    In words: at slave address AC is a Servo16 module with version 1.003 connected.

    w <SLA> <cmd> [arg1] [arg2] [arg3] [arg4] [arg5] [arg6] [arg7] [arg8]
    Write cmd and arguments to slave SLA, the arguments are optional

    Example: Set servo 2 to center position
    Transmit serial data to i2cMaster: 77 AC 02 80 0A
    77 is ‘w’, instructs i2cMaster to write to the i2c bus.
    AC is the slave address of the servo module.
    02 selects servo 2.
    80 sets servo 2 to position 128.
    0A terminates the message.

    Received reply from i2cMaster: 77 AC 02 80 0A
    This is the echo of the command sent.

    The actual data send over the i2c bus is “start AC 02 80 stop”.

    r <SLA> <cmd> [arg1] [arg2] [arg3] [arg4] [arg5] [arg6] [arg7] [arg8] <ReadLen>
    Read <ReadLen> bytes from slave SLA, the arguments are optional
    Reply: r <CmdLen> <SLA> <cmd> [arg1] [arg2] .. [arg7] [read1] [read2] .. [read(ReadLen)]
    The issued read command is echoed back, with the read bytes appended. CmdLen is the length of the issued read command (not counting <ReadLen>.

    Example: Get the servo position of servo 3 and 4
    Transmit serial data to i2cMaster: 72 AC 03 02 0A
    72 is ‘r’, instructs i2cMaster to read from the i2c bus.
    AC is the slave address of the servo module.
    03 selects servo 3.
    01 read two bytes.
    0A terminates the message.

    Serial data received from i2cMaster: 72 02 AC 02 40 50 0A
    72 is ‘r’
    02 number of bytes in the read command.
    AC is the slave address of the servo module.
    02 the module command sent.
    40 first read byte, position of servo 3.
    50 second read byte, position of servo 4
    0A terminates the answer.
    Also servo 3 is at position 40 hex and servo 4 is at 50 hex.

    The actual data send over the i2c bus is “start AC 03 repeated-start AD 40 50 stop”.

    See modSonar.c source for details.

    © 2018 Tech Toy Hacks Suffusion theme by Sayontan Sinha