如何使用Processing Game Control Plus使用PS4控制器控制多个伺服器

问题描述 投票:1回答:1

我过去三天试图用我的基本编程知识来解决这个问题,这就是我所取得的成就:使用处理程序从PS4控制器收集数据,并通过串行端口将其发送到Arduino,从而能够使用串行端口控制一个伺服器和Game Control Plus库。

好吧,那我应该不会有更多问题了?对?没有。我不知道如何传递PS4控件的其他3个类比轴,并使Arduino获得它们并将其拆分为变量以控制其他伺服器。

我将分享我的2个代码:

//Processing Code

import processing.serial.*;

import org.gamecontrolplus.gui.*;
import org.gamecontrolplus.*;
import net.java.games.input.*;

Serial myPort;

ControlIO control;
ControlDevice stick;
float px, py, pz, pw;


int[] lista;


public void setup() {
  lista = new int[4];
  String portName = Serial.list()[2]; 
  myPort = new Serial(this, portName, 9600);
  surface.setTitle("GCP Joystick example");

  control = ControlIO.getInstance(this);


  stick = control.filter(GCP.STICK).getMatchedDevice("joystick");
  if (stick == null) {
    println("No suitable device configured");
    System.exit(-1); 
  }

}


public void getUserInput() {
  px = map(stick.getSlider("X").getValue(), -1, 1, 0, width);
  py = map(stick.getSlider("Y").getValue(), -1, 1, 0, height);
  pz = map(stick.getSlider("Z").getValue(), -1, 1, 0, width);
  pw = map(stick.getSlider("W").getValue(), -1, 1, 0, height);
}

// Event handler for the SHADOW button


public void draw() {
  getUserInput(); // Polling the input device
  background(255, 255, 240);

  fill(0, 0, 255, 32);
  noStroke();
  println(int(px)); 
  myPort.write(int(px));

// I tried to pass this way, but I still don't know how make Arduino recognize and split them
/**  lista[0] = int(px); 
  lista[1] = int(py);
  lista[2] = int(pz);
  lista[3] = int(pw);

for (int i = 0; i < 4) {
  println(lista[i]); 
  myPort.write(lista[i]);
  if (myPort.readStringUntil('\n') == "k"){ 
    i += 1
}
  else{}
println("---------"); 
  */
}

现在,Arduino代码:

#include <Servo.h>

char val;
Servo servo1;
int x_pos;
int servo1_pin = 9;
int initial_position = 90;
int x_pos_pas = 50;

void setup() {
  Serial.begin(9600);
  servo1.attach(servo1_pin); 
  servo1.write (initial_position);
}

void loop() {
  if (Serial.available()) 
   { 
     val = Serial.read();
     x_pos = int(int(val) * 1.8);
   }
  if(x_pos != x_pos_pas){
    servo1.write(x_pos);    
  }
  else{}
  x_pos_pas = x_pos;
  delay(10);
}
arduino controls processing servo ps4
1个回答
0
投票

这有点使您想做的事情感到困惑,但是从我可以弄清的困惑中,有关串行通信的问题。

这是我了解通信如何使用您当前的代码以及与此相关的一些问题的方式:

1。截断

您正在编写映射到草图尺寸的px(我在任何地方都看不到,因此猜测它是默认的100x100吗?)。

如果尺寸大于255,这可能是一个问题。

即使通过处理串行write(int)也会得到一个int,在幕后它正在使用jssc.Serial.writeInt()来获取一个从0到255的值。(基本上,它只写一个字节,但在0-255范围内,其中byte type in Processing java在-127到128之间。)>

如果要发送的值大于255,则需要将其拆分为单个字节。 (请参见使用byte并使用bit shifting and AND masking将单个字节放在一起成为一个多字节整数的ARGB值拆分示例)

2。重复

OR在for循环中再次发送:px无论如何,代码都已注释,但这是需要注意的。我个人制作了新的简单测试草图来解决单个简单的问题,而不是使用大量的未使用的代码块,这些代码使代码更难以阅读/导航和最终调试。我鼓励您将较大的问题分解为多个较简单的单个问题,并一次解决一个问题。

3。数据终止

注释的代码尝试发送4个整数,但是Arduino无法知道数据以什么顺序到达。如果出了什么问题,将很难分辨顺序。

有多种方法可以做到这一点。理想情况下,您将编写一个通信协议。(并且这个主题上有很多myPort.write(lista[i]);。)

[这听起来像是一个有趣的项目,学习有关使用位/字节/字节数组的知识,并通过某种形式的数据验证(校验和/ CRC等)从头开始构建通信协议]

[如果您时间紧,只想驱动伺服器而不必过多担心通过串行可靠地发送多个(可能)大值,我建议您尝试resources

您需要将Firmata固件刷新到Arduino,然后使用Firmata处理库连接到串行端口(具有正确的波特率),并根据需要调用Firmata Processing。也请参见库的arduino.servoWrite()示例。

基于您对0到> 100之间的映射值的注释,您可以使用arduino_servo的其他任何字符> 100来改变用途,以区分数据与字符串终止符char。切记,您将失去精度:

  1. [SerialEvent example返回具有32位精度的getValue()
  2. 理论上,您可以使用0-254的相同技术(使用255作为终止符)。 0-100范围使用6位]
  3. 这里是一个粗略的示例,其中考虑了尚未在实际设备上测试过的代码:

处理中:

float

Arduino:

import processing.serial.*;

import org.gamecontrolplus.gui.*;
import org.gamecontrolplus.*;
import net.java.games.input.*;

Serial myPort;

ControlIO control;
ControlDevice stick;
float px, py, pz, pw;

// px,py,pz,pw remapped to 0-100 range
int[] lista = new int[4];
// px,py,pz as bytes + terminator character (255)
byte[] toArduino = {0,0,0,0,(byte)255};

public void setup() {
  size(100,100);
  lista = new int[4];
  String portName = Serial.list()[2]; 
  try{
    myPort = new Serial(this, portName, 9600);
  }catch(Exception e){
    println("error connecting to serial port: " + portName);
    e.printStackTrace();
  }
  surface.setTitle("GCP Joystick example");

  control = ControlIO.getInstance(this);

  try{
    stick = control.filter(GCP.STICK).getMatchedDevice("joystick");
  }catch(Exception e){
    e.printStackTrace();
  }
  if (stick == null) {
    println("No suitable device configured");
  }

}


public void getUserInput() {
  if(stick == null){
    return;
  }
  // map values
  px = map(stick.getSlider("X").getValue(), -1, 1, 0, width);
  py = map(stick.getSlider("Y").getValue(), -1, 1, 0, height);
  pz = map(stick.getSlider("Z").getValue(), -1, 1, 0, width);
  pw = map(stick.getSlider("W").getValue(), -1, 1, 0, height);
  // cast to int
  lista[0] = (int)px;
  lista[1] = (int)py;
  lista[2] = (int)pz;
  lista[3] = (int)pw;
  // update bytearray
  toArduino[0] = (byte)lista[0];
  toArduino[1] = (byte)lista[1];
  toArduino[2] = (byte)lista[2];
  toArduino[3] = (byte)lista[3];
}

// Event handler for the SHADOW button


public void draw() {
  getUserInput(); // Polling the input device
  background(255, 255, 240);

  fill(0, 0, 255, 32);
  noStroke();

  text("px: " + px
    +"\npy: " + py
    +"\npz: " + pz
    +"\npw: " + pw
    ,5,15);

  if(myPort != null){
    myPort.write(toArduino);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.