arduino unity串行通信延迟

问题描述

我想基于mpu-6050传感器旋转对象,所以我为arduino编写了此代码

create_ast(){//src/a/utils.cpp
    extract_a_tree();
}

create_ast(){//src/b/utils.cpp
   init_graph();
   init_view();
}

#define //src/a/define.h,this one is written in c++11 standard
sql_UPDATE 301
sql_REPLACE 302

#define //src/b/define.h,this one is written in c++17 standard
sql_INSERT 998
sql_UPDATE 302

TypeA* generate_a(){//src/a/interface.h
  //do sth
}


TypeB* generate_b(){//src/b/interface.h
  //do sth B
}

和此代码统一。

#include <Wire.h>

const int mpu_addr = 0x68;
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; 

void setup() {
  initmpu6050(); //mpu-6050 센서에 대한 초기 설정 함수
  Serial.begin(115200); //Serial 통신 시작
  calibAccelGyro(); //센서 보정
  initDT(); //시간 간격에 대한 초기화 -> 현재 시각 저장
            //즉,드론이 전원이 ON 되면 그떄부터 측정 시작!
}

void loop() {
  readAccelGyro(); //가속도,자이로 센서 값 읽어드림
  //SendDataToProcessing(); //프로세싱으로 값 전달
  calcDT(); //측정 주기 시간 계산
  calcAccelYPR();

  static int cnt;
  cnt++;
  if(cnt%2 == 0)
    SendDataToProcessing(); //위에 동일한 함수는 주석처리!
  //측정 주기 시간이 짝수(2ms 단위로 하기 위해서)이면 프로세싱으로 보낸다.

}

void initmpu6050(){
  Wire.begin(); //I2C 통신 시작 아림
  Wire.beginTransmission(mpu_addr); //0x68번지 값을 가지는 mpu-6050과 I2C 통신
  Wire.write(0x6B);
  Wire.write(0); //잠자는 mpu-6050을 깨우고 있다.
  Wire.endTransmission(true); //I2C 버스 제어권에서 손 놓음
}

void readAccelGyro(){
  Wire.beginTransmission(mpu_addr); //0x68번지 값을 가지는 mpu-6050과 I2C 통신 시작
  Wire.write(0x3B); //0x3B번지에 저장
  Wire.endTransmission(false); //데이터 전송 후 재시작 메새지 전송(연결은 계속 지속)
  Wire.requestFrom(mpu_addr,14,true); //0x68 번지에 0x3B 부터 48까지 총 14바이트 저장
  AcX = Wire.read() << 8 | Wire.read();
  AcY = Wire.read() << 8 | Wire.read();
  AcZ = Wire.read() << 8 | Wire.read();
  Tmp = Wire.read() << 8 | Wire.read();
  GyX = Wire.read() << 8 | Wire.read();
  GyY = Wire.read() << 8 | Wire.read();
  GyZ = Wire.read() << 8 | Wire.read();
}

float dt;
float accel_angle_x,accel_angle_y,accel_angle_z;
float gyro_angle_x,gyro_angle_y,gyro_angle_z;
float filtered_angle_x,filtered_angle_y,filtered_angle_z;
float baseAcX,baseAcY,baseAcZ;  //가속도 평균값 저장 변수
float baseGyX,baseGyY,baseGyZ;  //자이로 평균값 저장 변수

void SendDataToProcessing(){
  Serial.print(accel_angle_x,2);
  Serial.print(F(","));
  Serial.print(accel_angle_y,"));
  Serial.print(accel_angle_z,2);
  Serial.println(F(""));
}

void calibAccelGyro(){
  float sumAcX = 0,sumAcY = 0,sumAcZ = 0;
  float sumGyX = 0,sumGyY = 0,sumGyZ = 0;

  readAccelGyro(); //가속도 자이로 센서 읽어들임

  //평균값 구하기
  for(int i=0; i<10; i++){
    readAccelGyro();
    sumAcX += AcX; sumAcY += AcY; sumAcZ += AcZ;
    sumGyX += GyX; sumGyY += GyY; sumGyZ += GyZ;
    delay(100);
  }
  baseAcX = sumAcX / 10; baseAcY = sumAcY / 10; baseAcZ = sumAcZ / 10;
  baseGyX = sumGyX / 10; baseGyY = sumGyY / 10; baseGyZ = sumGyZ / 10;
}

unsigned long t_Now;  //현재 측정 주기 시간
unsigned long t_prev; //이전 측정 주기 시간

void initDT(){
  t_prev = millis();
}

void calcDT(){
  t_Now = millis();
  dt = (t_Now - t_prev) / 1000.0; //millis()로 얻은 값은 밀리초 단위이니까!!!!
  t_prev = t_Now;
}

void calcAccelYPR(){
  float accel_x,accel_y,accel_z; //가속도 센서의 최종적인 보정값!!!
  float accel_xz,accel_yz;
  const float radians_TO_degrees = 180/3.14159;

  accel_x = AcX - baseAcX; // 가속도(직선) X축에 대한 현재 값 - 가속도 센서의 평균값
  accel_y = AcY - baseAcY;
  accel_z = AcZ + (16384 - baseAcZ);

  //직석 +X축이 기울어진 각도 구함
  accel_yz = sqrt(pow(accel_y,2) + pow(accel_z,2));
  accel_angle_y = atan(-accel_x / accel_yz)*radians_TO_degrees;

  accel_xz = sqrt(pow(accel_x,2));
  accel_angle_x = atan(accel_y / accel_xz)*radians_TO_degrees;

  accel_angle_z = 0;
}

它工作正常。但它有一个延迟,并且它们之间的差距不断增加。 我认为问题是Arduino的循环和unity的更新具有不同的时间范围。但是我不知道该怎么解决

解决方法

之后似乎有点失踪

     string phrase = ardu.re

,因为没有分号,并且SerialPort没有.re getter。 我相信您的猜想是正确的,arduino每秒可以轻松完成请求数千次,并且除非您读取所有结果,否则它们只会累积在SerialPorts输入缓冲区中。

除了延迟对arduino的读取外,每次读取串行缓冲区时,都应该完整读取串行缓冲区,例如使用ReadExisting()或在while循环内重复ReadLine,只要返回的字符串不是空的。

请记住,您将要面对的下一件事是,当您进行检查时,某些帧将不会完全累积在读取缓冲区中(有可能在传输的中间捕获到一个帧),所以应该进行有效性检查(在.Split之后进行简单的长度检查)来处理这种情况