- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
您好,我一直在研究Python代码,该代码将通过WiFi刷新我的Arduino,而我几乎可以将它如此接近地工作。
问题是它是为Python 2创建的,我希望它在最新的python 3上运行。我在套接字发送或接收字符串的地方添加了.encode和解码。直到停止读取字符串并想要读取十六进制字符串为止,它的效果都很好。我得到这个错误
Traceback (most recent call last): File "C:\Users\edwin\Desktop\FlashTesting\pythonFlash.py", line 258, in main() File "C:\Users\edwin\Desktop\FlashTesting\pythonFlash.py", line 250, in main if wait_for (cli, "\x00", MAX_TIMEOUT) [0]: File "C:\Users\edwin\Desktop\FlashTesting\pythonFlash.py", line 123, in wait_for received += cli.recv(1).decode() # .decode() is new TypeError: Can't convert 'bytes' object to str implicitly UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe1 in position 0: unexpected end of data.
import sys
import binascii
import struct
import select
import socket
import errno
MAX_TIMEOUT = 500
SUCCESS = "success"
FAILED = "failed"
PORT = 50000
#-------------------------------------------------------------------------------------------------
'''
Class containing the data from non-contiguous memory allocations
'''
class Data :
def __init__ (self, begin, data):
self.begin = begin
self.data = data
self.count = len (data)
#-------------------------------------------------------------------------------------------------
'''
Parameters:
line: The line to parse
Returns:
The size of data. The address of data. The type of data. The line checksum. True if the checksum is correct, otherwise False.
Description:
It parses a line from the .hex file.
'''
def parse_line (line):
ok = False
size = int (line [ 1 : 3 ], 16)
address = int (line [ 3 : 7 ], 16)
type = int (line [ 7 : 9 ], 16)
next_index = (9 + size * 2)
data = binascii.a2b_hex (line [9: next_index])
checksum = int (line [ next_index :], 16)
#checking if checksum is correct
sum = size + (address >> 8) + (address & 0xFF) + type
for byte in data:
sum += byte # was ord(byte) removed to fix TypeError
if ( ~ (sum & 0xFF) + 1) & 0xFF == checksum:
ok = True
return (size, address, type, data, checksum, ok)
#-------------------------------------------------------------------------------------------------
'''
Parameters:
chunks: An array with different chunks of data.
path: The path to the .hex file to read
Returns:
True if the reading was successfully, otherwise False.
Description:
It reads a .hex file and stores the data in memory.
'''
def read_hex_file(chunks, path):
try:
file = open (path, 'r')
except IOError:
print ("Hex file not loaded")
return False
line = file.readline()
if line [0] != ':':
print ("The file seems to be a not valid .hex file")
file.close ()
return False
size, address, type, data, checksum, ok = parse_line(line.strip())
if not ok:
print ("The checksum in line 1 is wrong")
file.close()
return False
chunks.append(Data(address, data))
# Read the other lines
index = 0
count = 2
for line in file:
size, address, type, data, checksum, ok = parse_line(line.strip())
if not ok:
print ("The checksum in line", count, "is wrong")
file.close()
return False
if chunks [index].begin + chunks[index].count == address:
chunks [index].count += size
for code in data:
chunks [index].data += bytes(code) # added bytes to fix TypeError
else:
chunks.append(Data(address, data))
index += 1
count += 1
return True
#-------------------------------------------------------------------------------------------------
'''
Parameters:
None
Returns:
The server socket
Description:
It opens a server socket at the specified port and listens to connections.
'''
def init_server():
server = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
server.bind (('', PORT))
server.listen (1)
return server
#-------------------------------------------------------------------------------------------------
'''
Parameters:
cli: The client socket
response: The search string
timeout: The maximum time in milliseconds the function can be running before a time out.
Returns:
True if the string was found, otherwise False. The received string.
Description:
It waits for the expected string.
'''
def wait_for(cli, response, timeout):
inputs = [cli]
received = ""
milliseconds = 0
while milliseconds < timeout:
rlist, wlist, xlist = select.select(inputs,[], [], 0.001)
if len (rlist) > 0:
received += cli.recv(1).decode() # .decode() is new fixed TypeError
if response in received:
return True, received
milliseconds += 1
return False, received
#-------------------------------------------------------------------------------------------------
'''
Parameters:
cli: The client socket
timeout: The maximum time in milliseconds the function can be running before a time out.
length: The number of bytes to receive.
Returns:
True if the string has the required length, otherwise False. The received string.
Description:
It waits for the required length of bytes.
'''
def return_data(cli, timeout, length = 1):
inputs = [cli]
received = ""
milliseconds = 0
while milliseconds < timeout:
rlist, wlist, xlist = select.select(inputs,[], [], 0.001)
if len (rlist) > 0:
received = cli.recv(length).decode() # .decode() is new
return True, received
milliseconds += 1
return False, received
#-------------------------------------------------------------------------------------------------
'''
Parameters:
cli: The client socket
Returns:
True if the string was found, otherwise False
Description:
It waits for the acknowledge string.
'''
def acknowledge(cli):
if wait_for (cli, "\x14\x10", MAX_TIMEOUT) [0]: #STK_INSYNC, STK_OK
print (SUCCESS)
return True
else:
print (FAILED)
return False
#-------------------------------------------------------------------------------------------------
'''
Parameters:
chunks: An array with different chunks of data.
cli: The client socket
Returns:
Nothing
Description:
It starts the STK500 protocol to program the data at their respective memory address.
'''
def program_process(chunks, cli): # I HAVE ADDED .encode() to any strings inside cli.send IDK if they are correct ? the code has not got to this part yet....
print ("Connection to Arduino bootloader:"),
counter = 0
cli.send(("\x30\x20").encode()) #STK_GET_SYNCH, SYNC_CRC_EOP
if not acknowledge(cli):
return
print ("Enter in programming mode:"),
cli.send (("\x50\x20").encode()) #STK_ENTER_PROGMODE, SYNC_CRC_EOP
if not acknowledge(cli):
return
print ("Read device signature:"),
cli.send(("\x75\x20").encode()) #STK_READ_SIGN, SYNC_CRC_EOP
if wait_for (cli, "\x14", MAX_TIMEOUT) [0]: #STK_INSYNC
ok ,received = return_data (cli, MAX_TIMEOUT, 3)
print (binascii.b2a_hex (received))
if not wait_for (cli, "\x10", MAX_TIMEOUT) [0]: #STK_INSYNC
print (FAILED)
return
else:
print (FAILED)
return
for chunk in chunks:
total = chunk.count
if total > 0: #avoid the last block (the last line of .hex file)
current_page = chunk.begin
pages = total / 0x80
index = 0
for page in range (pages):
print ("Load memory address", current_page , ":"),
cli.send (struct.pack ((("<BHB").encode()), 0x55, current_page , 0x20)) #STK_LOAD_ADDRESS, address, SYNC_CRC_EOP
if not acknowledge (cli):
return
print ("Program memory address:"),
cli.send ((("\x64\x00\x80\x46").encode()) + chunk.data [index:index + 0x80] + (("\x20").encode())) #STK_PROGRAM_PAGE, page size, flash memory, data, SYNC_CRC_EOP
if not acknowledge (cli):
return
current_page += 0x40
total -= 0x80
index += 0x80
if total > 0:
print ("Load memory address", current_page , ":"),
cli.send (struct.pack ((("<BHB").encode()), 0x55, current_page, 0x20)) #STK_LOAD_ADDRESS, address, SYNC_CRC_EOP
if not acknowledge (cli):
return
print ("Program memory address:"),
cli.send (struct.pack(((">BHB").encode()), 0x64, total, 0x20) + chunk.data [index:index + total] + (("\x20").encode())) #STK_PROGRAM_PAGE, page size, flash memory, data, SYNC_CRC_EOP
if not acknowledge (cli):
return
print ("Leave programming mode:"),
cli.send (("\x51\x20").encode()) #STK_LEAVE_PROGMODE, SYNC_CRC_EOP
acknowledge (cli)
#-------------------------------------------------------------------------------------------------
def main():
print ("Arduino program via ESP V1.1")
print ("Listen to connections")
ser = init_server()
inputs = [ser]
while True:
rlist, wlist, xlist = select.select(inputs,[],[])
for s in rlist:
if s == ser:
cli, addr = s.accept()
print (addr[0], "connected")
# It assures the connection is for programming an Arduino and not other service.
if wait_for (cli, "hello", 20000) [0]:
cli.send(("welcome").encode()) # encode(0 is new
ok, received = wait_for(cli, "hex", 10000)
if ok:
chunks = []
print ("Read hex file", received.strip()) # prints out Read hex file Blink.ino.hex
if read_hex_file(chunks, received.strip()):
cli.send (("ok").encode()) # encode(0 is new
print ("listening for blank Serial")
# Wait for the byte '0' sent by Arduino after resetting
if wait_for (cli, "\x00", MAX_TIMEOUT) [0]: # CODE CURRENTLY STOPS HERE DUE TO UNICODE DECODE ERROR
program_process (chunks, cli)
else:
cli.send(("error").encode()) # encode(0 is new
cli.close()
print ("Listen to connections")
#-------------------------------------------------------------------------------------------------
if __name__ == "__main__":
main()
最佳答案
正如bjorn所暗示的那样,您不能(总是)按字节解码UTF-8字符串,仅仅是因为一个字符可以由多个字节组成。因此,您可以做的是组装字符串,直到(希望)包含完整的UTF-8序列,然后再对其进行解码。
def wait_for(cli, response, timeout):
inputs = [cli]
response = response.encode() # Make bytes!
received = b"" # Make bytes!
milliseconds = 0
while milliseconds < timeout:
rlist, wlist, xlist = select.select(inputs, [], [], 0.001)
if len(rlist) > 0:
received += cli.recv(1) # Do not decode yet!
if response in received:
return True, received.decode() # .decode() is new fixed TypeError
milliseconds += 1
return False, received.decode() # .decode() is new fixed TypeError
关于python - 从python 2到3的UnicodeDecodeError,带有.decode()和套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48043848/
我想使用 li 和 ul 制作一个多级下拉列表,以便显示我博客中按年和月排序的所有文章。我希望我的下拉菜单看起来像 Google Blogspot 下拉菜单: 这是我的 CSS 和 HTML 代码 u
我在 Win 7 64 机器上将 CodeBlocks 与 gcc 4.7.2 和 gmp 5.0.5 结合使用。开始使用 gmpxx 后,我看到一个奇怪的段错误,它不会出现在 +、- 等运算符中,但
我正在使用 tern 为使用 CodeMirror 运行的窗口提供一些增强的智能感知,它工作正常,但我遇到了一个问题,我想添加一些自定义“types”,可以这么说,这样下拉列表中它们旁边就有图标了。我
我正在尝试让我的 PC 成为 Android 2.3.4 设备的 USB 主机,以便能够在不需要实际“附件”的情况下开发 API。为此,我需要将 PC 设置为 USB 主机和“设备”(在我的例子中是运
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
我在设置服务器方面几乎是个新手,但遇到了一个问题。我有一个 Ubuntu 16.04 VPS 并安装了 Apache2 和 Tomcat7。我正在为 SSL 使用 LetsEncrypt 和 Cert
我在一个基于谷歌地图的项目上工作了超过 6 个月。我使用的是 Google Maps API V1 及其开发人员 API key 。当我尝试发布应用程序时,我了解到 Google API V1 已被弃
我是 Python 的新手,所以如果我对一些简单的事情感到困惑,请原谅。 我有一个这样的对象: class myObject(object): def __init__(self):
这个问题已经有答案了: How can I access object properties containing special characters? (2 个回答) 已关闭 9 年前。 我正在尝
我有下面的 CSS。我想要的是一种流体/液体(因为缺乏正确的术语)css。我正在为移动设备开发,当我改变模式时 从纵向 View 到陆地 View ,我希望它流畅。现在的图像 在陆地 View 中效
我正在尝试使用可以接受参数的缓存属性装饰器。 我查看了这个实现:http://www.daniweb.com/software-development/python/code/217241/a-cac
这个问题在这里已经有了答案: Understanding slicing (36 个答案) 关闭 6 年前。 以a = [1,2,3,4,5]为例。根据我的直觉,我认为 a[::-1] 与 a[0:
mysqldump -t -u root -p mytestdb mytable --where=datetime LIKE '2014-09%' 这就是我正在做的事情,它会返回: mysqldum
我正在制作销售税计算器,除了总支付金额部分外,其他一切都正常。在我的程序中,我希望能够输入一个数字并获得该项目的税额我还希望能够获得支付的总金额,包括交易中的税金。到目前为止,我编写的代码完成了所有这
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许在 Stack Overflow 上提出有关通用计算硬件和软件的问题。您可以编辑问题,使其成为
我是否必须进行任何额外的设置才能让 apache-airflow 在任务失败时向我发送电子邮件。我的配置文件中有以下内容(与默认值保持不变): [email] email_backend = airf
这个问题在这里已经有了答案: What does the $ symbol do in VBA? (5 个回答) 3年前关闭。 使用返回字符串(如 Left)的内置函数有什么区别吗?或使用与 $ 相同
我有一个用VB6编写的应用程序,我需要使用一个用.NET编写的库。有什么方法可以在我的应用程序上使用该库吗? 谢谢 最佳答案 这取决于。您可以控制.NET库吗? 如果是这样,则可以修改您的库,以便可以
当我创建一个以 ^ 开头的类方法时,我尝试调用它,它给了我一个错误。 class C { method ^test () { "Hi" } } dd C.new.test; Too m
我已经使用 bower 安装了 angularjs 和 materialjs。 凉亭安装 Angular Material 并将“ngMaterial”注入(inject)我的应用程序,但出现此错误。
我是一名优秀的程序员,十分优秀!