我正在尝试使用来自传感器的方向数据控制 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
}
}