Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
194 views
in Technique[技术] by (71.8m points)

python - Serial Bluetooth latency is crazy high

I am trying to control the mouse of a raspberry pi with orientation data from a sensor (I'm using this one). The sensor is hooked up to an esp32 that sends the data over serial Bluetooth. The problem is that the data seems to process about 30 seconds late on the rpi. Everything is working otherwise. I could not find a way to decrease the serial Bluetooth buffer size because pyserial's set_buffer_size command was raising an error (I think that this is because the Rpi is running Linux) (I am trying to decrease buffer size because, if I'm correct, the buffer being too big can create latency). How can I reduce the latency on this?

EDIT: I realized that I should just slow down the rate at which it sends, so I made the esp32 only send data every x milliseconds (I have it set to 100 right now) and now it works great, even though it kinda sucks to have a low update rate.

Code on 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

Code on 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
  }
}
question from:https://stackoverflow.com/questions/65861115/serial-bluetooth-latency-is-crazy-high

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...