python - 在蓝牙套接字上使用 pySerialTransfer
问题描述
当设备通过 USB 电缆连接时,我有工作代码使用 pySerialTransfer 从 Raspberry Pi 向 Arduino 发送一个结构。但是,我想通过蓝牙而不是使用 USB 电缆来做到这一点。
独立地,使用单独的 python 代码和单独的 Arduino 草图,我已经能够让 Raspberry Pi 和 Arduino 通过蓝牙通过连续的文本流或二进制数据进行通信。
我的问题是我看不到如何结合这两种方法 - 即:如果我通过蓝牙发送二进制编码结构,我看不到如何获得 pySerialTransfer / SerialTransfer 库的好处来解析它接收端。我看到了如何“手动”进行解析,寻找特殊的终止字符等,但我希望通过 pySerialTransfer 避免这种需要。
感谢您提供任何指针/建议/示例。到目前为止,我能够构建的所有工作代码都在这里。
pySerialTransfer
工作 Arduino C 串行代码
#include "SerialTransfer.h"
SerialTransfer myTransfer;
int const ONBOARD_LED_PIN = 13;
struct POSITION {
int id;
float azimuth;
float altitude;
} position;
void Blink(int n) {
for (int i=0; i<n; i++) {
digitalWrite(ONBOARD_LED_PIN, HIGH);
delay(75);
digitalWrite(ONBOARD_LED_PIN, LOW);
delay(75);
}
delay(150);
}
void setup()
{
Serial.begin(115200);
myTransfer.begin(Serial);
pinMode(ONBOARD_LED_PIN, OUTPUT);
digitalWrite(ONBOARD_LED_PIN, LOW);
}
void loop()
{
if(myTransfer.available())
{
//////////////////////////////////////////////
// handle call from Python
myTransfer.rxObj(position, sizeof(position));
//////////////////////////////////////////////
//////////////////////////////////////////////
// send response
myTransfer.txObj(position, sizeof(position));
myTransfer.sendData(sizeof(position));
//////////////////////////////////////////////
}
else if(myTransfer.status < 0)
{
Serial.print("ERROR: ");
if(myTransfer.status == -1)
Serial.println(F("CRC_ERROR"));
else if(myTransfer.status == -2)
Serial.println(F("PAYLOAD_ERROR"));
else if(myTransfer.status == -3)
Serial.println(F("STOP_BYTE_ERROR"));
}
}
工作树莓派序列号
import time
import struct
from pySerialTransfer import pySerialTransfer
def StuffObject(txfer_obj, val, format_string, object_byte_size, start_pos=0):
"""Insert an object into pySerialtxfer TX buffer starting at the specified index.
Args:
txfer_obj: txfer - Transfer class instance to communicate over serial
val: value to be inserted into TX buffer
format_string: string used with struct.pack to pack the val
object_byte_size: integer number of bytes of the object to pack
start_pos: index of the last byte of the float in the TX buffer + 1
Returns:
start_pos for next object
"""
val_bytes = struct.pack(format_string, *val)
for index in range(object_byte_size):
txfer_obj.txBuff[index + start_pos] = val_bytes[index]
return object_byte_size + start_pos
if __name__ == '__main__':
try:
link = pySerialTransfer.SerialTransfer('/dev/cu.usbmodem14201', baud=115200)
link.open()
time.sleep(2) # allow some time for the Arduino to completely reset
base = time.time()
while True:
sent = (4, 1.2, 2.5)
format_string = '<lff'
format_size = 4+4+4
StuffObject(link, sent, format_string, format_size, start_pos=0)
link.send(format_size)
start_time = time.time()
elapsed_time = 0
while not link.available() and elapsed_time < 2:
if link.status < 0:
print('ERROR: {}'.format(link.status))
else:
print('.', end='')
elapsed_time = time.time()-start_time
print()
response = bytearray(link.rxBuff[:link.bytesRead])
response = struct.unpack(format_string, response)
print('SENT: %s' % str(sent))
print('RCVD: %s' % str(response))
print(' ')
except KeyboardInterrupt:
link.close()
蓝牙通讯
工作 Arduino 蓝牙通信
#include "SerialTransfer.h"
// Connect the HC-05 TX to Arduino pin 2 RX.
// Connect the HC-05 RX to Arduino pin 3 TX through a voltage divider.
//
long n = 0;
struct POSITION {
float azimuth=5;
float altitude=10;
};
SerialTransfer myTransfer;
void setup()
{
Serial.begin(9600);
// HC-06 default serial speed for communcation mode is 9600
Serial1.begin(9600);
myTransfer.begin(Serial1);
}
void loop()
{
n++;
POSITION x;
x.azimuth=n;
x.altitude=n+1;
myTransfer.txObj(x, sizeof(x));
myTransfer.sendData(sizeof(x));
if(Serial1.available() > 0){ // Checks whether data is comming from the serial port
Serial.println(Serial1.read());} // Reads the data from the serial port
delay(1000);
}
工作python蓝牙通信
import bluetooth
sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
bd_addr = '98:D3:11:FC:42:16'
port = 1
sock.connect((bd_addr, port))
d = sock.recv(10240000)
print(d)
sock.send("hello")
解决方案
pySerialTransfer / SerialTransfer 将使用 CRC 以数据包格式排列数据,因此它是通过串行通信快速安全的方式。
实际上,没有特殊字符来终止数据包,因为二进制数据可以是从 0x00 到 0xFF 的任何字符,涵盖所有 ASCII 码。
推荐阅读
- python - Django HttpRequest 与请求
- python - 输入用户名以使用 telnetlib 远程登录设备后 Python 脚本挂起
- docker - 在 Docker 容器上安装 ant
- php - 如何使用自定义消息显示 500 错误视图?
- google-apps-script - 在现有电子表格谷歌表格中创建一个新表格
- heroku - Godaddy 域重定向到我的 Heroku 服务器,但 URL 已更改
- json - 如何通过结构重新格式化 JSON?
- powershell - 查找文件,无论其扩展名如何
- amazon-dynamodb - 如何在 node.js 中使用 dynamodb 扫描操作获取整个表数据
- csv - 将段落数据加载到 Teradata