Arduino Serial 不解析命令
Arduino Serial not parsing commands
我正在使用 Processing (java) 通过串行方式与控制两个伺服系统和一个激光器的 Arduino 进行通信。一切都独立工作,但是当我使用 Processing 打开激光时,我无法控制伺服系统,直到我关闭激光。
我尝试过的故障排除:
- 使用 Arduino Serial 或手动向 Arduino 发送命令
腻子使 Arduino 按预期工作(伺服控制是
独立于激光状态)
- 将 Arduino 置于串行桥配置中以监控什么
串行命令处理正在发送到 Arduino,它就像
预期(电机位置、激光状态)
- 我正在使用外部电源,所以我知道它不是
最大电流消耗问题。 (而且有效
- 包括处理延迟,刷新 Arduino 缓冲区。
- 使用了所有“\n”、“\r”、“\r\n”组合。
这是我的处理程序:
import processing.serial.*;
import org.gamecontrolplus.gui.*;
import org.gamecontrolplus.*;
import net.java.games.input.*;
String ard_ser = "/dev/ttyACM0";
ControlIO control;
ControlDevice stick;
float px, py;
int deg_x, deg_y;
boolean trailOn;
Serial myPort;
ArrayList<PVector> shadows = new ArrayList<PVector>();
ArrayList<PVector> trail = new ArrayList<PVector>();
public void setup() {
size(400, 400);
myPort = new Serial(this, Serial.list()[0],9600);
printArray(Serial.list());
// Initialise the ControlIO
control = ControlIO.getInstance(this);
// Find a device that matches the configuration file
stick = control.getMatchedDevice("joystick");
if (stick == null) {
println("No suitable device configured");
System.exit(-1); // End the program NOW!
}
// Setup a function to trap events for this button
stick.getButton("LASER").plug(this, "toggleLaser", ControlIO.ON_PRESS);
}
// Poll for user input called from the draw() method.
public void getUserInput() {
px = map(stick.getSlider("X").getValue(), -1, 1, 0, width);
deg_x = int(map(stick.getSlider("X").getValue(),-1,1,0,180));
py = map(stick.getSlider("Y").getValue(), -1, 1, 0, height);
deg_y = int(map(stick.getSlider("Y").getValue(),-1,1,0,180));
//stick.getButton("LASER").plug(this,"toggleLaser",ControlIO.);
}
// Event handler for the Laser button
public void toggleLaser() {
println("laser");
if (myPort.available()>0){
myPort.write("-1\n");
}
//delay(1000);
return;
}
public void draw() {
getUserInput(); // Polling
background(255, 255, 240);
// Draw shadows
fill(0, 0, 255, 32);
noStroke();
for (PVector shadow : shadows)
ellipse(shadow.x, shadow.y, shadow.z, shadow.z);
if ( trail.size() > 1) {
stroke(132, 0, 0);
for (int n = 1; n < trail.size(); n++) {
PVector v0 = trail.get(n-1);
PVector v1 = trail.get(n);
line(v0.x, v0.y, v1.x, v1.y);
v0 = v1;
}
}
// Show position
noStroke();
fill(255, 64, 64, 64);
ellipse(px, py, 20, 20);
String position = str(deg_x)+','+str(deg_y)+'\n';
if (myPort.available()>0){
//println(position);
myPort.write(position);
}
delay(10);
}
它有一点可视化来监控电机位置,基本上只是发送 "mot_x_pos,mot_y_pos \n" 和一个“-1\n”来切换激光。
示例输出串行流:
90,90\n
50,50\n
-1\n
Arduino代码解析流并控制motors/laser:
#include <Servo.h>
bool laser = true;
// true sets the value high (off for my transistor)
char val = 0;
const int laser_pin = 7;
int out1 = 9; //servo pins
int out2 = 11;
boolean newData= true;
Servo servo_x;
Servo servo_y;
int pos_x =0;
int pos_y =0;
int x_prev = 90;
int y_prev = 90;
void setup() {
Serial.begin(9600);
Serial.println("<Arduino is ready>");
servo_x.attach(out1);
servo_y.attach(out2);
pinMode(laser_pin, OUTPUT);
digitalWrite(laser_pin, laser); //turn laser off on startup
}
void loop(){
while(Serial.available()>0){
pos_x = Serial.parseInt();
pos_y = Serial.parseInt();
val = Serial.read(); // this catches the newline escape characters
if ( (pos_x<0) || (pos_y<0) ){
//toggle laser
if(laser){
laser = false;
}
else {laser = true;}
digitalWrite(laser_pin, laser);
}
else if( (val == '\n') || (val == '\r') ){
if(pos_x != x_prev){ //only write to the motors if something has changed
servo_x.write(pos_x);
x_prev = pos_x;
}
if(pos_y != y_prev){
servo_y.write(pos_y);
y_prev = pos_y;
}
}
}
}
如有任何建议,我们将不胜感激。
如果您提供了不起作用的命令序列,将会有所帮助。
您的 Arduino 代码试图读取两个 int,但您只使用激光命令发送了一个。那会失去同步(parseInt 不关心行尾,很高兴转到下一行)
尝试
- 让您的激光按钮发送“-1,-1”,这样所有行上都有两个数字
- 更好的是,为你的行创建一个 better-structured 格式:以一个说明它是伺服命令还是激光命令的字母开头,然后阅读需要的内容,然后确保找到 '\n',然后重复。
我正在使用 Processing (java) 通过串行方式与控制两个伺服系统和一个激光器的 Arduino 进行通信。一切都独立工作,但是当我使用 Processing 打开激光时,我无法控制伺服系统,直到我关闭激光。 我尝试过的故障排除:
- 使用 Arduino Serial 或手动向 Arduino 发送命令 腻子使 Arduino 按预期工作(伺服控制是 独立于激光状态)
- 将 Arduino 置于串行桥配置中以监控什么 串行命令处理正在发送到 Arduino,它就像 预期(电机位置、激光状态)
- 我正在使用外部电源,所以我知道它不是 最大电流消耗问题。 (而且有效
- 包括处理延迟,刷新 Arduino 缓冲区。
- 使用了所有“\n”、“\r”、“\r\n”组合。
这是我的处理程序:
import processing.serial.*;
import org.gamecontrolplus.gui.*;
import org.gamecontrolplus.*;
import net.java.games.input.*;
String ard_ser = "/dev/ttyACM0";
ControlIO control;
ControlDevice stick;
float px, py;
int deg_x, deg_y;
boolean trailOn;
Serial myPort;
ArrayList<PVector> shadows = new ArrayList<PVector>();
ArrayList<PVector> trail = new ArrayList<PVector>();
public void setup() {
size(400, 400);
myPort = new Serial(this, Serial.list()[0],9600);
printArray(Serial.list());
// Initialise the ControlIO
control = ControlIO.getInstance(this);
// Find a device that matches the configuration file
stick = control.getMatchedDevice("joystick");
if (stick == null) {
println("No suitable device configured");
System.exit(-1); // End the program NOW!
}
// Setup a function to trap events for this button
stick.getButton("LASER").plug(this, "toggleLaser", ControlIO.ON_PRESS);
}
// Poll for user input called from the draw() method.
public void getUserInput() {
px = map(stick.getSlider("X").getValue(), -1, 1, 0, width);
deg_x = int(map(stick.getSlider("X").getValue(),-1,1,0,180));
py = map(stick.getSlider("Y").getValue(), -1, 1, 0, height);
deg_y = int(map(stick.getSlider("Y").getValue(),-1,1,0,180));
//stick.getButton("LASER").plug(this,"toggleLaser",ControlIO.);
}
// Event handler for the Laser button
public void toggleLaser() {
println("laser");
if (myPort.available()>0){
myPort.write("-1\n");
}
//delay(1000);
return;
}
public void draw() {
getUserInput(); // Polling
background(255, 255, 240);
// Draw shadows
fill(0, 0, 255, 32);
noStroke();
for (PVector shadow : shadows)
ellipse(shadow.x, shadow.y, shadow.z, shadow.z);
if ( trail.size() > 1) {
stroke(132, 0, 0);
for (int n = 1; n < trail.size(); n++) {
PVector v0 = trail.get(n-1);
PVector v1 = trail.get(n);
line(v0.x, v0.y, v1.x, v1.y);
v0 = v1;
}
}
// Show position
noStroke();
fill(255, 64, 64, 64);
ellipse(px, py, 20, 20);
String position = str(deg_x)+','+str(deg_y)+'\n';
if (myPort.available()>0){
//println(position);
myPort.write(position);
}
delay(10);
}
它有一点可视化来监控电机位置,基本上只是发送 "mot_x_pos,mot_y_pos \n" 和一个“-1\n”来切换激光。 示例输出串行流:
90,90\n
50,50\n
-1\n
Arduino代码解析流并控制motors/laser:
#include <Servo.h>
bool laser = true;
// true sets the value high (off for my transistor)
char val = 0;
const int laser_pin = 7;
int out1 = 9; //servo pins
int out2 = 11;
boolean newData= true;
Servo servo_x;
Servo servo_y;
int pos_x =0;
int pos_y =0;
int x_prev = 90;
int y_prev = 90;
void setup() {
Serial.begin(9600);
Serial.println("<Arduino is ready>");
servo_x.attach(out1);
servo_y.attach(out2);
pinMode(laser_pin, OUTPUT);
digitalWrite(laser_pin, laser); //turn laser off on startup
}
void loop(){
while(Serial.available()>0){
pos_x = Serial.parseInt();
pos_y = Serial.parseInt();
val = Serial.read(); // this catches the newline escape characters
if ( (pos_x<0) || (pos_y<0) ){
//toggle laser
if(laser){
laser = false;
}
else {laser = true;}
digitalWrite(laser_pin, laser);
}
else if( (val == '\n') || (val == '\r') ){
if(pos_x != x_prev){ //only write to the motors if something has changed
servo_x.write(pos_x);
x_prev = pos_x;
}
if(pos_y != y_prev){
servo_y.write(pos_y);
y_prev = pos_y;
}
}
}
}
如有任何建议,我们将不胜感激。
如果您提供了不起作用的命令序列,将会有所帮助。
您的 Arduino 代码试图读取两个 int,但您只使用激光命令发送了一个。那会失去同步(parseInt 不关心行尾,很高兴转到下一行)
尝试
- 让您的激光按钮发送“-1,-1”,这样所有行上都有两个数字
- 更好的是,为你的行创建一个 better-structured 格式:以一个说明它是伺服命令还是激光命令的字母开头,然后阅读需要的内容,然后确保找到 '\n',然后重复。