【发布时间】:2019-08-13 00:02:38
【问题描述】:
总结
我有一个 MATLAB 脚本,它使用一对遥测无线电向 Python 脚本发送串行消息。 MATLAB 数据都是单数(32 位浮点数,IEEE Standard 754)。然而,当 Python 接收到串行消息时,它会将每个数字解释为单个字节而不是 4。
背景
我正在运行 Windows 10、MATLAB R2018a、Python 3.7 并使用一对 Holybro Telemetry Radios 进行通信。这些无线电对于两个 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 端,它把消息的每个元素都塞进了一个字节(p 是 112,x03 是 3 等等)。
使用whois dataToSend 确认它是一个 1x5 的单数数组,由 20 个字节组成(或者至少在接收之前是这样)。
问题
知道为什么会发生这种情况以及如何让 python 将 MATLAB 单曲识别为 32 位/4 字节吗?
更新
事实证明,即使 MATLAB 也无法正确解释其单曲;我已经意识到 MATLAB 接收器脚本等待我调用 MATLAB 发送器 4 次,因为它只将每个单个解释为字节(意味着消息大小只有 5 个字节而不是 20 个)。此外,当消息中的某个元素更改为小数(例如 5.7)时,在输出时,它会四舍五入为 6。
【问题讨论】:
标签: python matlab serial-port