python - 从串行连接获取 b'\x0 8'b'\x9e'b'\x1d' 或 b'\xe 0'b'\xe 0'b' 错误

标签 python serial-port putty

我有一个 USB 连接到 device发出串行信息。 当我运行下面的 Python 脚本(在 Jupyter Notebook 中)时,我从中得到了奇怪的信息。

import serial

ser = serial.Serial(port='COM3', baudrate=115200, bytesize=serial.EIGHTBITS, 
    parity=serial.PARITY_NONE, timeout=1)
ser.flushInput()

while True:
    print(ser.read())

当我将波特率设置为 115200 时,我得到以下信息: b'\xe0'b'\xe0'b'\x00'b'\x00'b'\xe0'b'\x00'b'\x00'b'\xe0' ...

在 9200 我得到这个: b'\x08'b'\x9e'b'\x1d'b'\xca'b'L'b'k'b'\x84'b'\xff'b'\x90'b'\x8c'b' G'b'\x9b'

有谁知道如何获取真实数据吗? 我应该获得有关太阳能充电 Controller 的信息,例如

V:12

答:1

等等

编辑: 我现在有以下内容,但没有提供任何打印: 第一个单元格:

import os, serial, argparse

class vedirect:

    def __init__(self, serialport, timeout):
        self.serialport = serialport
        self.ser = serial.Serial(serialport, 19200, timeout=timeout)
        self.header1 = '\r'
        self.header2 = '\n'
        self.hexmarker = ':'
        self.delimiter = '\t'
        self.key = ''
        self.value = ''
        self.bytes_sum = 0;
        self.state = self.WAIT_HEADER
        self.dict = {}


    (HEX, WAIT_HEADER, IN_KEY, IN_VALUE, IN_CHECKSUM) = range(5)

    def input(self, byte):
        if byte == self.hexmarker and self.state != self.IN_CHECKSUM:
            self.state = self.HEX


        if self.state == self.WAIT_HEADER:
            self.bytes_sum += ord(byte)
            if byte == self.header1:
                self.state = self.WAIT_HEADER
            elif byte == self.header2:
                self.state = self.IN_KEY

            return None
        elif self.state == self.IN_KEY:
            self.bytes_sum += ord(byte)
            if byte == self.delimiter:
                if (self.key == 'Checksum'):
                    self.state = self.IN_CHECKSUM
                else:
                    self.state = self.IN_VALUE
            else:
                self.key += byte
            return None
        elif self.state == self.IN_VALUE:
            self.bytes_sum += ord(byte)
            if byte == self.header1:
                self.state = self.WAIT_HEADER
                self.dict[self.key] = self.value;
                self.key = '';
                self.value = '';
            else:
                self.value += byte
            return None
        elif self.state == self.IN_CHECKSUM:
            self.bytes_sum += ord(byte)
            self.key = ''
            self.value = ''
            self.state = self.WAIT_HEADER
            if (self.bytes_sum % 256 == 0):
                self.bytes_sum = 0
                return self.dict
            else:
                print ('Malformed packet')
                self.bytes_sum = 0
        elif self.state == self.HEX:
            self.bytes_sum = 0
            if byte == self.header2:
                self.state = self.WAIT_HEADER
        else:
            raise AssertionError()

    def read_data(self):
        while True:
            byte = self.ser.read(1)
            packet = self.input(byte)

    def read_data_single(self):
        while True:
            byte = self.ser.read(1)
            packet = self.input(byte)
            if (packet != None):
                return packet


    def read_data_callback(self, callbackFunction):
        while True:
            byte = self.ser.read(1)
            if byte:
                packet = self.input(byte)
                if (packet != None):
                    callbackFunction(packet)
            else:
                break


def print_data_callback(data):
    print (data)


#print(ve.read_data_single())

第二:

ve = vedirect("COM3", 1)

第三个仍然永远运行[*]:

print(ve.read_data_single())

同时我得到了 this

当我发送消息[0]时,我得到\t,但其中没有更多值

最佳答案

如果您尝试使用 VE-Direct 协议(protocol),根据 manual :

On power up, a VE.Direct interface will always be in Text-mode, and continuously transmits all runtime fields. As soon as it receives a valid HEX-message, it will switch to HEX-mode. It will stay in HEXmode as long as HEX-messages are frequently received. After a product has not received any valid HEX-messages for several seconds, it will switch back to Text-mode and start to auto transmit the run-time fields periodically again. Some products will send Asynchronous HEX-messages, starting with “:A” and ending with a newline ‘\n’, on their own. These messages can interrupt a regular Text-mode frame.

您的问题似乎是您没有正确设置波特率,默认情况下为19200

如果您想在十六进制模式下工作,您可以使用 Python 3.x 来实现,只需解码十六进制消息即可:

received_hex=ser.read()
received_utf=received_hex.decode()
print(received_utf)

您可以在其他问题中找到有关此特定问题的一些很好的指导。看看this ,作为一个例子。

您可能需要检查手册第 4 页和设备的固件版本,看看是否支持 VE-Direct 协议(protocol)

如果您不确定设置(波特率停止位等),那么使用 putty(您似乎已经在使用)等终端程序开始连接设备可能更有意义。如果你使用的是 Windows,我认为 RealTerm更易于使用,您可以轻松地从 HEX 切换到 ASCII。

编辑:事实证明,针对这个特定协议(protocol)做了很多有用的事情。 This script看起来很有前途。

如果您想运行此脚本,请打开 DOS 终端(确保您的 Python 文件夹 C:\Python3.x\bin 在您的路径中,移动到存储脚本的文件夹( C:\Example) 并输入:

C:\Example\python vedirect.py --port COM3

查看下面的评论,您的脚本似乎已经可以运行,但仍需要一些工作才能使其可用。现在,如果您稍微更改一下循环,您就可以看到设备的输出:

message=""
while True:
    message += ser.read()
    print(message)

输出显然相当难看,但是通过一些工作,您可以使其看起来像上面的脚本。手册上还有一些关于如何读取这些设备数据的很好的指导。看一下,看看是否可以将其组合在一起。现在,根据您的需要,您可能更喜欢使用自己的脚本或从另一个脚本开始。如果您正在学习,请在查看解决方案之前尝试自己动手,如果您需要尽快找到解决方案,那么我认为 github 脚本是您应该去的地方。

关于python - 从串行连接获取 b'\x0 8'b'\x9e'b'\x1d' 或 b'\xe 0'b'\xe 0'b' 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56750155/

相关文章:

c - 使用初始数据读取串口会导致很多零

debugging - 需要一个好的串口日志工具

ssh - 无法使用 ssh 模式登录 putty,引发 fatal error

python - __name__ 的目的是什么?

python - Azure 服务总线 - Python 客户端消息的 AutoRenewTimeout

python - 将 abc.abstractmethod 与其他装饰器相结合

python - 计算 shell 脚本中矩阵中沿行和列而非对角线连接的非零数的数量

php - 在 Perl 中读取串口

svn - 将 PuTTY 的 svn 存储库转换为 mercurial 存储库

putty - JSch 如何与 PuTTY 私钥一起使用