Copyright (c) 2004-2009, Michael E. Ferguson
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANT ABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Table Of Contents


What is AVRRA?
Getting Started
The Driver Model
Examples
Low-Level Drivers
      Digital Driver
      Analog Driver
      Serial Drivers
      Clock Driver
      I2C Driver
      Utility Functions
Sensor-Level Drivers
      Sharp IR Ranger Driver
      SRF-05 Sonar Driver
      Maxbotix: Sonar Driver
      SRF-08: I2C Sonar Driver
      CMPS-03:I2C Compass Driver
      Encoder Driver
      AVRcam Driver
Output-Level Drivers
      Motor Driver
      AX-12 Servo Driver
      Servo Driver
      Speech Synthesizer Driver

What is AVRRA?


AVRRA is the AVR-Robot-API. It is designed to be an easy to use API for programming robots with AVR micro controllers. It abstracts port setup and usage, as well as other low-level hardware functions. Support Drivers are provided for many popular sensors. Additionally, AVRRA provides direct support for several low-cost AVR boards on the market, such as the ARC Robot Controller (when upgraded to a mega324), AVRRA Mini, and AVRRA Lite. It is released under the BSD License, listed above.

NOTE: - The API currently supports the ATMEGA168 and ATMEGA324. Support for the 368, 164, and 644 is pending.

Getting Started
System requirements:

  • AVR GCC compiler, AVRDUDE programmer
  • Subversion client, for bleeding edge source


AVRRA requires no installation. It is simply a collection of header files written in C. Currently, there are three ways to get AVRRA: a STABLE release via ZIP/TAR files only, or the bleeding edge version from either ZIP/TAR or the subversion directory.

To get the STABLE release:
Go to http://avrra.sourceforge.net and select the newest release from Downloads

To get the DEVELOPMENT (bleeding edge) release:
Go to the Blundering Robotics subversion repository. Clicking on Tarball next to a file or folder name will allow you to download it. You will likely want to download just the avrra/library folder, most of the other information in the avrra directory is not documented yet. To check out a working copy on a unix machine:
    svn checkout svn://www.blunderingbotics.com/avrra/library avrra/library
Note that the example directory is /avrra/library/example if you are using subversion directly.
With either installation, you should set up your directory structure as such:
    /projectdirectory    
        /avrra
            /library
                /dev
        /example
        /robot1
        /robot2
        ...
In this way, the path from any robot file to the avrra files will be:
    ../avrra/library/file.h 

Once you have downloaded the AVRRA directories, you can begin building robots! But first, a little background on AVRRA. AVRRA is comprised of a set of header files, each containing a driver for a specific piece of hardware.

Most drivers have a name which is also used as the name of the file (driverName.h). Each driver has an Init(), and one or both of a getData() or setData() function. Some Init() functions are only for driver model compliance and do not have to be called, refer to the documentation for more specifics.

Base-level drivers provide basic functionality for using things such as analog ports, digital ports, and the serial port. An I2C driver is currently under development.

Sensor-level drivers provide functionality for specific popular sensors. The sharp IR driver provides functions which take a reading from the sensor and convert it to an URCP reading. Output-level drivers are similar.

AVRRA defines easy to use port numbering. Port A, Pin 1 is #0, Pin 2 is #1... and Port B, Pin 1 is #8. The numbers continue on sequentially.

There are special drivers, called "devices" which define a specific board, such as the AVRRA lite. They contain motor drivers, port definitions, and board initialization. These files are in the /avrra/library/dev folder. Currently the following exist:
  • dev\arc.h – for the ARC1.1 AVR board (m324).
  • dev\lite.h – for the AVRRA Lite board (m324).
  • dev\mini.h – for the AVRRA Mini board (m168).

Limitations
AVRRA is still a very young API. Support for certain items is still very limited. The digital driver is a resource hog - It uses almost 700 bytes of code and will be updated shortly. This API primarily targets the ATMEGA324 and ATMEGA168, and only supports clock frequencies of 14.7456MHz (Such as found on the Mini&Lite Boards). Documentation is currently sparse.

Items anticipated for V1.0 release:
  • Update digital driver, as set of macros.
  • Clock independence for srf05, clock, and servo libraries.
  • Document servo and encoder libraries
Items anticipated for other future release:
  • LCD drivers.
  • Add standard support for different systems of units.
  • Expand AX-12 servo library to handle sync write.

Examples

Below is an example, which will print IR readings to serial output:
// Robot specific port definitions
#define PIN_HEAD_IR		0x00		// PA[0] - HEAD IR

#include "../avrra/dev/lite.h"
		
int main(){	
    int x;
    
    // initialize stuff
    motorInit();
    gp2d12Init(PIN_HEAD_IR);
    serialInit(115200);
    Print("?Hello\n");

    while(1){ 
        x = gp2d12GetData(PIN_HEAD_IR);
        Print("?IR=");
        PrintNumber(x);
        Print("\n");
        delayms(500);
    }
};

Back to Contents

Low-Level Drivers

Digital Driver (digital.h)


The digital driver is used to access any digital port on the AVR. Ports are mapped to a linear address space: Port A has bits mapped to 0-7, Port B has bits mapped to 8-15, etc. Currently 31 or PortD7 is the highest port accessible through the digital driver.

Definitions

#define AVRRA_HIGH0xFF
#define AVRRA_LOW0x00
#define AVRRA_INPUT0x00
#define AVRRA_OUTPUT0xFF

Functions

void digitalInit(void) – does nothing, simply for driver model compliance.
char digitalGetData(char channel) – returns the value (1 or 0) of port channel.
      Acceptable channel values: 0x00 (PA[0])to 0x1F (PD[7]).
void digitalSetData(char channel, char data) – sets port channel to data (1 or 0).
void digitalSetDirection(char channel, char dir) – sets port channel to input or output.


Analog Driver (analog.h)


The analog driver is used to get a reading from the analog input ports. It handles all of the functions for setting the analog channel to the analog to digital converter.

Functions

void analogInit(void) – fires up physical hardware for ADC.
char analogGetData8(char channel) – returns a reading from port channel.
      Reading is 8-bits where 0x00 = 0VDC and 0xFF = 5VDC.
char analogGetData10(char channel) – returns a reading from port channel.
      Reading is 10-bits where 0x00 = 0VDC and 0x1FF = 5VDC.


Serial Driver (serial.h)


The serial driver implements a full duplex serial port on USART(0), the receiving end is buffered and interrupt driven. It is also commonly attached to a wireless output for off board debugging.

Functions

void serialInit(long baud) – initializes the driver
signed char serialRead() – gets a character (0 if none in buffer).
void serialWrite(unsigned char data) – sends a character.
int serialAvailable() – returns number of characters available in the buffer.
void serialFlush() – empties buffer.
void Print(const char *psz)) – prints a string to the serial port.
void PrintNumber(int value) – prints a integer (0-999) to the serial port.


Serial1 Driver (serial1.h)


This driver, for the ATMEGA324P, implements a second full duplex, buffered serial port.

Functions

void serial1Init(long baud) – initializes the driver
signed char serial1Read() – gets a character (0 if none in buffer).
void serial1write(char data) – sends a character.


Clock Driver (clock.h)


The clock driver creates a 60Hz system clock on timer2.

Issues: Currently is clock dependent. This should be fixed soon. Requires a 14.7546MHz clock.

Definitions

#define TGT_HAS_CLOCK

Functions

void clockInit(void) – initializes the 60Hz system clock.
void clockInit(int hertz) – initializes custom clock (FUTURE RELEASES?)
void clockDisable(void) – stops clock.
void clockEnable(void) – restarts clock, does not affect uptime.
t_time getClock(void) – returns system uptime, i.e. number of ticks of clock.


I2C Driver (I2C.h)


Provides access to the I2C bus, at 100KHz. Currently does not implement sort of interrupt driven communications.

Definitions

#define I2C_READ1
#define I2C_WRITE0

Functions

void i2cInit(void) – starts the I2C hardware.
void i2cStart(unsigned char address) – issues start condition, sends address/direction.
      0 = success.
void void i2cStop(void) – issues stop condition, releases bus.
unsigned char i2cReadAck(void) – read one byte from bus, request more.
unsigned char i2cReadNck(void) – read one byte from bus, issue stop condition.



Back to Contents

Sensor-Level Drivers

Sharp IR Sensor Driver (sharpir.h)


The Sharp IR drivers implement functions for GP2D12, GP2D120 (short), and GP2A0Y02YK (long) sensors. The three GP2D12 infrared range sensor gives off an analog voltage inversely proportional to the distance to the object sensed. The GP2D12 sensor driver handles conversion of this analog voltage into a reading in URCP distance coordinates (64points = 1ft).

Functions

void gp2d12Init(char channel) – initializes driver.
int gp2d12GetData(char channel) - returns a reading from port channel in URCP.
void gp2dShortInit(char channel) – initializes driver.
int gp2dShortGetData(char channel) - returns a reading from port channel in URCP.
void gp2dLongInit(char channel) – initializes driver.
int gp2dLongGetData(char channel) - returns a reading from port channel in URCP.


SRF-05 Sonar Ranger Sensor Driver (srf05.h)


The SRF-05 sonar ranger from Devantech provides a single wire interface for triggering and receiving the time of flight data.

Issues: Currently is clock dependent. This should be fixed soon. Requires a 14.7546MHz clock.

Functions

void srf05Init(char channel) –
unsigned char srf05GetData(char channel) - returns a reading from port channel, in inches.


Maxbotix Sonar Ranger Sensor Driver (maxbotix.h)


The Maxbotix EZ family of sonar rangers provide a two wire interface for triggering and reading an analog distance.

Functions

void maxbotixInit(char control, char analog) – Initializes a maxbotix sensor
void maxbotixPing(char control) – causes the sensor to send out a ping.
int maxbotixGetData(char analog) – returns a reading analog port, in URCP. User should ping first.


SRF-08 I2C Sonar Driver (srf08.h)


Driver for the Devantech SRF-08 and SRF-02 I2C sonar ranging sensors. There can be up to 16 devices on the bus, with addresses 0xE0-0xFF (even numbers for write, odd for read). You must call Ping before calling Read. Calls should be a minimum of 50ms apart. When calling these functions, the device number passed is the offset from the base:

    Device Address = Base Address (0xE0) + (2 * device_no)

Definitions

#defineSRF_ADDR0xE0 // Base Address
#define SRF_COMMAND0x00 // command register
#define SRF_LIGHT0x01 // light sensor register
#define SRF_ECHO_H0x02 // 1st echo high byte
#define SRF_ECHO_L0x03 // 1st echo low byte
#define SRF_2ND_H0x04 // 2nd echo high byte
#define SRF_2ND_L0x05 // 2nd echo low byte
/* choices for units */
#define SRF_CMD_INCH0x50
#define SRF_CMD_CM0x51
#define SRF_CMD_MS0x52

Functions

void srf08Init(void) – initializes I2C bus.
void srf08SetUnits(unsigned char units) – Sets the units we wish to use - should be one of the values defined above.
void srf08GetVersion(unsigned char device) – Gets the version of the sonar device.
void srf08Ping(unsigned char device) – Pint the sonar before we read a distance back.
void srf08GetData(unsigned char device) – Gets a reading from the sonar.


I2C Compass (cmps03.h)


Driver for the Devantech CMPS-03 I2C compass.

Definitions

#define CMPS_ADDR /td>0xC0
// Register Definitions  
#define CMPS_VERSION0x00
#define CMPS_BEARING0x01
#define CMPS_BEAR_HI0x02
#define CMPS_BEAR_LO 0x03
#define CMPS_CALIBRATE0x0F

Functions

void cmps03Init() – initializes I2C bus.
unsigned char cmps03GetData() – reads a heading from compass (URCP BinaryRADianS 0-255).
unsigned char cmps03GetVer() – reads the version number from compass.


Encoders Driver (in device file)


Uses INT0 and INT1 plus two additional pins to provide full quadrature encoder support. Still in development. See source code for details.


AVRCam Driver (avrcam.h)


Driver for AVRCam. NOTE: This driver is still under development – and only for the ATMEGA324P. It currently defaults to using USART1 – but does not use serial1.h. Also note that names of functions in this driver are likely to change in future releases.

Functions

void visionInit() – initializes AVRCam and serial port 1. This will enable an interrupt routine that handles information from the camera.
byte pingCam() – pings AVRCam, returns 1 if successful, 0 otherwise.
void passRawCam() – passes a raw image back to the PC (requires serial.h)
void enableTracking() – turns on tracking.
void disableTracking() – turns off tracking


Back to Contents

Output-Level Drivers

Motor Driver (in device file)


There are several different possible motor controller techniques depending on how the motor driver is connected to the controller and whether closed loop control is used. The interface below is the minimum specification that should be implemented for ALL motor drivers (typically in a device file). Motor controls use the 8-bit TIMER0.

For all motors, 255 is full speed forward, -255 is full speed backward, and 0 is stopped. Note that we can therfore call something like

        motorRight(BACKWARD * HALF_SPEED);
to go backwards at half speed.

Definitions

#define FORWARD1
#define BACKWARD-1
#define FULL_SPEED255
#define HALF_SPEED127
#define REG_SPEEDvaries by device
#define STOP0

Functions

void motorInit(void) – initializes the PWM drivers.
void motorStop(void) – stops both motors, saves values for a resume.
void motorResume(void) – restarts both motors at previous speed (after a stop).
void motorLeft(int speed) – 255 = full forward, -255 = full backward, 0 = stop.
void motorRight(int speed) – 255 = full forward, -255 = full backward, 0 = stop.
void motors(int lspeed, int rspeed) – set both motors at once.

Optional (requires encoders):
void moveX(int inches) – closed loop move X inches (forward is positive).
void turnX(int angle) – closed loop turn of an angle, in degrees (left is positive).


AX-12 Servo Driver (ax12.h)


The servo system uses USART1 on the ATMEGA324P to control AX-12 servos. See the source code for details.


Servo Driver (servo.h)


The servo system uses the 16-bit TIMER1 to power 2 servos. SERV0_A and SERVO_B are pin definitions for PD5 and PD4 (PB1 and PB2 on the m168), repectively. Range of servos is -90 to 90 degrees, center adjustment is best determined by trial and error. Invert will change the direction around the center point.

Issues: Currently is clock dependent. This should be fixed soon. Requires a 14.7546MHz clock.

Functions

void servoInit(int channel, int centerAdj, int invert) – Initializes a servo, with a center adjustment and invert.
void servoSetPosition(int channel, int position) – Sets position of servo -90 to 90 degrees.
void servoGetPosition(int channel) – Reads position from memory (not from servo!).


Speech Synthesizer Driver (sp03.h)


Provides a very simple connection to the Devantech SP03 via I2C. Currently only plays the pre-defined phrases held in memory on the SP03, there is not yet support for buffer loading.

Definitions

#define SP03_ADDR0xC4
#define SP03_CMD_REG0x00
#define SP03_VER_REG0x01
#define HALF_SPEED127
#define REG_SPEEDvaries by device
#define STOP0

Functions

void sp03Init(void) – Initializes I2C bus, SP03 needs no initialization.
void sp03GetData(void) – Reads status, 0 = done.
void sp03GetVer(void) – Reads version of SP03.
void sp03Speak(unsigned char phrase) – Speaks a pre-defined phrase, 1-30.


Back to Contents