Help with arduino and sabertooth 2x12

Hi All,

I just recieved my wonderful A4WD rover kit with a sabertooth 2x12. The problem is that I cannot get power to the motor terminals (and I am also a noob).

Hardware involved:
Adruino duemilanove
Sabertooth 2x12
ghm-01 motor
14.8v 4S20C lipo battery
2x GHM-01 motors
2x GHM-16 motors
2X encoders

Connections:
Arduino Serial tx -> sabertooth s1
B- -> battery neg (black wire)
B+ -> battery pos (red wire)
m1a -> motor yellow wire
m2a -> motor read wire

I have the sabertooth set to address 131 according to the DIP wizard. When I power everything on the status1 led goes solid and the status 2 will blink 4 times then pause (as they should for a 4S battery). The TX led on the arduio will blink but when testing voltage at the motor connectors I get zero volts.

What am I doing wrong??

const int BAUDRATE = 192000;
const byte ADDRESS = 131;

void setup()
{
  //Hardware Serial
  Serial.begin(BAUDRATE);
  delay(2000);
  Serial.print(170, BYTE); //bauding character to Sabertooth
  delay(200);

}

void loop()
{
  int speed = 127;
  int direction_m1 = 0;
  int direction_m2 = 4;
  
  Serial.print(ADDRESS, BYTE);
  Serial.print(direction_m1, BYTE);
  Serial.print(speed, BYTE);
  Serial.print ( ((ADDRESS + direction_m1 + speed) & 0b01111111), BYTE); //checksum
  delay(10000);
}

Probably need more info to help figure out.

Like which Sabertooth 2x12. My assumption is the non-RC version… What are your actual dip switches set to…

Are you sure in your code that the baud rate is set correctly: const int BAUDRATE = 192000;
It probably should be: 19200

I am not sure if you can hook up the motors directly up to 14.8v. May need some switching regulator to handle properly…

Kurt

Thanks for the response.

Yes, it is the non-RC version.
Assuming that towards the edge of the board is ON and towards the center of the board is OFF.
1 - ON
2 - ON
3 - ON
4 - ON
5 - ON
6 - OFF

Fixed the baud rate, but it didn’t work.

I don’t think it is the motors. When apply power I get zero volts at the motor terminals. I would expect I would get close to the same value that I get at the battery terminals or a flat 12V.

It would probably help to have pictures showing your setup to make sure of things.

Looking at page 17 of the users guide (PDF) I am not sure your dip switches are correct. Unless you have your meaning of OFF/On reversed. I don’t remember which direction is marked as on or off, but should be 00L001 where L=0 for lithium cuttoff… So I would check to make sure that they are not all reversed…

If you have lithium cut off turned on and your voltage is low it may not give any power to the motors. So you should make sure it is charged properly. I am not sure again what these motors which expect 12v will do with 14+v. My guess is that they will not like it.
You may need some form of voltage regulator…

On the code side I am not sure about the set baud rate command that you have in the init… I believe when shipped the unit expects 9600 baud rate, which you can change. To change it I believe you have to send a specific packet at 9600 baud which will permanently change it. I believe the packet should look something like: <0xf - baud change command><3 - 19200>

If it were me, I would try removing your init stuff, setup your serial port for 9600 and try sending your commands at 9600 and see if that works.

Good Luck
Kurt

Here is my set up:
img156.imageshack.us/img156/1025/img1426ou.jpg
img231.imageshack.us/img231/4986/img1421h.th.jpg
This is the meter reading I get at the motor terminals. It will range from 0.00 to 0.04.

I verified that I have the correct ON/OFF positions and removed the init code but no luck.

const int BAUDRATE = 9600;
const byte ADDRESS = 131;

void setup()
{
  //Hardware Serial
  Serial.begin(BAUDRATE);
  delay(2000);
  //Serial.print(170, BYTE); //bauding character to Sabertooth
  //delay(200);

}

I am not so worried about connecting motors yet. I would like to verify I am getting voltage at the motor terminals first.

Thanks for the help.

One thing I see is that you don’t have a ground wire running between the Sabertooth and the Arduino, so the signals may not work properly. I believe it is marked on the Sabertooth as 0v.

Kurt

I just got done trying that as well and all it will get me is a blinking error LED.

When I power on the sabertooth the error led will light up then turn off ( normal operations I am guessing ). When I turn on the Arduino the error LED will turn on solid for ~3 seconds then start blinking rapidly.

img153.imageshack.us/img153/8075/img1427kg.th.jpg

Sorry, but don’t know much more what to advise you. It may easily be that the Sabertooth detects that you don’t have any motors connected and shuts off the system or the like.

Also I am not familiar enough with the Arduino 2009, but you appear to be trying to hook it up to the hardware serial port, which is also used by the USB port. So having them both connected may not work here. I have only used Arduino Megas which have 4 hardware serial ports.

My guess is that you will need to connect the sabertooth up to a different digital IO pin and then use the software serial library, which I believe has a max speed of 9600.

Good Luck
Kurt

Kurt,

That’s an interesting observation on the RX/TX ports. A Sparkfun tutorial describes connecting the LAN board up (the RX/TX pins are on the header), and says nothing about disabling the output of the USB chip.

You caught the ground connection before I could reply!

I don’t see any jumpers on my UNO.

Probably OK to just output to both Sabertooth and USB chip.

Alan KM6VV

On an FTDI chip arduino, the FTDI output is in parallel with the board rx/tx pins, such that both input/output to the microcontroller.

I tried to use the Softserial library of the arduino and still get no results at the motor terminals. I used pin digital pin 12 on the ardunio as my TX pin so all I have done was to move the green wire to pin 12 and still have the arduino gnd to 0V on the sabertooth.

Thanks for all the help

With the software serial library did you initialize the IO pins to be input/output. I found when I did a simple test that I did not get any output until I did so. Here is the quick and dirty version of your stuff…

[code]#include <SoftwareSerial.h>

const int BAUDRATE = 9600;
const byte ADDRESS = 131;
SoftwareSerial mySerial = SoftwareSerial(2, 3);
void setup()
{
//Hardware Serial

mySerial.begin(BAUDRATE);
pinMode(2, INPUT);
pinMode(3, OUTPUT);
Serial.begin(38400);
delay(2000);
//mySerial.print(170, BYTE); //bauding character to Sabertooth
//delay(200);

}

void loop()
{
int speed = 127;
int direction_m1 = 0;
int direction_m2 = 4;

mySerial.print(ADDRESS, BYTE);
mySerial.print(direction_m1, BYTE);
mySerial.print(speed, BYTE);
mySerial.print ( ((ADDRESS + direction_m1 + speed) & 0b01111111), BYTE); //checksum
delay(10000);
}
[/code]

I verified the output stream looked OK using my logic analyzer…

Kurt

P.S - This was run on seeeduino Mega…

Yeah, that’s the problem!

the FTDI TX goes to RX of UNO, and the RX goes to the TX of UNO (NOT parallel).

But I see Kurt is using SoftwareSerial, using pins 2 & 3, so no conflict.

Connecting the NET card (via stacking pins) STILL would be parallel to the FTDI (prewired on UNO), and I can see no way to prevent a contention (cut a trace??).

Kurt,

Can’t you just do a #define the baudrate? Or is that what Arduino is actually doing? Does it reserve a ram byte? I know for const or initialization of a variable, you get a ROM table to initialize the RAM. I don’t know what Arduino is doing…

Alan KM6VV

Hi Kurt,

With the code you provided I get the error led to go solid for ~3 seconds then it starts a rapid blink. This is the same behavior I get when I use the hardware serial.

I also tried this code (found here forums.trossenrobotics.com/showthread.php?t=3636 ) adapted it to my 2x12 and I still get the error behavior.

#include <SoftwareSerial.h>

/*****************************************************
 * DIP Switches as per the wized:
 * - NiMh Battery
 * - TTL RS232
 * - Simplified Serial Mode
 * - Just one Sabertooth conected
 * - 9600 baudrate
 *
 * Pin 1 - OFF
 * Pin 2 - ON
 * Pin 3 - ON
 * Pin 4 - ON
 * Pin 5 - OFF
 * Pin 6 - OFF
 ****************************************************/

// Labels for use with the Sabertooth 2x12 motor controller

// Digital pin 13 is the serial transmit pin to the 
// Sabertooth 2x12
#define SABER_TX_PIN               13

// NOT USED (but still init'd)
// Digital pin 12 is the serial receive pin from the 
// Sabertooth 2x12
#define SABER_RX_PIN               12

// Set to 9600 through Sabertooth dip switches
#define SABER_BAUDRATE             9600

// Simplified serial Limits for each motor
#define SABER_MOTOR1_FULL_FORWARD  127
#define SABER_MOTOR1_FULL_REVERSE  1

#define SABER_MOTOR2_FULL_FORWARD  255
#define SABER_MOTOR2_FULL_REVERSE  128

// Motor level to send when issuing the full stop command
#define SABER_ALL_STOP             0


SoftwareSerial SaberSerial = SoftwareSerial( SABER_RX_PIN,
                                             SABER_TX_PIN );

void initSabertooth( void )
{
  // Init software UART to communicate 
  // with the Sabertooth 2x12
  pinMode( SABER_TX_PIN, OUTPUT );

  SaberSerial.begin( SABER_BAUDRATE );     

  // 2 second time delay for the Sabertooth to init
  delay( 2000 );

  // Send full stop command
  setEngineSpeed( SABER_ALL_STOP );
}

/*****************************************************
 * setEngineSpeed
 *
 * Inputs - cSpeed_Motor1 - Input a percentage of full 
 *                          speed, from -100 to +100
 *
 *****************************************************/
void setEngineSpeed( signed char cNewMotorSpeed )
{
  unsigned char cSpeedVal_Motor1 = 0;

  unsigned char cSpeedVal_Motor2 = 0;
  
  // Check for full stop command
  if( cNewMotorSpeed == 0 )
  {
    // Send full stop command for both motors
    SaberSerial.print( 0, BYTE );

    return;
  }  
  
  // Calculate the speed value for motor 1
  if( cNewMotorSpeed >= 100 )
  {
    cSpeedVal_Motor1 = SABER_MOTOR1_FULL_FORWARD;

    cSpeedVal_Motor2 = SABER_MOTOR2_FULL_FORWARD;
  }
  else if( cNewMotorSpeed <= -100 )
  {
    cSpeedVal_Motor1 = SABER_MOTOR1_FULL_REVERSE;

    cSpeedVal_Motor2 = SABER_MOTOR2_FULL_REVERSE;
  }
  else
  {
    // Calc motor 1 speed (Final value ranges from 1 to 127)
    cSpeedVal_Motor1 = map( cNewMotorSpeed, 
                           -100, 
                            100, 
                            SABER_MOTOR1_FULL_REVERSE,
                            SABER_MOTOR1_FULL_FORWARD );

    // Calc motor 2 speed (Final value ranges from 128 to 255)
    cSpeedVal_Motor2 = map( cNewMotorSpeed, 
                           -100, 
                            100, 
                            SABER_MOTOR2_FULL_REVERSE, 
                            SABER_MOTOR2_FULL_FORWARD );
  }

  // Fire the values off to the Sabertooth motor controller
  SaberSerial.print( cSpeedVal_Motor1, BYTE );

  SaberSerial.print( cSpeedVal_Motor2, BYTE );
}
void setup( )
{
  initSabertooth( );
}

void loop ( )
{
  /*
  // Full stop
  setEngineSpeed( 0 ); 

  // Half reverse
  setEngineSpeed( -50 );

  // Full reverse
  setEngineSpeed( -100 );

  // Half forward
  setEngineSpeed( 50 );
 */
  // Full forward
  setEngineSpeed( 100 );
}

Do you have a reset sw or pins on the sabertooth? It could be that the motor controller is getting commands before it is ready.

Try a reset, and/or add a program startup delay to give the sabertooth time to initialize.

Alan KM6VV

No reset on the sabertooth. I power cycle it for the reset and then power it up before I power up the arduino.

No matter what delay I give it the results are the same. I end up with a rapid blinking error led.

Have you hooked any motor up to the Sabertooth? It probably will detect that there is no motor and not be happy. I can not directly test your setup as again I have arduino Mega and my Sabertooth is an older 2x10, which looks like it is reasonably compatible, but looking it it’s instructions I see the information about auto baud rate detection and why you have to send an 0xaa (170) to it as the first character…

Kurt

Yes, what he said. The idea I have is that if one wants to send serial data straight from the arduino IDE serial monitor to the sabertooth for testing, one could connect the sabertooth rx to the arduino rx pin, basically placing the arduino and sabertooth in parallel for receiving data from the serial monitor. There may need to be code running on the arduino to place the arduino rx pin in a a condition that would not impact the sabertooth ability to receive the serial data.

Yes, you can have the monitor TX going to both Arduino and sabertooth RX. You can also use a extra PC serial port to “white rat” the commands to the 'tooth.

I’d really check the baudrate settings.

Alan KM6VV

Kurt,

I connected the motors to the sabertooth but still no luck. I tested the motors by connecting a 7.4v battery to them. Everything seems to work but the sabertooth.

Alan and zoomkat,

I have tried monitoring the RX commands and it appears the commands are being sent correctly. This can be done when using the arduino hardware serial. I don’t have a ftdi cable to see if the software serial is doing the same.