连接 Arduino 传感器 MPU6050 和处理的问题

Issues interfacing Arduino sensor MPU6050 and Processing

我有一个 MPU6050 陀螺仪和加速度计通过 I2C 协议连接到 Arduino。这些传感器使用这些指令将连续的数据流发送到串行端口(在 arduino IDE 中):

Serial.print(euler[0] * 180/M_PI);
Serial.print(":");
Serial.print(euler[1] * 180/M_PI);
Serial.print(":");
Serial.println(euler[2] * 180/M_PI);

这来自传感器库中包含的示例草图,它只是将偏航/俯仰/滚动的值发送到串行端口,以冒号分隔。

现在是有趣的部分。我一直对可视化数据很着迷,所以我想构建一种来自 Processing 中串行数据的图表(这是一个更大的项目的一部分,其中包括超声波传感器,比如一种雷达)。

所以我写了一个关于处理的简短草图来捕获数据以便分析和可视化它。这是草图:

import processing.serial.*;

Serial myPort;

String data; //Angle values

String[] splitted; //Array containing splitted data

float yaw, pitch , roll;



void setup()
{
  myPort = new Serial (this, Serial.list()[0], 115200);

}

void draw()
{

  while (myPort.available() > 0) //data arrived fromm serial
  {

    data = myPort.readStringUntil('\n');

    //Data Parsing
    splitted = data.split(":");

    yaw = float(splitted[0]);
    pitch = float(splitted[1]);
    roll = float(splitted[2]);

    println(yaw + "  " + pitch + "  " + roll);


  }



}

此代码无效。有 2 个错误交替出现。其中之一是:

ArrayIndexOutOfBondsException

另一个:

NullPointerException

指向 "splitted" 数组。

我想我遇到了问题。在之前版本的 Processing sketch 中,我使用的是:

readString() function

我认为,由于数据是一次一个地发送到 Arduino sketch 中的串行端口,因此处理 sketch 有时只捕获一个或两个偏航、俯仰、滚动值,导致数组索引当没有值添加到数组时崩溃或 nullPointerexception。然后我将 '''readString''' 更改为 '''readStringUntil('\n')''',因为,也许第一个数据包会丢失,但接下来的另一个数据包将始终被 cathed without打破它们(我抓住了整条线)。但是还是出现了同样的错误,所以我觉得我的小经验已经帮不了解决问题了。我需要你的帮助。

请原谅我的英语不好,感谢您的帮助。

你走在正确的轨道上。这里有一些提示:

  • 您可以使用 try/catch 块,这样草图不会简单地因错误而崩溃
  • 您可以使用自动调用的 bufferUntil() to tell the serial library to buffer bytes for you until a new line is encountered: it works well in tandem with serialEvent()(因此您不需要使用会阻塞 rendering/the 草图其余部分的 while 循环)
  • 您可以检查(并且应该)任何可能出现数据错误的地方(空字符串、空字符串、字符串中没有足够的值等)

这是草图的修改版本:

import processing.serial.*;

Serial myPort;

float yaw, pitch , roll;

void setup()
{

  String[] portNames = Serial.list();
  // skipp serial setup if there are no ports
  if(portNames.length == 0){
    println("no serial ports found");
    return;
  }

  // try to open serial port, handle error
  try
  {
    myPort = new Serial (this, portNames[0], 115200);
    // buffer bytes(characters) until new line is hit
    myPort.bufferUntil('\n');
  }
  catch(Exception e)
  {
    println("error opening port: " + portNames[0]);
    println("double check the port is present and not used by other applications (e.g. SerialMonitor)");
    e.printStackTrace();
  }

}

void draw()
{

  background(0);
  text(String.format("yaw: %.2f \npitch: %.2f \nroll: %.2f", yaw, pitch, roll), 5, 15);
}

// serialEvent gets called when there's new data: no need an explicit blocking while loop
void serialEvent(Serial port){
  try
  {
    // read string from serial  
    String rawSerialString = port.readString();
    // exit on null string
    if(rawSerialString == null)
    {
      println("received null string, skipping this serial message");
      return;
    }
    // exit on empty string
    if(rawSerialString.length() == 0)
    {
      println("received empty string, skipping this serial message");
      return;
    }

    // trim white space (\r, \n, etc.)
    rawSerialString = rawSerialString.trim();
    // split and convert to float
    float[] rotations = float(rawSerialString.split(":"));

    // exit if message got jumbled up and values are missing
    if(rotations.length < 3)
    {
      println("received less than 3 values, skipping this serial message");
      return;
    }

    // finally extract values
    yaw   = rotations[0];
    pitch = rotations[1];
    roll  = rotations[2];

    println(yaw + "  " + pitch + "  " + roll);

  }
  catch(Exception e)
  {
    println("error reading/parsing serial data");
    e.printStackTrace();
  }

}

显然您收到的行少于两个冒号。

从这里很难判断您接下来应该做什么,但无论如何检查拆分数组的长度是第一步。通过 if 或作为 Exception.