Controlling Servos with Firmata and Game Control Plus

903 Views Asked by At

Good Night, My Arduino has the example program of Firmata running on it, StandardFirmata, and I made a program in Processing using Firmata and a library called Game Control Plus. My program takes the values ​​of the PS4 joystick and converts them into numbers that the Firmata passes as commands to the Arduino and everything seems to work well, however, for some reason, the left and right servo motors do not perform numbers under 90 and even sometimes they stop when executing movements. First thing I thought was that the engines were forcing or that the program was sending the wrong values, so I made a simple Arduino program for the servo and they can execute values ​​under 90, and I also did the processing print on the screen the values ​​he was passing and the values ​​are going correctly. Anyway, I will leave the code and the wiring diagram I made below. I hope someone can help me solve this mystery.

import processing.serial.*;

/**
Controlling Servos with Firmata and Game Control Plus
Be able to control servos using any compatible joystick
by Davi Colares
*/

//Import necessay libraries
import cc.arduino.*;
Arduino arduino;
import org.gamecontrolplus.gui.*;
import org.gamecontrolplus.*;
import net.java.games.input.*;

//Define some useful things for GCP
ControlIO control;
ControlDevice stick;

//Define joystick, servos variables and initial values
float c_base, c_left, c_right, c_claw;
int base = 8, 
    left = 10,
    right = 9,
    claw = 11,
    initial_base = 90,
    initial_left = 90,
    initial_right = 90,
    initial_claw = 90;

public void setup()
{
  //Define Arduino Port, in my case 2
  arduino = new Arduino(this, Arduino.list()[2], 57600);

  //Define pin servos
  arduino.pinMode(base, Arduino.SERVO);
  arduino.pinMode(left, Arduino.SERVO);
  arduino.pinMode(right, Arduino.SERVO);
  arduino.pinMode(claw, Arduino.SERVO);

  //Sets servos to initial position
  arduino.servoWrite(base, initial_base);
  arduino.servoWrite(left, initial_left);
  arduino.servoWrite(right, initial_right);
  arduino.servoWrite(claw, initial_claw);

  //Open a config screen for the control, based in Gcpconfig, example code
  surface.setTitle("PS4 com MeArm");
  control = ControlIO.getInstance(this);
  stick = control.filter(GCP.STICK).getMatchedDevice("joystick");
  if (stick == null){
    println("Nenhum dispositivo configurado");
    System.exit(-1);
  }
}

public void getUserInput(){
  c_base = map(stick.getSlider("X").getValue(), -1, 1, 0, width);
  c_left = map(stick.getSlider("Y").getValue(), -1, 1, 0, height);
  c_right = map(stick.getSlider("Z").getValue(), -1, 1, 0, width);
  c_claw = map(stick.getSlider("W").getValue(), -1, 1, 0, height);

  //The base servo is 50, so I multiply by 1.8 to match 90 degree of servo
  c_base = c_base *1.8;
  c_left = c_left *1.8;
  c_right = c_right *1.8;
  c_claw = c_claw *1.8;
}

public void draw(){
  //print in processing serial and servos
  println(int(c_base), int(c_left), int(c_right), int(c_claw));
  getUserInput();
  arduino.servoWrite(base, int(c_base));
  arduino.servoWrite(left, int(c_left));
  arduino.servoWrite(right, int(c_right));
  arduino.servoWrite(claw, int(c_claw));
  delay(5);
}

Controller config using Gcpconfig, compatible with PS4

control ps4
X   base    3   SLIDER  Eixo X  0   1.0 0.05
Y   left    3   SLIDER  Eixo Y  0   1.0 0.05
W   right   3   SLIDER  Rotação Y   0   1.0 0.05
Z   claw    3   SLIDER  Rotação X   0   1.0 0.05

Arduino and Servos Connections

Robotic Arm Finished

1

There are 1 best solutions below

5
On BEST ANSWER

The answer might be:
Timer1:
Timer1 is a 16bit timer.
In the Arduino world the Servo library uses timer1 on Arduino Uno
Pins 9 and 10: controlled by timer1
since firmata is a complex program relying on timers and interupts this might be the cause as you attach

....
  left = 10,
  right = 9,
  ....

to exact those pins.
Why is a simple test program working`? Because you do not use interupts/tmers there.
I checked in the firmata source, they call the servo.h library => so choose two different pins for your servos
More details on timers: https://www.robotshop.com/community/forum/t/arduino-101-timers-and-interrupts/13072
ServoFirmata: https://github.com/firmata/arduino/tree/master/examples/ServoFirmata
Read also the issues (open/closed) regarding servos