pwm speed control over serial - was working - but now doesnt - debug - solved

Im newish to the Arduino and certainly coding so please forgive me.

Ive been working on a walking robot (theo jansen style) driven by 2 x 18v drill motors. To control them I decided to write a VB.Net program which sends commands from my game pad over serial wirelessly (URF to XRF). I send back the received commands just so I can check its getting the instructions im sending. All of that is working fine and in fact I've had the robot working too, but after a little fiddling with the code late at night, I found that one of the motors no longer has speed control, its either on or off ?!?
I checked the mosfet swapped around the motors etc and found that all the hardware is fine. The gamepad send data also comes back as it should, so I also know that the arduino is sending and receiving what im telling it too.

So here's the code in full (disclaimer. this code is made up from bits and pieces I found on the net and a little of my own work, it probably isn't the best but it was working)

#include <avr/pgmspace.h>
#include <Servo.h> 

int IRledPin = 3;
int motor1 = 10;
int motor2 = 11;
Servo XcamServo;


#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[20];
byte index;

void setup() {
  pinMode(IRledPin, OUTPUT);
  XcamServo.attach(9);
  analogWrite(motor1, 0);
  analogWrite(motor2, 0);
  XcamServo.write(89);
  Serial.begin(9600);
}

void loop() {
  // Read all serial data available, as fast as possible
  while (Serial.available() > 0) {
    char inChar = Serial.read();

    if (inChar == SOP) {
      index = 0;
      inData[index] = '\0';
      started = true;
      ended = false;
    } 
    else if (inChar == EOP) {
      ended = true;
      break;
    } 
    else {
      if (index < 19) {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if (started && ended) {
    Serial.println(inData);
    // The end of packet marker arrived. Process the packet
    char *cmd = strtok(inData, ",");

    if (cmd) {
      char *val = strtok(NULL, ",");
      char *val2 = strtok(NULL, ",");
      if (val) {
        sendCommand(cmd, val, val2);
      }
    }

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

void sendCommand(char *command, char *value, char *value2) {
  if (strcmp(command,"Button") == 0) {
    Button(value, value2);
  }
  if (strcmp(command,"LA") == 0) {
    LA(value, value2);
  }
  if (strcmp(command,"RA") == 0) {
    RA(value, value2);
  }
}

void Button(char* value, char* value2) {
  if (strcmp(value, "A") == 0) {
    digitalWrite(IRledPin, HIGH);

  }
  if (strcmp(value, "B") == 0) {
    digitalWrite(IRledPin, LOW);

  }
  if (strcmp(value, "X") == 0) {
    digitalWrite(IRledPin, LOW);

  }
  if (strcmp(value, "Y") == 0) {
    digitalWrite(IRledPin, LOW);

  }
  if (strcmp(value, "LB") == 0) {
    digitalWrite(IRledPin, LOW);

  }
  if (strcmp(value, "RB") == 0) {
    digitalWrite(IRledPin, LOW);

  }
  if (strcmp(value, "LS") == 0) {
    digitalWrite(IRledPin, LOW);

  }
  if (strcmp(value, "RS") == 0) {
    digitalWrite(IRledPin, LOW);

  }
  if (strcmp(value, "LT") == 0) {
    digitalWrite(IRledPin, LOW);

  }
  if (strcmp(value, "RT") == 0) {
    digitalWrite(IRledPin, LOW);

  }
  if (strcmp(value, "DUP") == 0) {
    digitalWrite(IRledPin, LOW);

  }
  if (strcmp(value, "DDOWN") == 0) {
    digitalWrite(IRledPin, LOW);

  }
  if (strcmp(value, "DLEFT") == 0) {
    digitalWrite(IRledPin, LOW);

  }
  if (strcmp(value, "DRIGHT") == 0) {
    digitalWrite(IRledPin, LOW);

  }
}

void LA(char* value, char* value2) {
  int x = atoi(value);
  int y = atoi(value2);
  int Lx = map(x,0, 2000, 0, 510);
  int Ly = map(y, 1000, 2000, 0, 255);
  
if (Ly < 1){
    analogWrite(motor1, 0);
   analogWrite(motor2, 0);
  
}
 else if (Ly > 0 && Lx == 255){
    analogWrite(motor1, Ly);
   analogWrite(motor2, Ly);
  
 }
 
else if (Lx < 255){
    int brakeFlip = map(Lx, 0, 254, Ly, 0);
    int m1 = Ly - brakeFlip;
    analogWrite(motor1, m1);
    analogWrite(motor2, Ly);
  }

  else if (Lx > 255 ){
    int brake = map(Lx, 256, 510, 0, Ly);
    int m2 = Ly - brake;
    analogWrite(motor1, Ly);
    analogWrite(motor2, m2);
  }

  else {
    analogWrite(motor1, Ly);
    analogWrite(motor2, Ly);
  }
}

void RA(char* value, char* value2) {
  int xcam = atoi(value);
  int ycam = atoi(value2);
  int Rxcam = map(xcam,0, 2000, 0, 179);
  
  if (Rxcam >90 || Rxcam <88){
  XcamServo.write(Rxcam);
  delay(15);
  }
  else{ 
  XcamServo.write(89);
  delay(15);
}
}

A lot of it can be ignored I expect, there's a bit of error checking etc all that seems fine. The issue comes down to the left analog stick where a bit of explanation is probably required.

When it comes to the Analog sticks the game pad sends out <LA,0000,000> the error checking looks for the <> to know the start and the end of the packet and disposes of them. so then you have LA,0000,0000. The LA means "Left analog" and the 0000,0000 are the X and Y. The Range of those No.s is 0-2000. Using X as an example, 0 = full left on the analog stick, 1000 =Centre & 2000 is far right.
Motors 1 & 2 are driven like a tank, so when you push the analog stick full forward both motors speed up to full speed. Then if you move the stick to the left or the right the X value is used as a break on the respective side. This is done using the map value & I guessing that's where my problem is but I just don't see it. Heres the code for the Left Analog Stick by itself

//Left Analog Stick X&Y
void LA(char* value, char* value2) {

//Change input chars to string
  int x = atoi(value);
  int y = atoi(value2);

//Map X axis 
  int Lx = map(x,0, 2000, 0, 510);

//Map Y axis
  int Ly = map(y, 1000, 2000, 0, 255);

//if Y = 0, motor speed = 0
if (Ly < 1){
    analogWrite(motor1, 0);
   analogWrite(motor2, 0);
  
}
//if Y is larger than 0 and X is central, set motor speed to Ly (Y mapped from 0 - 255) 
 else if (Ly > 0 && Lx == 255){
    analogWrite(motor1, Ly);
   analogWrite(motor2, Ly);
  
 }

 //Heres the first Brake, if Lx = 0 -255 
else if (Lx < 255){
//So here the Brake is being mapped and might seem a little confusing but I needed to make sure that I didn't have more brake than forward motion(Ly)
    int brakeFlip = map(Lx, 0, 254, Ly, 0);
//m1 is the value of Ly(forward speed) - the Brake(breakflip)
    int m1 = Ly - brakeFlip;
    analogWrite(motor1, m1);
    analogWrite(motor2, Ly);
  }

//same for the opposite side brake
  else if (Lx > 255 ){
    int brake = map(Lx, 256, 510, 0, Ly);
    int m2 = Ly - brake;
    analogWrite(motor1, Ly);
    analogWrite(motor2, m2);
  }

  else {
    analogWrite(motor1, Ly);
    analogWrite(motor2, Ly);
  }
}

Its motor 1 that the problems with. It will only ever output at full (255), or off (0) even tho I can see that its receiving all its instructions. Motor 2 works fine.

Any help would be appreciated. Sorry for the long post, I wasn't sure how much detailed explanation would be needed heh.

Thanks in advance

Read this

Second paragraph.

Hey yer a beautiful person so you are. I wondered what had happened, I added a servo d'oh!

Thanks for that. Been scratching my head for a day over that. Guess I'll just have to move motor1 pin.
Year a star :slight_smile: