在 python 2.7 中我发送 char 类型变量没有任何问题,但由于使用 Pyrebase 时出现问题,我需要使用 Python 3.5,将数据发送到 Arduino 时出现问题,我无法解决。arduino 应该接收 char 类型的数据。我澄清说我正在研究 Raspbian。我留下代码和错误。提前致谢。代码:
import pyrebase
import serial
puerto = serial.Serial('/dev/ttyACM0', 9600)
config = {
"apiKey": "Axxxxxxxxxxxxxxxxxxxxxxxxx",
"authDomain": "pxxxxxxxxxx.firebaseapp.com",
"databaseURL": "https://pxxxxxxxxxxxxxx.firebaseio.com",
"storageBucket": "pxxxxxxxxxx.appspot.com"
}
puerto = serial.Serial('/dev/ttyACM0', 9600, timeout=1)
firebase = pyrebase.initialize_app(config)
db = firebase.database()
res = db.child("cambio").child("valor1").get()
while True:
res = db.child("cambio").child("valor1").get()
if (res == "True"):
puerto.write('p')
else:
puerto.write('q')
错误:
Traceback (most recent call last):
File "pyreb.py", line 30, in <module>
puerto.write('q')
File "/usr/lib/python3/dist-packages/serial/serialposix.py", line 518, in write
d = to_bytes(data)
File "/usr/lib/python3/dist-packages/serial/serialutil.py", line 63, in to_bytes
raise TypeError('unicode strings are not supported, please encode to bytes: {!r}'.format(seq))
TypeError: unicode strings are not supported, please encode to bytes: 'q'
它告诉您它不支持传递字符串的 unicode 编码,并且您必须将它们作为字节传递。尝试类似:
来源:https ://www.mkyong.com/python/python-3-convert-string-to-bytes/
TL;DR: 您必须先调用
encode()
字符串上的方法,然后才能发送它。详细解释方法和原因:
Python 2 中的字符串
在 python 2 中,该类型
str
实际上表示一个字节字符串,而不是字符。发生的情况是,每次您的程序使用字符串时,解释器都会将其隐式处理为字节字符串,并即时对其进行转换。问题是要将字符转换为字节,这只能使用某些编码来完成,例如 ASCII(但仅限于英文字母)或 ISO-8859 标准(但根据不同的标准有不同的标准)使用的字母表)。
Unicode 通过打破 (1 个字符) -> (1 字节) 等价性来解决这个问题。在 Unicode 中,每个字符不再是单个字节。比如使用UTF-8,一个字符可以占用1个字节(如果是ascii,即小于128的代码),或者2个字节(如果是128到2048之间的代码),或者3个字节(如果它是 2048 和 65536 之间的代码),或 4 个字节(如果它是大于 65536 的代码)。
Python2 为您“决定”在将字符串转换为字节时使用哪种编码。一旦决定,我总是使用字节。这可能会导致意外,如下所示:
ñ
如果选择的编码是 ISO-8859-1(其中每个字符,包括,占用一个字节),答案可能是 3 。但它也可能是 4,如果选择的编码是 UTF-8(因为在这个中ñ
,作为大于 128 的代码,占用两个字节)。实际上,python 不会随机选择要使用的编码,但它需要一个(强制性)注释,您必须在文件开头放置一个类型:# coding: utf-8
例如。现在,当您进行输入/输出时,您想要输出的字节可能不会遵循与源代码相同的编码。
例如,您使用 UTF-8 编写了 python 程序,因此您将注释
# coding: utf-8
放在了开头。然后您的程序初始化变量texto = "año"
,这意味着texto
它将是一个 4 字节的字符串。最后,您将变量发送texto
到输出设备,例如 arduino 显示器。该显示器需要什么编码?它将接收 4 个字节(具体来说,它的值将是:
61, C3, B1, 6F
,十六进制)。显示的内容取决于您期望的编码:"año"
.año
也许你见过这个......)Python3中的字符串
在 python3 中,决定结束从字符到字节的隐式转换。
在内部,python 将所有字符存储为“unicode 点”而不是字节。每个字符产生一个 unicode 点。这避免了之前在计算时出现的问题
len("año")
,根据我们使用 ISO-8859-1 还是 UTF-8,它可能给出 3 或 4(如果我们使用 UTF-16,它甚至可能给出 6,因为在这种编码中每个字符都是两个字节)。在 python 3len("año")
中,它总是返回 3,例如,当我们想要将显示的长度调整到某个宽度时,这会简化很多事情。但是当我们想要输入/输出一个字符串时,就需要将其显式转换为字节。也就是说,python 不会自动为我们做这件事。
这样做的缺点是我们的 python2 程序不再兼容,因为所有的转换都必须是显式的(也是输入的,因为当我们从设备读取某些内容时,我们将读取字节,如果我们想将其视为字符串我们必须将其转换为 char) 。但它的优点是我们可以完全控制所使用的编码,当我们不同的 I/O 设备不都使用相同的编码时尤其重要。
在上面的示例中,如果我们知道我们的显示需要 ISO-8859-1,即使我们的编辑器将文本保存为 UTF-8,那也没关系,因为 python 存储在变量中的
texto
是 3 个 unicode 点。当我们要将它发送到显示器时,我们将其“编码”为一个字节序列,指定显示器使用哪种编码,例如:或者这样:
或者,如果您要使用 utf-8,如下所示:
现在我们有两种不同的类型。
texto
是类型的str
(我坚持认为它不再是一个字节序列而是一个 unicode 点序列),并且codificado
它是类型bytes
并且相当于旧的 python2 字符串。如果您将 的值打印到控制台(使用
print
)codificado
,您会看到它b
在它前面放了一个,表示它是一个字节字符串。例如:b
表示它是一个字节串,然后我们看到这些字节的表示。如果有问题的字节可以表示为 ASCII(如a
oro
),它将“按原样”显示。如果不是,它将显示\x
字节的十六进制代码(在这种情况下,我们看到ñ
已使用值 byte 进行编码f1
)。现在可以在输入/输出操作中使用该字节序列,例如将其发送到文件,或通过套接字或通过串行端口。当然,请记住,通信“另一端”的人是否会理解您正在使用的编码。至少,由于必须
encode()
显式使用 python3,它迫使我们意识到这个问题并正确编码。该错误表示您不能直接发送字符,而是要求您发送字节/字节数组。
您可以通过在字符串之前放置一个“b”来实现这一点:
因此解决方案可能如下:
您可以在这里查看更多信息:http: //learning-python.com/strings30.html