WebbotLib AVR library
WebbotLib It just does it
  C++ documentation  C documentation

DimensionEngineering/Sabertooth.h

Adds support for various motor controllers from Dimension Engineering.
Namely the Sabertooth 2 x 5 Amp controller, the SyRen10 and SyRen25 boards.
sabertooth2x5big.jpg
These controllers require a UART port where the Gnd and Transmit pins are connected to each board on the 0V and S1 inputs respectively.
These boards can be driven in a number of different modes but we will use only two of these modes namely:
Each board can drive up to two motors, called motors 1 and 2.
Simplified serial mode can only be used to control one board (so a maximum of 2 motors) - but has the advantage that it only has to send one byte for each motor and the baud rate can be set via the DIP switches to select either 2400, 9600, 19200 or 38400 baud.
Packetized serial mode has the advantage that multiple boards (up to 8 i.e. 16 motors) can be placed on the same serial line - each board has a unique address set via the DIP switches. This combination of address and motor number is therefore unique for each motor. The advantage of this mode is the ability to control multiple boards but the disadvantage is that we need to send 4 bytes for each motor compare with one for simplified serial mode. However: the greatest disadvantage is that packetized mode uses an 'auto baud rate' detection algorithm with valid baud rates of 2400, 9600, 19200 and 38400 baud. This detection is based on the first byte that it is automatically sent by this library. Although this 'sounds' easy the practical issue is that your main controller board 'may' suffer from contact bounce on its power switch - the end result being that one or more spurious characters may be sent over the UART and confuse the Sabertooth board as to what the actual baud rate should be. If you are using separate power supplies for the Sabertooth and your micro-controller board then this also means that you need to 'turn on' the Sabertooth card before, or at the same time, as your micro-controller. When using this mode the library will wait for 2 seconds before sending the automatic baud detection character.
In order to use the boards you must first create each motor by using 'MAKE_SABERTOOTH_MOTOR' assigning each motor an address (if using Packetized mode - as per the DIP switches) and a motor number (1 or 2 - since each board supports 2 motors) and then combine them all into a driver using 'MAKE_SABERTOOTH_DRIVER' which then allows you to specify which mode you want to use.
This driver is then passed to 'sabertoothInit' when your application is initialising (in appInitHardware). Your main program can then set the speed of each motor using act_setSpeed in the same way as for any other servo or motor.
Here is a small example for the Axon that makes the motors spin forward and backward at different speeds and assumes that the board address is set as 128:-
#include "sys/axon.h" // We are using the Axon
// Include files
#include "uart.h"
#include "Motors/DimensionEngineering/Sabertooth.h"
 
// Create motors 0 and 1 at address 128
SABERTOOTH_MOTOR motor1 = MAKE_SABERTOOTH_MOTOR(FALSE, 128,1);
SABERTOOTH_MOTOR motor2 = MAKE_SABERTOOTH_MOTOR(FALSE, 128,2);
 
// Create a driver that includes them both and uses UART0 at 19200 baud
SABERTOOTH_MOTOR_LIST PROGMEM motors[] = {&motor1,&motor2};
// Create the driver using simple serial mode....
SABERTOOTH_DRIVER driver = MAKE_SABERTOOTH_DRIVER(motors, UART0, 19200, SIMPLE);
// ... or use packetized mode if you have more than one board
//SABERTOOTH_DRIVER driver = MAKE_SABERTOOTH_DRIVER(motors, UART0, 19200, PACKETIZED);
     
// Initialise the driver in my start up code
void appInitHardware(void){
    sabertoothInit(&driver);
}
TICK_COUNT appInitSoftware(TICK_COUNT loopStart){
    return 0;
}
// Move the motors back and forth
int dir=1; // Are we increasing speed (+1) or decreasing speed (-1)
TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart){
    // Get the current speed of motor 2
    DRIVE_SPEED speed = act_getSpeed(&motor2);
    // Increase or decrease it
    speed += dir;
    // Change direction if we've hit the end stop
    if(speed == DRIVE_SPEED_MAX){
        dir = -1;
    }else if(speed == DRIVE_SPEED_MIN){
        dir = 1;
    }
    // Set the speed of both motors
    act_setSpeed(&motor1,speed);
    act_setSpeed(&motor2,speed);
    return 40000; // Only call me every 40ms
}

 

Function

 


SABERTOOTH_MOTOR MAKE_SABERTOOTH_MOTOR(boolean inverted, uint8_t address, uint8_t motornumber)

Defines a motor on a controller board.
The inverted parameter specifies whether or not the motor should turn in the opposite direction ie if the wheels are mounted on the left and right of the robot then one motor needs to turn clockwise and the other anti-clockwise in order to go forwards. So one motor should be defined as 'inverted'.
The address parameter defines the address of the board - as set on the dip switches.
The motornumber parameter specifies the motor number on the board ie motor 0 or motor 1.
For example: to define motor 0 on a board at address 128 then declare the motor as follows:-
SABERTOOTH_MOTOR motor1 = MAKE_SABERTOOTH_MOTOR(FALSE, 128,0);
Having created the individual motors you need to group them into a list:-
SABERTOOTH_MOTOR_LIST PROGMEM motors[] = {&motor1,&motor2};
Note the '&' before the name of each motor, and the use of PROGMEM.

SABERTOOTH_DRIVER MAKE_SABERTOOTH_DRIVER(SABERTOOTH_MOTOR_LIST motors, UART* uart, BAUD_RATE baudrate, SABERTOOTH_MODE mode)

Groups together all of the motors, from as many boards as you like in packetized mode or from one board if using simple mode, that are driven via the same UART.
The first parameter is the list of motors and is followed by the UART to be used and the required baud rate.
The mode parameter can be either PACKETIZED or SIMPLE.
NB Check the data sheets to see what baud rates are allowed. When using PACKETIZED mode you must set up the DIP switches to match the board address and the baud rate is auto-detected. In SIMPLE mode then the DIP switches must be set to match the baud rate you are using.

sabertoothInit(SABERTOOTH_DRIVER* driver)

Initialise the motor driver.
This should be called once - in your initialisation code: appInitHardware();
This will setup the baud rate for the UART and set all motors to a speed of zero. As per the manual: this method will add a delay of 2 seconds before returning in order to give the boards a chance to initialise themselves.
You may now change the speed of the motors in the usual way via:-
act_setSpeed(motor1, speed);
Look at actuators.h for more information. Note especially that this provides the act_getSpeed call to query the current speed - which can save your main loop from trying to store this in yet another variable. Obviously the value returned is the last value you set using setSpeed - ie its the 'last requested speed' not the 'physical current speed'. To find the actual speed you would need some encoder hardware and use the encoder support provided elsewhere in this library.

Valid XHTML 1.0 Transitional