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
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