使用python解析arduino序列中的数据

使用python解析arduino序列中的数据,python,tkinter,arduino,pyserial,Python,Tkinter,Arduino,Pyserial,我试图使用pySerial解析arduino中的数据,以便将每个值属性化为tKinter GUI应用程序使用的变量 为此,我尝试从arduino获取数据,并将每个解析的值属性化为float或complex(text+num)变量。对于这一点,我的第一个测试是对每种数据类型使用if条件,但我不知道它是否适合这种方式,我的类似代码也不起作用 #从数据序列arduino braud 9600获取值 ser=serial.serial('/dev/cu.usbmodem14201',9600,超时=3,

我试图使用pySerial解析arduino中的数据,以便将每个值属性化为tKinter GUI应用程序使用的变量

为此,我尝试从arduino获取数据,并将每个解析的值属性化为float或complex(text+num)变量。对于这一点,我的第一个测试是对每种数据类型使用if条件,但我不知道它是否适合这种方式,我的类似代码也不起作用

#从数据序列arduino braud 9600获取值
ser=serial.serial('/dev/cu.usbmodem14201',9600,超时=3,writeTimeout=0)
data=ser.read_all()
模拟值=0.0
电压=0#int
温度=0.0
EC=0.0
温度B=0.0
湿度b=0.0
PH值=0.0
提取器语句=“NULL”
lightstatement=“NULL”
intractorstatement=“NULL”
FANstatement=“NULL”
date=“NULL”#如图所示
def DataReaderThread():
尽管如此:
currentLineRead=ser.readline()
打印(currentLineRead)
currentLineReadName=reading.split(“:”,0)
currentLineReadValue=reading.split(“:”,1)
如果currentLineReadName=“b”模拟值:
analogValue=currentLineReadValue
elif currentLineReadName=“b”电压:
电压传感器=currentLineReadValue
elif currentLineReadName=“b”临时文件:
温度传感器=currentLineReadValue
elif currentLineReadName=“b”EC”:
如果currentLineReadValue=“无解决方案!\r\n\”:
ECSENSOR值=0.0
其他:
EcSensorValue=currentLineReadValue
elif currentLineReadName=“b”温度b”:
温度B=currentLineReadValue
elif currentLineReadName=“b”湿度b”:
HumidityB=currentLineReadValue
elif currentLineReadName=“b\pHvalue”:
pHvalue=currentLineReadValue
elif currentLineReadName=“b”提取器声明:
提取器状态=currentLineReadValue
elif currentLineReadName=“b”lightstatement”:
ligthStatement=currentLineReadValue
elif currentLineReadName=“b”语句:
IntroTorStatement=currentLineReadValue
else currentLineReadName=“b'FANstatement”:
fanStatement=currentLineReadValue
返回(模拟值、电压ECSENSOR、温度ECSENSOR、ECSENSOR值、温度B、湿度B、PH值、提取器状态、LIGHTH状态、内部状态、FAN状态)
这里有arduino的输出,称为“currentLineRead”(多行的视觉:

b'
b'
b'模拟值:30\r\n'
b'电压:146\r\n'
b'temp:24.25\r\n'
b'EC:没有解决方案!\r\n'
b'温度b:23.60\r\n'
b'湿度b:35.70\r\n'
b'pHvalue:14.68\r\n'
b'提取器语句:1\r\n'
b'lightstatement:0\r\n'
b'intractorstatement:0\r\n'
b'Fan声明:10:0:0 1/1/0周中的天:1\r\n'
b'
b'
b'模拟值:30\r\n'
b'电压:146\r\n'
b'temp:24.25\r\n'
b'EC:没有解决方案!\r\n'
b'温度b:23.60\r\n'
b'湿度b:35.70\r\n'
b'pHvalue:14.68\r\n'
b'提取器语句:1\r\n'
b'lightstatement:0\r\n'
b'intractorstatement:0\r\n'
b'Fan声明:10:0:0 1/1/0周中的天:1\r\n
我想将每个值赋给上面的变量集。例如:b'TemperatureB:23.60\r\n',我只想要数值。请问最好的方法是什么


谢谢!

您实际上可以使用json包和我发现的一些片段来“放松”语法,使键周围不需要“”引号(因为ArduinoJson发送具有这种标准化的字符串,以便在传输过程中节省一些字节)

将json行反序列化为python词汇对象可能是最好的方法。 它允许您:

  • 通过名称轻松获取键的值
  • 测试密钥是否存在
只要调用
.get(“key\u name”)
方法,如果字典中没有名为
“key\u name”
的键,那么默认情况下该方法将返回
None

以下是片段:

类和对象声明

import re
import json
from parsec import (
    sepBy,
    regex,
    string,
    generate,
    many
)

whitespace = regex(r'\s*', re.MULTILINE)

lexeme = lambda p: p << whitespace

lbrace = lexeme(string('{'))
rbrace = lexeme(string('}'))
lbrack = lexeme(string('['))
rbrack = lexeme(string(']'))
colon = lexeme(string(':'))
comma = lexeme(string(','))
true = lexeme(string('true')).result(True)
false = lexeme(string('false')).result(False)
null = lexeme(string('null')).result(None)
quote = string('"') | string("'")

def number():
    return lexeme(
        regex(r'-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?')
    ).parsecmap(float)


def charseq():
    def string_part():
        return regex(r'[^"\'\\]+')

    def string_esc():
        return string('\\') >> (
            string('\\')
            | string('/')
            | string('b').result('\b')
            | string('f').result('\f')
            | string('n').result('\n')
            | string('r').result('\r')
            | string('t').result('\t')
            | regex(r'u[0-9a-fA-F]{4}').parsecmap(lambda s: chr(int(s[1:], 16)))
            | quote
        )
    return string_part() | string_esc()

class StopGenerator(StopIteration):
    def __init__(self, value):
        self.value = value

@lexeme
@generate
def quoted():
    yield quote
    body = yield many(charseq())
    yield quote
    raise StopGenerator(''.join(body))

@generate
def array():
    yield lbrack
    elements = yield sepBy(value, comma)
    yield rbrack
    raise StopGenerator(elements)


@generate
def object_pair():
    key = yield regex(r'[a-zA-Z][a-zA-Z0-9]*') | quoted
    yield colon
    val = yield value
    raise StopGenerator((key, val))


@generate
def json_object():
    yield lbrace
    pairs = yield sepBy(object_pair, comma)
    yield rbrace
    raise StopGenerator(dict(pairs))
    
value = quoted | number() | json_object | array | true | false | null
relaxed_json = whitespace >> json_object
产出:

{'test': 157.0}
<class 'dict'>
157.0
None
No key named toast here
{'test':157.0}
157
没有一个
这里没有叫toast的钥匙

请重复并从“演示如何解决此编码问题”不是堆栈溢出问题。我们希望您做出诚实的尝试,然后询问有关算法或技术的特定问题。堆栈溢出不是为了替换现有文档和教程。这是一个使用字符串函数从输入中提取所需信息的问题。查找如何在n两个文本标记。您所说的“我想将每个值属性化为变量”到底是什么意思?什么变量?您可以在读取时调用
.strip()
,删除尾随的换行符,然后使用
.split(“:”,1)
获取键/值对。@请删掉抱歉,我已经更正了我的帖子。@acw1668感谢您的回复非常感谢您的回复。我已经以其他形式解析了arduino输出的数据,以便能够使用它。但是您的方式似乎和我一样更有用。我会尝试一下。
{'test': 157.0}
<class 'dict'>
157.0
None
No key named toast here