Programming for RC connections

I am currently working on a project for an RC car. The car is being powered by a brush motor with a Sabertooth 2x32 motor controller. I am able to send servo commands from the Arduino (Mega 2560) to get it to move but I can't seem to get it moving from an RC connection. I want to be able to have it run programs, and then when I flip a switch it allows for RC communications.

Motor Controller: Sabertooth 2x32 regenerative dual motor driver
RC: http://www.hobbypartz.com/fs-gtr3c-receiver.html

Thanks, any tips/notes are highly appreciated.

If the Arduino part works, then the place to ask questions about RC control is an RC forum. You don't ask you Arduino questions on the RC forum, do you?

Actually, the RC communicates fine without the Arduino, I would like to incorporate the Arduino which is why I came to the Arduino forum.

If the servo control outputs from the arduino and RC receiver are connected together, then you may need to put a little diode in each line before they connect. Also the arduino, servo batteries, and rc receiver grounds probably should be connected together.

Power the Arduino from whatever channel on the receiver you are trying to read, nice smooth voltage source, no headache with having an extra battery, gets all those pesky grounds hooked together for you (which yes is totally important).

A beefy servo can pull a couple amps at lock/stall without smoking the receiver so it is pretty unlikely your Arduino project is going to be too much load unless you are trying to drive like 50 Neopixels or something!

Please post the code that you have tried. Do the Arduino and the RC receiver have a common ground and how is the RC output connected to the Arduino ?

I am able to send servo commands from the Arduino (Mega 2560) to get it to move but I can’t seem to get it moving from an RC connection.

Actually, the RC communicates fine without the Arduino

These two statements can not both be true.

I suspect that what he means is that when the car is connected only to the Arduino he can get the car to move and when the car is connected only to the RC receiver he can get the car to move but with the Arduino connected to the RC receiver and then on to the car he cannot make it work. However, we do not know how things are connected, what power source(s) are being used, what the program consists of or what the objective is of using the Arduino so everything is speculation.

I think that I will wait until we hear from the OP what he/she wants to do and how before commenting again as there are too many unknowns at the moment.

Both the RC and the Arduino are being powered by the same 5v output and ground from the Sabertooth motor controller.

Rattled_Cage:
maybe this complicates the post but !
Read about the dip switches of the sabertooth (scroll down to dip switch settings)

if the microcomputers controlling the board it must be set to Rc Microcomputer dip settings
if the rc radios out puts are being plugged straight in SET to Rc Mode etc

sounds like you want to be able to use both rc and microcomputer

Default program 1: Serial Autopilot with R/C takeover
Default program 1 would be used with both a microcontroller and an R/C transmitter. Often, you want a
robot to run autonomously, except for having the option of manual control for parking, maneuvering in
tight spaces, or if the autopilot malfunctions.
S1 is set up as a serial receiver and is connected to an Arduino or similar.
S2 is set up as an R/C input with fixed calibration.

This is correct, if I didn't have to deal with dip switches I would just separately power them. I would rather just use the Arduino as a middle man for the RC. Thats exactly what I am trying to produce with a program and I don't have much so far.

As of right now I am going through every RC program I can find with similar attributes and trying to see if I can get any movement.

All I need to be able to do is get whatever the input is from the RC and output it as analog
(0-2.5v sends it backwards 2.5-5v sends it forward)

Battery -> Powers MotorController (Not 5v)
MotorController 5v output (constant) -> Arduino + RC

S1 controls back wheels (drive)
S2 controls front wheels (steering)

All I need to be able to do is get whatever the input is from the RC and output it as analog

What have you tried ? Please, please post your code so that we can offer help.

Do you need to output a voltage between 0 and 5V or will a PWM signal suffice ?

UKHeliBob:
What have you tried ? Please, please post your code so that we can offer help.

Do you need to output a voltage between 0 and 5V or will a PWM signal suffice ?

// MultiChannels
//
// rcarduino.blogspot.com
//
// A simple approach for reading three RC Channels using pin change interrupts
//
// See related posts - 
// http://rcarduino.blogspot.co.uk/2012/01/how-to-read-rc-receiver-with.html
// http://rcarduino.blogspot.co.uk/2012/03/need-more-interrupts-to-read-more.html
// http://rcarduino.blogspot.co.uk/2012/01/can-i-control-more-than-x-servos-with.html
//
// rcarduino.blogspot.com
//

// include the pinchangeint library - see the links in the related topics section above for details
#include <PinChangeInt.h>

#include <Servo.h>

// Assign your channel in pins
#define THROTTLE_IN_PIN 8
#define STEERING_IN_PIN 9
#define AUX_IN_PIN 10

// Assign your channel out pins
#define THROTTLE_OUT_PIN 5
#define STEERING_OUT_PIN 6
#define AUX_OUT_PIN 7

// Servo objects generate the signals expected by Electronic Speed Controllers and Servos
// We will use the objects to output the signals we read in
// this example code provides a straight pass through of the signal with no custom processing
Servo servoThrottle;
Servo servoSteering;
Servo servoAux;

// These bit flags are set in bUpdateFlagsShared to indicate which
// channels have new signals
#define THROTTLE_FLAG 1
#define STEERING_FLAG 2
#define AUX_FLAG 4

// holds the update flags defined above
volatile uint8_t bUpdateFlagsShared;

// shared variables are updated by the ISR and read by loop.
// In loop we immediatley take local copies so that the ISR can keep ownership of the 
// shared ones. To access these in loop
// we first turn interrupts off with noInterrupts
// we take a copy to use in loop and the turn interrupts back on
// as quickly as possible, this ensures that we are always able to receive new signals
volatile uint16_t unThrottleInShared;
volatile uint16_t unSteeringInShared;
volatile uint16_t unAuxInShared;

// These are used to record the rising edge of a pulse in the calcInput functions
// They do not need to be volatile as they are only used in the ISR. If we wanted
// to refer to these in loop and the ISR then they would need to be declared volatile
uint32_t ulThrottleStart;
uint32_t ulSteeringStart;
uint32_t ulAuxStart;

void setup()
{
 Serial.begin(9600);
 
 Serial.println("multiChannels");

 // attach servo objects, these will generate the correct 
 // pulses for driving Electronic speed controllers, servos or other devices
 // designed to interface directly with RC Receivers  
 servoThrottle.attach(THROTTLE_OUT_PIN);
 servoSteering.attach(STEERING_OUT_PIN);
 servoAux.attach(AUX_OUT_PIN);

 // using the PinChangeInt library, attach the interrupts
 // used to read the channels
 PCintPort::attachInterrupt(THROTTLE_IN_PIN, calcThrottle,CHANGE); 
 PCintPort::attachInterrupt(STEERING_IN_PIN, calcSteering,CHANGE); 
 PCintPort::attachInterrupt(AUX_IN_PIN, calcAux,CHANGE); 
}

void loop()
{
 // create local variables to hold a local copies of the channel inputs
 // these are declared static so that thier values will be retained 
 // between calls to loop.
 static uint16_t unThrottleIn;
 static uint16_t unSteeringIn;
 static uint16_t unAuxIn;
 // local copy of update flags
 static uint8_t bUpdateFlags;

 // check shared update flags to see if any channels have a new signal
 if(bUpdateFlagsShared)
 {
   noInterrupts(); // turn interrupts off quickly while we take local copies of the shared variables

   // take a local copy of which channels were updated in case we need to use this in the rest of loop
   bUpdateFlags = bUpdateFlagsShared;
   
   // in the current code, the shared values are always populated
   // so we could copy them without testing the flags
   // however in the future this could change, so lets
   // only copy when the flags tell us we can.
   
   if(bUpdateFlags & THROTTLE_FLAG)
   {
     unThrottleIn = unThrottleInShared;
   }
   
   if(bUpdateFlags & STEERING_FLAG)
   {
     unSteeringIn = unSteeringInShared;
   }
   
   if(bUpdateFlags & AUX_FLAG)
   {
     unAuxIn = unAuxInShared;
   }
    
   // clear shared copy of updated flags as we have already taken the updates
   // we still have a local copy if we need to use it in bUpdateFlags
   bUpdateFlagsShared = 0;
   
   interrupts(); // we have local copies of the inputs, so now we can turn interrupts back on
   // as soon as interrupts are back on, we can no longer use the shared copies, the interrupt
   // service routines own these and could update them at any time. During the update, the 
   // shared copies may contain junk. Luckily we have our local copies to work with :-)
 }
 
 // do any processing from here onwards
 // only use the local values unAuxIn, unThrottleIn and unSteeringIn, the shared
 // variables unAuxInShared, unThrottleInShared, unSteeringInShared are always owned by 
 // the interrupt routines and should not be used in loop
 
 // the following code provides simple pass through 
 // this is a good initial test, the Arduino will pass through
 // receiver input as if the Arduino is not there.
 // This should be used to confirm the circuit and power
 // before attempting any custom processing in a project.
 
 // we are checking to see if the channel value has changed, this is indicated  
 // by the flags. For the simple pass through we don't really need this check,
 // but for a more complex project where a new signal requires significant processing
 // this allows us to only calculate new values when we have new inputs, rather than
 // on every cycle.
 if(bUpdateFlags & THROTTLE_FLAG)
 {
   if(servoThrottle.readMicroseconds() != unThrottleIn)
   {
     servoThrottle.writeMicroseconds(unThrottleIn);
   }
 }
 
 if(bUpdateFlags & STEERING_FLAG)
 {
   if(servoSteering.readMicroseconds() != unSteeringIn)
   {
     servoSteering.writeMicroseconds(unSteeringIn);
   }
 }
 
 if(bUpdateFlags & AUX_FLAG)
 {
   if(servoAux.readMicroseconds() != unAuxIn)
   {
     servoAux.writeMicroseconds(unAuxIn);
   }
 }
 
 bUpdateFlags = 0;
}


// simple interrupt service routine
void calcThrottle()
{
 // if the pin is high, its a rising edge of the signal pulse, so lets record its value
 if(digitalRead(THROTTLE_IN_PIN) == HIGH)
 { 
   ulThrottleStart = micros();
 }
 else
 {
   // else it must be a falling edge, so lets get the time and subtract the time of the rising edge
   // this gives use the time between the rising and falling edges i.e. the pulse duration.
   unThrottleInShared = (uint16_t)(micros() - ulThrottleStart);
   // use set the throttle flag to indicate that a new throttle signal has been received
   bUpdateFlagsShared |= THROTTLE_FLAG;
 }
}

void calcSteering()
{
 if(digitalRead(STEERING_IN_PIN) == HIGH)
 { 
   ulSteeringStart = micros();
 }
 else
 {
   unSteeringInShared = (uint16_t)(micros() - ulSteeringStart);
   bUpdateFlagsShared |= STEERING_FLAG;
 }
}

void calcAux()
{
 if(digitalRead(AUX_IN_PIN) == HIGH)
 { 
   ulAuxStart = micros();
 }
 else
 {
   unAuxInShared = (uint16_t)(micros() - ulAuxStart);
   bUpdateFlagsShared |= AUX_FLAG;
 }
}

Its going to need to be between 0 and 5v because thats the input requirement for the motor controller to run
And I’ve been able to run with the provided code Rattled_Cage, just trying to add in the RC connections now.

Here is what I am looking to do ultimately!

I would like to use the Remote Control Receiver to drive the system through the Arduino Board which seems like there are a ton of programs out there I just feel a bit stuck right now.

Next I would like to use the Remote Controller signal as an “Emergency E-stop”
Where when the remote is turned off but system is powered up the “Arduino Program Starts”
When the Remote control power is turned on I would like it to shut down the Arduino Program and let the manual remote control take over by the operator.
Can anyone help me with this program code?

I would like to use the Remote Control Receiver to drive the system through the Arduino Board which seems like there are a ton of programs out there I just feel a bit stuck right now.

If you can't find one, then the "ton of programs" might be fantasy thinking. I think generally speaking the RC receiver outputs servo control pulses. How do you plan to modify/use these pulses? You might use an RC switch to control power on/off to part of your circuit. You might use a small RC controlled servo to operate a switch in your system to switch between parts of your control system.

If I interpret your requirements correctly then there will be two states that the system could be in

State 1 - no RC signal being received and the vehicle behaving autonomously under the control of the Arduino
State 2 - an RC signal being received and the vehicle under the control of the RC receiver

If that is the case then the program sounds simple in its operation.

First write the code that controls the vehicle to run autonomously. You have not said what you want it to do but there are "a ton of programs out there". You can test this with no RC

Second write the code that takes the RC inputs and passes them through unchanged to the servo outputs. You can test this alone with no autonomous control code.

Thirdly write the code that detects whether RC input is present. If it is then run the code from step two but if it is not then run the code from step one.

Which part are you stuck on ?