串行蓝牙延迟非常高

时间:2021-01-23 15:43:24

标签: python arduino bluetooth pyserial esp32

我正在尝试使用来自传感器的方向数据控制 raspberry pi 的鼠标(我正在使用 this 一个)。传感器连接到 esp32,通过串行蓝牙发送数据。问题是数据似乎在 rpi 上处理延迟了大约 30 秒。一切正常。我找不到减小串行蓝牙缓冲区大小的方法,因为 pyserial 的 set_buffer_size 命令引发了错误(我认为这是因为 Rpi 正在运行 Linux)(我正在尝试减小缓冲区大小,因为如果我是对的,缓冲区太大会造成延迟)。如何减少延迟?

编辑:我意识到我应该放慢它的发送速度,所以我让 esp32 只每 x 毫秒发送一次数据(我现在将它设置为 100),现在它工作得很好,即使它更新率低有点糟糕。

rpi 上的代码:

import serial
import pyautogui
import struct
import time

pyautogui.FAILSAFE = False #allow cursor to go to corner of screen

ser = serial.Serial("/dev/rfcomm0")#start serial Bluetooth
ser.baudrate = 1000000

resolution = pyautogui.size()#get screen size
verticalRatio = resolution.height / resolution.width
viewAngle = 45#horizontal angle bounds of screen

move = False #toggle between x and y values
rot = [0, 0]#raw rotation
percent = [0.0, 0.0]#position as percent of screen
pos = [0, 0]#position to put cursor
while True:
    if ser.in_waiting > 0:#when there is serial data
        if not move:#x value
            rot[0] = struct.unpack('>B', ser.read())[0]-90 #decode data
            percent[0] = rot[0]/viewAngle #set as percent
            pos[0] = percent[0] * (resolution.width / 2) + (resolution.width / 2) #convert to screen point
        else:#y value and move cursor
            rot[1] = struct.unpack('>B', ser.read())[0]-90 #decode
            percent[1] = rot[1]/(viewAngle*verticalRatio) #percent
            pos[1] = percent[1] * (resolution.height / 2) + (resolution.height / 2) #to screen point
            print(str(rot) + ' ' + str(time.time())) #for debugging
            pyautogui.moveTo(pos[0], pos[1]) #move cursor
        move = not move

ESP32 上的代码:

#include <BluetoothSerial.h>

#include <Wire.h>
#include <Adafruit_BNO055.h>
#include <Adafruit_Sensor.h>
#include <utility/imumaths.h>

const int SAMPLERATE_DELAY = 10; //delay of sensor

Adafruit_BNO055 bno = Adafruit_BNO055(55);//sensor
BluetoothSerial ser;//serial port

imu::Vector<3> EulerCorrect(imu::Vector<3> vec){//prevent looping strait from 360 to 0 (allow negative angles)
  if(vec.x()>180){
    vec.x() -= 360;
  }
  if(vec.y()>180){
    vec.y() -= 360;
  }
  if(vec.z()>180){
   vec.z() -= 360;
  }
  return vec;
}

void setup(void) {
  Serial.begin(9600);
  ser.begin("Gesture Control");

  if (! bno.begin()) {
    Serial.println("Couldnt start");
    while (1) yield();
  }
  Serial.println("Connected");

  bno.setExtCrystalUse(true);
}

void loop() {
  unsigned long startTime = millis();
  prevPercent = percent;

  imu::Vector<3> rot = bno.getVector(Adafruit_BNO055::VECTOR_EULER);//get orientation
  rot = EulerCorrect(rot);

  //clamp values
  if(rot.x() > 90){
    rot.x() = 90;
  }
  if(rot.y() > 90){
        rot.y() = 90;
  }
  if(rot.x() < -90){
    rot.x() = -90;
  }
  if(rot.y() < -90){
    rot.y() = -90;
  }

  //send data
  ser.write((byte)(rot.x()+90));
  ser.write((byte)(rot.z()+90));

  Serial.print(rot.x());
  Serial.print(" ");
  Serial.println(rot.z());


  while ((millis() - startTime) < SAMPLERATE_DELAY){
    //wait for sensor
  }
}

0 个答案:

没有答案