Differential Steering using a joystick / programming question....

Thought I'd share my code as I did not find anythig that exactly matched what I wanted.

I'm running two RC servo outputs into my arduino one on pins 12 and 13 and using 3,9, 10,11 as pwm outputs for my two H-bridges. Enable-signal on the bridges are constantly enabled. My code is a mix and match from several sources+some own adaptions. I'm sure some things can be improved, but it works as is.

Maybe I'll rewrite it to use digital control channels for direction and only two PWM outputs (pins 5-6)in the future (to be able to increase the PWM frequency).

const int chA=12;  //Fwd-rev servo input 
const int chB=13;  //Left-right servo input

//RX signal massaging values
const int RXLo=1000;
const int RXHi=2000;
const int RXDeadLo=1490;
const int RXDeadHi=1510;
const int RXCenter=1500;

const byte controllerFA = 11; //PWM FORWARD PIN for OSMC Controller A (left motor)
const byte controllerRA = 10;  //PWM REVERSE PIN for OSMC Controller A (left motor)
const byte controllerFB = 9;  //PWM FORWARD PIN for OSMC Controller B (right motor)
const byte controllerRB = 3;  //PWM REVERSE PIN for OSMC Controller B (right motor)

int analogTmp = 0; //temporary variable to store 
int throttle, direction = 0; //throttle (Y axis) and direction (X axis) 

int leftMotor,leftMotorScaled = 0; //left Motor helper variables
float leftMotorScale = 0;

int rightMotor,rightMotorScaled = 0; //right Motor helper variables
float rightMotorScale = 0;

float maxMotorScale = 0; //holds the mixed output scaling factor

int deadZone = 10; //jostick dead zone 
int ch[3];  //Array to store and display the values of each channel

void setup()  { 
 //initialization of pins  
 Serial.begin(115200);
 pinMode(controllerFA, OUTPUT);
 pinMode(controllerRA, OUTPUT);
 pinMode(controllerFB, OUTPUT);
 pinMode(controllerRB, OUTPUT);  

 pinMode(chA, INPUT);
 pinMode(chB, INPUT);
} 

void loop()  { 
  ch[0] = pulseIn (chA,HIGH);  //Read and store channel 1
  ch[1] = pulseIn (chB,HIGH);

  for (int i=0; i<=2; i++)      //Signal Conditioning loop
  {
   if (ch[i] <= RXLo)             //Trim Noise from bottom end
   {
    ch[i] = RXLo;
   }
  
   if (ch[i] <= RXDeadHi && ch[i] >= RXDeadLo)     //Create Dead-Band
   {
    ch[i] = RXCenter;
   }
  
   if (ch[i] >= RXHi)            //Trim Noise from top end
   {
     ch[i] = RXHi;
   }
   ch[i]=map(ch[i],RXLo,RXHi,-255,255);
  }

 throttle = ch[0];
 direction = ch[1];
 //mix throttle and direction
 leftMotor = throttle+direction;
 rightMotor = throttle-direction;

 //print the initial mix results
 Serial.print("LIN:"); Serial.print( leftMotor, DEC);
 Serial.print(", RIN:"); Serial.print( rightMotor, DEC);

 //calculate the scale of the results in comparision base 8 bit PWM resolution
 leftMotorScale =  leftMotor/255.0;
 leftMotorScale = abs(leftMotorScale);
 rightMotorScale =  rightMotor/255.0;
 rightMotorScale = abs(rightMotorScale);

 Serial.print("| LSCALE:"); Serial.print( leftMotorScale,2);
 Serial.print(", RSCALE:"); Serial.print( rightMotorScale,2);

 //choose the max scale value if it is above 1
 maxMotorScale = max(leftMotorScale,rightMotorScale);
 maxMotorScale = max(1,maxMotorScale);

 //and apply it to the mixed values
 leftMotorScaled = constrain(leftMotor/maxMotorScale,-255,255);
 rightMotorScaled = constrain(rightMotor/maxMotorScale,-255,255);

 Serial.print("| LOUT:"); Serial.print( leftMotorScaled);
 Serial.print(", ROUT:"); Serial.print( rightMotorScaled);

 Serial.print(" |");

 //apply the results to appropriate uC PWM outputs for the LEFT motor:
 if(abs(leftMotorScaled)>deadZone)
 {
   if (leftMotorScaled > 0)
   {
     Serial.print("F");
     Serial.print(abs(leftMotorScaled),DEC);

     analogWrite(controllerRA,0);
     analogWrite(controllerFA,abs(leftMotorScaled));            
   }
   else 
   {
     Serial.print("R");
     Serial.print(abs(leftMotorScaled),DEC);

     analogWrite(controllerFA,0);
     analogWrite(controllerRA,abs(leftMotorScaled));  
   }
 }  
 else 
 {
 Serial.print("IDLE");
 analogWrite(controllerFA,0);
 analogWrite(controllerRA,0);
 } 

 //apply the results to appropriate uC PWM outputs for the RIGHT motor:  
 if(abs(rightMotorScaled)>deadZone)
 {
   if (rightMotorScaled > 0)
   {
     Serial.print("F");
     Serial.print(abs(rightMotorScaled),DEC);

     analogWrite(controllerRB,0);
     analogWrite(controllerFB,abs(rightMotorScaled));            
   }
   else 
   {
     Serial.print("R");
     Serial.print(abs(rightMotorScaled),DEC);

     analogWrite(controllerFB,0);
     analogWrite(controllerRB,abs(rightMotorScaled));  
   }
 }  
 else 
 {
 Serial.print("IDLE");
 analogWrite(controllerFB,0);
 analogWrite(controllerRB,0);
 } 

 Serial.println("");

 //To do: throttle change limiting, to avoid radical changes of direction for large DC motors and alter PWM base frequency.

 delay(10);

}