用相同的参数初始化两个Python 类,得到不同的结果
Initialize two Python classes with same arguments, get different results
Objective: 理解关于两个 classes 使用相同参数初始化并产生不同结果的奇怪行为。
背景:
我的项目涉及 Raspberry Pi 3 通过串行(通过 USB 端口)通信与 Arduino MEGA 上的各种传感器通信。通讯协议简单
Raspberry Pi发送两个字节:
- 传感器的地址(例如
'\x04'
)
- 可以包含其他命令的第二个空字节(例如
'\x00'
)
MEGA等待两个字节,然后根据大case/switch
树回复请求的信息。
我已经用 Python class
es 封装了处理各种传感器的代码。给我带来麻烦的是 Encoder()
class。这是一个最小的例子:
import serial
class Encoder(object):
def __init__(self, hex_name):
self.hex_name = hex_name
def value(self):
temp = self.hex_name + '\x00'
arduino.write(temp)
return int(arduino.readline())
if __name__ == '__main__':
arduino = serial.Serial('/dev/ttyACMO', 115200)
encoder_one = Encoder('\x03')
encoder_two = Encoder('\x04')
print encoder_one.value()
print encoder_two.value()
Arduino 处理请求如下图:
if(Serial.available() >= 2){
temp1 = Serial.read();
temp2 = Serial.read();
switch(temp1){
case 1:
...
case 3:
Serial.println(positionLeft);
break;
case 4:
Serial.println(positionRight);
break;
case 5:
...
}
}
问题:
我从编码器中得到了无意义的值。特别令人担忧的是,当我用 same hex_name(即 '\x04'
)初始化两个编码器时,我从 encoder_one.value()
和 [=21 得到不同的值=].
假设:
- class 结构有些错误。
在将它封装到 class 之前,我已经可以正常工作了。我想知道我是否将 encoder_one
和 encoder_two
分配给同一个对象或类似的愚蠢的东西。
我在 value()
中的 return
之前添加了一行,用于打印 hex_name
(即 print self.hex_name
)。当我将两个编码器都设置为 '\x04'
时,我打印了相同的非字母数字字符。当我将一个编码器设置为 '\x03'
并将另一个编码器设置为 '\x04'
时,我得到了两个不同的非字母数字字符——一个是之前测试的字符。
- 通信中的帧偏移。
MEGA 需要两个字节。它等待两个字节,发送请求的信息,然后清除缓冲区。在我的 Python 程序中将十六进制值存储为字符串是可能的,当它执行 arduino.write()
时会添加一个额外的字节。类似于 \n
或其他不可打印的字符。
结论:
我已经花了大约三个小时研究这个错误,我认为解决它需要一些关于 classes 如何工作的信息,但我不明白。
原来是第二个假设。十六进制字节的连接步骤中显然包含一些不可打印的字符。切换到以下顺序解决了问题。
编辑: 我发现在 write()
之后立即执行 readline()
会出现间歇性错误。我在两个操作之间添加了 10 毫秒的延迟。
旧:
def value(self):
temp = self.hex_name + '\x00'
arduino.write(temp)
return int(arduino.readline())
新:
def value(self):
arduino.write(self.hex_name)
arduino.write('\x00')
time.sleep(0.010)
return int(arduino.readline())
完整的(现在可用的)示例如下所示。
import serial
class Encoder(object):
def __init__(self, hex_name):
self.hex_name = hex_name
def value(self):
arduino.write(self.hex_name)
arduino.write('\x00')
time.sleep(0.010)
return int(arduino.readline())
if __name__ == '__main__':
arduino = serial.Serial('/dev/ttyACMO', 115200)
encoder_one = Encoder('\x03')
encoder_two = Encoder('\x04')
print encoder_one.value()
print encoder_two.value()
Objective: 理解关于两个 classes 使用相同参数初始化并产生不同结果的奇怪行为。
背景:
我的项目涉及 Raspberry Pi 3 通过串行(通过 USB 端口)通信与 Arduino MEGA 上的各种传感器通信。通讯协议简单
Raspberry Pi发送两个字节:
- 传感器的地址(例如
'\x04'
) - 可以包含其他命令的第二个空字节(例如
'\x00'
)
MEGA等待两个字节,然后根据大case/switch
树回复请求的信息。
我已经用 Python class
es 封装了处理各种传感器的代码。给我带来麻烦的是 Encoder()
class。这是一个最小的例子:
import serial
class Encoder(object):
def __init__(self, hex_name):
self.hex_name = hex_name
def value(self):
temp = self.hex_name + '\x00'
arduino.write(temp)
return int(arduino.readline())
if __name__ == '__main__':
arduino = serial.Serial('/dev/ttyACMO', 115200)
encoder_one = Encoder('\x03')
encoder_two = Encoder('\x04')
print encoder_one.value()
print encoder_two.value()
Arduino 处理请求如下图:
if(Serial.available() >= 2){
temp1 = Serial.read();
temp2 = Serial.read();
switch(temp1){
case 1:
...
case 3:
Serial.println(positionLeft);
break;
case 4:
Serial.println(positionRight);
break;
case 5:
...
}
}
问题:
我从编码器中得到了无意义的值。特别令人担忧的是,当我用 same hex_name(即 '\x04'
)初始化两个编码器时,我从 encoder_one.value()
和 [=21 得到不同的值=].
假设:
- class 结构有些错误。
在将它封装到 class 之前,我已经可以正常工作了。我想知道我是否将 encoder_one
和 encoder_two
分配给同一个对象或类似的愚蠢的东西。
我在 value()
中的 return
之前添加了一行,用于打印 hex_name
(即 print self.hex_name
)。当我将两个编码器都设置为 '\x04'
时,我打印了相同的非字母数字字符。当我将一个编码器设置为 '\x03'
并将另一个编码器设置为 '\x04'
时,我得到了两个不同的非字母数字字符——一个是之前测试的字符。
- 通信中的帧偏移。
MEGA 需要两个字节。它等待两个字节,发送请求的信息,然后清除缓冲区。在我的 Python 程序中将十六进制值存储为字符串是可能的,当它执行 arduino.write()
时会添加一个额外的字节。类似于 \n
或其他不可打印的字符。
结论:
我已经花了大约三个小时研究这个错误,我认为解决它需要一些关于 classes 如何工作的信息,但我不明白。
原来是第二个假设。十六进制字节的连接步骤中显然包含一些不可打印的字符。切换到以下顺序解决了问题。
编辑: 我发现在 write()
之后立即执行 readline()
会出现间歇性错误。我在两个操作之间添加了 10 毫秒的延迟。
旧:
def value(self):
temp = self.hex_name + '\x00'
arduino.write(temp)
return int(arduino.readline())
新:
def value(self):
arduino.write(self.hex_name)
arduino.write('\x00')
time.sleep(0.010)
return int(arduino.readline())
完整的(现在可用的)示例如下所示。
import serial
class Encoder(object):
def __init__(self, hex_name):
self.hex_name = hex_name
def value(self):
arduino.write(self.hex_name)
arduino.write('\x00')
time.sleep(0.010)
return int(arduino.readline())
if __name__ == '__main__':
arduino = serial.Serial('/dev/ttyACMO', 115200)
encoder_one = Encoder('\x03')
encoder_two = Encoder('\x04')
print encoder_one.value()
print encoder_two.value()