【问题标题】:Issues With Serial Communication Between Arduino and ProcessingArduino和处理之间的串行通信问题
【发布时间】:2016-01-18 18:19:43
【问题描述】:

我正在尝试在 Ardunio 上的传感器(实际上是基于 AtMega328PU 的克隆建立在面包板上,但我不相信这是我的问题的根源)和处理脚本之间创建数据交换,我得到了一些意想不到的结果。我遵循详细的串行通信方法here,但我遇到了似乎没有实际通过串行连接传输的数据。

Arduino 代码:

int buttonPin = 9, photodiodePin = A0;
char dataToSend;

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, OUTPUT);
  pinMode(photodiodePin, INPUT);
}

void loop() {  
  if (Serial.available() > 0)
  {
    dataToSend = Serial.read();    

    if (dataToSend == 'B')
    {
      Serial.println(digitalRead(buttonPin));
    }
    else if (dataToSend == 'L')
    {
      Serial.println(analogRead(photodiodePin));
    }
  }
}

以及处理代码的相关部分:

import processing.serial.*;

Serial myPort;

void setup()
{
 size(1600,900);

 String portName = Serial.list()[1];
 myPort = new Serial(this, portName, 9600);
}

void draw()
{
  if(getButtonData() == 1)
  {
    //Do Stuff
  }
}

int getLightData()
{
  myPort.write('L');
  println("L");
  while(!(myPort.available() > 0)){
  }
  int lightValue = int(myPort.readStringUntil('\n'));
  return lightValue;
}

int getButtonData()
{
  myPort.write('B');
  println("B");
  while(!(myPort.available() > 0)){
    println("stuck in here");
    delay(500);
  }
  int buttonValue = int(myPort.readStringUntil('\n'));
  return buttonValue;
}

在处理中我得到一个输出:

B
stuck in here
stuck in here
stuck in here
stuck in here
...

注意:我知道我从列表中选择了正确的端口,所以这不是问题。

我已尝试调试问题并在互联网上搜索类似问题,但均无济于事。非常感谢您对此问题的任何帮助,谢谢!

【问题讨论】:

  • 您不需要将“.available”检查放在一段时间内(在 getButtonData 中),因为在程序停止之前循环调用 draw 方法。你需要摆脱!在可用的情况下检查并仅在数据可用时才执行操作。相应地调整 B 的发送。对 getLightData 执行相同操作。
  • 首先测试串行通讯,不要使用其余代码。在 Draw 方法中写入您的串行端口,看看您是否可以在 Arduino 端获得任何东西。另请阅读有关如何在处理中设置串行的一些文档。确保波特率、停止位和其他设置,特别是流量控制。
  • 还要确保处理实际上只是将 B 作为一个字节发送,而不是以可能需要多字节的另一种形式发送。

标签: arduino processing


【解决方案1】:

我会首先检查是否简单地从 Arduino 向 Processing 发送一条简单的消息。在 Arduino 中尝试这样的事情:

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println("test");
  delay(1000);
}

这个在处理中:

import processing.serial.*;


Serial arduino;
void setup(){
  String portName = Serial.list()[1];
  try{
    arduino = new Serial(this, portName, 9600);
    arduino.bufferUntil('\n');
  }catch(Exception e){
    System.err.println("Error initializing Serial port!\nPlease check connections and port settings");
    e.printStackTrace();
  }
}
void draw(){

}
void serialEvent(Serial s){
  println("received arduino message: " + s.readString());
}

如果这个简单的设置有效,您应该可以继续下一步并进行双向通信。如果上述方法不起作用,那么还有其他原因导致串行通信出现问题(在这种情况下,请报告您收到的错误,如果有的话或您遇到的行为)

如果上述方法可行,您可以尝试两种方式的通信。注意我正在使用serialEvent()bufferUntil。最好尽可能避免阻塞 while 循环。

Arduino 代码:

int buttonPin = 9, photodiodePin = A0;
char dataToSend;

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, OUTPUT);
  pinMode(photodiodePin, INPUT);
}

void loop() {  

}
void serialEvent(){
  if(Serial.available() > 0){
    char cmd = Serial.read();
    if(cmd == 'B'){
      Serial.println(digitalRead(buttonPin));
    }
    if(cmd == 'L'){
      Serial.println(analogRead(photodiodePin));
    }
  }
}

处理代码:

import processing.serial.*;


Serial arduino;

int digitalValue;
int analogValue;

int lastCMD;

void setup(){
  size(200,100);
  String portName = Serial.list()[1];
  try{
    arduino = new Serial(this, portName, 9600);
    arduino.bufferUntil('\n');
  }catch(Exception e){
    System.err.println("Error initializing Serial port!\nPlease check connections and port settings");
    e.printStackTrace();
  }
}
void draw(){
  background(0);
  text("Press 'B' to read digital pin\nPress 'L' to read analog pin\n\n"+
       "digital pin: " + digitalValue + "\nanalog pin: " + analogValue,10,25);
}
void keyReleased(){
  if(key == 'B' || key == 'L'){
    lastCMD = key;
    println("sending command" + lastCMD);

    if(arduino != null){
      arduino.write(lastCMD);
    }else println("Arduino is not initializing, not writing to serial port");
  } 
}
void serialEvent(Serial s){
  String rawString = s.readString();
  println("received arduino message" + rawString);
  try{
    rawString = rawString.trim();//remove any white space characters (if present)
    if(lastCMD == 'B') digitalValue = int(rawString);
    if(lastCMD == 'L') analogValue  = int(rawString);
  }catch(Exception e){
    println("Error parsing String from serial port:");
    e.printStackTrace();
  }

}

【讨论】:

  • 非常感谢!当我有时间时,我一定会尝试这种结构。不过我很好奇,为什么阻塞 while 循环不起作用?它是否检查太多次太快并丢失数据或其他什么?
  • 你可以让 while 循环工作,但我对 while 循环的问题是它们会阻塞其他所有内容,直到它们完成。它不是很灵活。处理中的delay() 也有点碰运气,因为它在某些版本中被删除然后又被带回来。即使在 Arduino 中,delay() 最初也很容易开始使用,但后来,我做了一个基于 millis() 的条件,允许其余代码运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
相关资源
最近更新 更多