gpt4 book ai didi

python - 使用 Python 串行读取 MATLAB 单曲

转载 作者:太空宇宙 更新时间:2023-11-04 04:05:27 24 4
gpt4 key购买 nike

总结

我有一个 MATLAB 脚本,它使用一对遥测 radio 向 Python 脚本发送串行消息。 MATLAB 数据都是单数(32 位 float ,IEEE Standard 754)。然而,当 Python 收到串行消息时,它将每个数字解释为一个字节而不是 4 个字节。

背景

我正在运行 Windows 10、MATLAB R2018a、Python 3.7 并使用一对 Holybro Telemetry Radios沟通。这些 radio 适用于两个 MATLAB 脚本之间的串行通信,这让我相信问题与 Python 如何解释 MATLAB 单一数据类型有关。

我的代码

MATLAB 发送器

这是发送消息的代码:

comport = 'COM6'
s = serial(comport);
s.BaudRate = 57600;

try
fopen(s);
headerToSend = single([112 112]);
packetToSend = single([3 4 5]);
dataToSend = [headerToSend packetToSend];
fwrite(s,dataToSend);
disp('Data sent is: ')
disp(dataToSend)
fclose(s);
delete(s);
whos dataToSend
catch ME
disp(ME.message)
end

请注意,消息可以包含转换为单数的整数或无法简化为整数的十进制数(如 0.1)。

Python 接收器

这是接收消息的代码:

import serial
import time
import sys

dat = []

# Open serial port
ser = serial.Serial(
port='COM3',
baudrate=57600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=0.1)

try:
# Main loop
while (True):
buffer = ser.read(4)
print("Buffer: ")
print(buffer)
time.sleep(1)
except KeyboardInterrupt:
ser.close()
sys.exit()

MATLAB 接收器(用于比较)

为了比较,我在 MATLAB 中复制了一个接收器以验证发送器是否正常运行:

clc;clear;
comport = 'COM3';
s = serial(comport);
s.BaudRate = 57600;
try
fopen(s);
data = [];
% Receive response data
pause(0.5);
expectedDataLength = 20; % 2 headers and 3 msg, each 4 bytes
data = fread(s,expectedDataLength)
fclose(s);
delete(s);
catch ME
disp(ME.message)
end
if isempty(data)
disp('Unable to read any data.');
else
%Logic to find the packet after stripping the header
data = data';
header = single([112 112]);

%Find the starting indices of 'header' in the 'data' received. It is
%expected to be 112 in this case
k = strfind(data,header);

if ~isempty(k) && any(ismember(k,1))
%get the packet data by stripping the header
packet = data(length(header)+1:expectedDataLength);
end

% The msg values are in the order x, y, and z.
msg1 = typecast(single(packet(1)),'single');
msg2 = typecast(single(packet(2)),'single');
msg3 = typecast(single(packet(3)),'single');

%display the msg data on screen
disp(['Message Data ', num2str(msg1),' | ', num2str(msg2), ' | ', num2str(msg3), '.'])
end

预期结果

我希望缓冲区读取:

b'x00\x00\x00\x70'
b'x00\x00\x00\x70'
b'x00\x00\x00\x03'
b'x00\x00\x00\x04'
b'x00\x00\x00\x05'

对于包含[112 112 3 4 5]的消息

使用上面显示的 MATLAB 阅读器时,它可以正确解释消息 。请参阅底部的更新。

实际结果

缓冲区改为:

b'pp\x03\x04'
b'\x05'

似乎,在 python 端,它已将消息的每个元素塞进一个字节(p112x033 等等)。使用 whois dataToSend 确认它是一个 1x5 数组,由 20 个字节组成(或者至少是,在被接收之前)。

问题

知道为什么会发生这种情况以及如何让 python 将 MATLAB 单曲识别为 32 位/4 字节吗?

更新

事实证明,即使是 MATLAB 也无法正确解释它的单曲;我已经意识到 MATLAB 接收器脚本等待我调用 MATLAB 发送器 4 次,因为它只将每个单个解释为字节(这意味着消息大小只有 5 个字节而不是 20 个字节)。此外,当消息的一个元素更改为小数(例如 5.7)时,则在输出中四舍五入为 6。

最佳答案

您的字节就在那里,只是您看不到它们。

替换你的:

print(buffer)

与:

print(ord(buffer))

而且它们应该神奇地凭空出现。

您可能想使用 struct.unpack 来获取您想要的单曲。

编辑: 如下所述,问题是您需要明确说明要用于从 Matlab 写入端口的精度。如果不这样做,它将使用默认的无符号 8 位。

这样做:

fwrite(s, dataToSend, 'single')

解决了问题。

关于python - 使用 Python 串行读取 MATLAB 单曲,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57433423/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com