[Solved] : Need help with arduino code: Problem interfacing servos using Xbee

Hi,

I am interfacing a USB gamepad connected to my laptop and using that to transmit commands via XBee series 1 (Xbee Series 1 USB explorer interface chip) to my robot driven by an arduino which is connected to another laptop and it receives commands wirelessly via another XBee series 1. For the transmitter code I am using the jInput java library to recognize my USB gamepad, and for transmitting the command I'm using the rxtx java library to communicate with the virtual serial port to which my XBee series 1 is connected. I have attached the java program.

On the receiver side, I have connected my arduino to another laptop and an XBee series 1 to receive the transmitted commands. I am using the SoftwareSerial library and using pins 2 and 3 as the rx/tx pins on the arduino. I use the regular Serial port of the arduino to debug my program using the serial monitor. I am able to verify that the commands are coming in correctly.

The problem I am facing is interfacing a servo that needs to be controlled via the USB gamepad. When I send in a character say 'B' by moving my right thumb joystick right, I intend to turn my servo from 0 degrees to 180 degrees, and then when I send in a character say 'D' by moving the right thumb joystick left, I intend to turn the servo from 180 degrees to 0 degrees. I have attached the arduino code as well. Here is a part of the code of what I am trying to do:

input = (char) xbee.read();    

if(input == 'B') {  //Right joystick right
        Serial.println("Inside B block");
        Serial.print("Init servo position = ");
        Serial.print(pos);
        if((pos >= MIN_SERVO) && (pos <= MAX_SERVO)){
            Serial.println("Running servo position " + pos);
            pos++;
            if(pos >= MAX_SERVO) {
              pos = MAX_SERVO; 
            }
            int mapPos1 = map(pos, 0, 180, 0, 179);
            mapPos1 = constrain(mapPos1, 0, 179);
            servo1.write(mapPos1);
            delay(5);
        }
      }
     
      if(input == 'D') {  //Right joystick left
        Serial.println("Inside D block");
        Serial.print("Init servo position = ");
        Serial.print(pos);
        if((pos <= MAX_SERVO) && (pos >= MIN_SERVO)) {
          Serial.println("Running servo position " + pos);
		  pos--;
          if(pos <= MIN_SERVO) {
             pos = MIN_SERVO; 
          }
          int mapPos2 = map(pos, 0, 180, 0, 179);
          mapPos2 = constrain(mapPos2, 0, 179);
          servo1.write(mapPos2);
          delay(5);
        }
      }

I am able to see the servo start moving very slowly from 0 degrees and its servo position keeps increasing till somewhere mid-point say 90 degrees, and then it resets back to 0 degrees and after that it does not move. Also I'm seeing a lot of delay because of which the servo does not move quickly enough when I move the thumb stick left or right. On my serial monitor I am seeing that the value of the pos keeps increasing and decreasing correctly based on my thumb stick input.

I tried google to see if anybody has some solutions. Most of the time I see people directly reading the thumb stick value using analogRead and then using the map function to interface the servo. But my case is different, where I just send the commands after the gamepad inputs are read by the jInput library.

I need help in understanding what could be wrong with the code and how to fix it. Any help would be greatly appreciated.

Thanks,
Sumair

DragonPlusSerialController.java (7.28 KB)

Test_Xbee_Servo_Control.ino (2.94 KB)

Hi,

After some debugging I was able to fix this problem on my own. Please see the solution below:

#include <SoftwareSerial.h>
#include <Servo.h>

SoftwareSerial xbee(2, 3);  //Rx, Tx

Servo myservo;  // create servo object to control a servo 
Servo gripper;
 
int pos = 0;    // variable to store the servo position 
int ledPin = 13;

char data;
 
void setup() 
{ 
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  Serial.begin(9600);
  xbee.begin(115200);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  gripper.attach(11);
} 
 
 
void loop() 
{ 
  while(xbee.available() == 0);
  
  data = xbee.read();
  
  if(data == 'B') {
     Serial.println(pos);
     pos = pos + 1;
     pos = constrain(pos, 0, 180);
     myservo.write(pos);
     delay(5);
  }
  if(data == 'D') {
     Serial.println(pos);
     pos = pos - 1;
     pos = constrain(pos, 0, 180);
     myservo.write(pos);
     delay(5);
  }
  if(data == 'K') {
     //digitalWrite(ledPin, HIGH);
     gripper.write(180);
  }
  if(data == 'L') {
     //digitalWrite(ledPin, LOW);
     gripper.write(0);     
  }
}