使用 Firmata 和 Game Control Plus 控制舵机

Controlling Servos with Firmata and Game Control Plus

晚安, 我的 Arduino 上有 Firmata 运行 的示例程序,StandardFirmata,我使用 Firmata 和一个名为 Game Control Plus 的库在 Processing 中制作了一个程序。 我的程序采用 PS4 操纵杆的值并将它们转换为数字,Firmata 作为命令传递给 Arduino,一切似乎都运行良好,但是,由于某种原因,左右伺服电机不工作执行 90 以下的数字,甚至有时他们在执行动作时会停止。 我首先想到的是引擎强制或程序发送了错误的值,所以我为伺服做了一个简单的 Arduino 程序,它们可以执行 90 以下的值,我还在屏幕上进行了处理打印他传递的价值观和正确的价值观。 无论如何,我将在下面留下我制作的代码和接线图。希望有人能帮我解开这个谜。

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);
}

使用 Gcpconfig 的控制器配置,兼容 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

答案可能是:
计时器 1:
Timer1 是一个 16 位定时器。
在 Arduino 世界中,Servo 库在 Arduino Uno
上使用 timer1 引脚 9 和 10:由 timer1
控制 由于 firmata 是一个依赖计时器和中断的复杂程序,这可能是您附加

的原因
....
  left = 10,
  right = 9,
  ....

精确定位这些引脚。
为什么一个简单的测试程序有效?因为你不在那里使用 interupts/tmers。
我检查了 firmata 源,他们调用 servo.h 库 => 所以为你的舵机选择两个不同的引脚
有关计时器的更多详细信息:https://www.robotshop.com/community/forum/t/arduino-101-timers-and-interrupts/13072
ServoFirmata: https://github.com/firmata/arduino/tree/master/examples/ServoFirmata
另请阅读有关伺服系统的问题(open/closed)