我有一个Tkinter和加速度传感器MMA8452Q。我设置了传感器,如果达到阈值,则设置中断标志,并通过GUI收集和绘制特定时间段的数据。
有时,当我读取数据或在使用I2C read函数读取寄存器的任何其他点时,都会得到"I2C读取失败“(当错误发生在check_flags()方法中),有时会得到这样的错误:
interrupt 1 True
4 0 1810275105
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
self.run()
File "/usr/lib/python3.7/threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File "/home/pi/.../tkinter/mix/mix_interrupt.py", line 307, in check_flags
pi.i2c_read_byte_data(acc_sensor, FF_MT_SRC)
File "/usr/lib/python3/dist-packages/pigpio.py", line 2874, in i2c_read_byte_data
return _u2i(_pigpio_command(self.sl, _PI_CMD_I2CRB, handle, reg))
File "/usr/lib/python3/dist-packages/pigpio.py", line 1011, in _u2i
raise error(error_text(v))
pigpio.error: 'I2C read failed'我的代码可能有什么问题,还是应该是这个问题的错误呢?这种情况并不总是发生,但似乎是随机发生的。为了澄清的是,如果这个错误发生在try-除了-块中,我的数据仍然会被绘制,但是有些数据会丢失,而这个图有时看起来不完整。
我的重要代码部分:
这是一条主线:
threading.Thread(target=self.check_flags).start() #This is in the init method此函数在这样的线程中运行,并检查是否设置了self.interrupt_flag。
def check_flags(self):
while(True):
#print("check the flags")
if (self.interrupt_flag == True):
pi.i2c_read_byte_data(acc_sensor, FF_MT_SRC)
global scale_variable
self.x_graph = []
self.y1_graph = []
self.y2_graph = []
self.y3_graph = []
a = datetime.datetime.now()
one_time = True
start_time = time.time()*1000
while(time.time()*1000-start_time) < self.timeframe:
try:
b = datetime.datetime.now()
delta = b-a
y1 = self.readACCx()
y2 = self.readACCy()
y3 = self.readACCz()
self.y1_graph.append(y1)
self.y2_graph.append(y2)
self.y3_graph.append(y3)
self.x_graph.append(delta.total_seconds()*1000)
if (y1 > self.threshold or y2 > self.threshold): # this is for catching the whole movement if its longer than the set timeframe
self.timeframe += 5
except pigpio.error as e:
print("error:", e)
self.save_data()
self.plot_data()
self.interrupt_flag = False这是我用来读取传感器数据的功能之一。另外两个几乎是一样的
def readACCx(self): #reads x axis value 12 bit
global scale_variable
comp_acc_x2 = pi.i2c_read_byte_data(acc_sensor, OUT_X_MSB)
comp_acc_x1 = pi.i2c_read_byte_data(acc_sensor, OUT_X_LSB)
acc_combined = ((comp_acc_x2 << 8) | comp_acc_x1) >>4
if acc_combined < 2048:
acc_combined = acc_combined*scale_variable
return acc_combined
else:
acc_combined = acc_combined - 4096
acc_combined = acc_combined*scale_variable
return acc_combined这是我的中断程序:
def my_callback1(self, gpio, level, tick): #first interrupt function
self.interrupt_flag = True
print("interrupt 1", self.interrupt_flag)
print(gpio, level, tick)编辑(几乎完美)工作代码:
protect = threading.Lock() # this is outside of any class at the top
def check_flags(self): # new data capture method
while(True):
#print("check the flags")
if (self.interrupt_flag == True):
protect.acquire()
ff_flag = pi.i2c_read_byte_data(acc_sensor, FF_MT_SRC)
print("interrupt cleared", ff_flag)
global scale_variable
self.x_graph = []
self.y1_graph = []
self.y2_graph = []
self.y3_graph = []
a = datetime.datetime.now()
one_time = True
start_time = time.time()*1000
while(time.time()*1000-start_time) < self.timeframe:
try:
b = datetime.datetime.now()
delta = b-a
y1 = self.readACCx()
y2 = self.readACCy()
y3 = self.readACCz()
self.y1_graph.append(y1)
self.y2_graph.append(y2)
self.y3_graph.append(y3)
self.x_graph.append(delta.total_seconds()*1000)
if (y1 > self.threshold or y2 > self.threshold):
self.timeframe += 5
except pigpio.error as e:
print("error:", e)
self.save_data()
self.plot_data()
self.interrupt_flag = False
self.timeframe = self.config.getint('setting', 'timeframe')
print("scale_variable: ", scale_variable)
protect.release()发布于 2022-08-08 17:15:52
你的回溯不符合你的代码。回溯显示i2c_read_byte_data结果没有保存在任何地方。I2C时钟一定是正确的,否则你就什么都得不到了。
问题可能是同步。当你说“中断”的时候,就发出了危险的信号。如果您的中断处理程序尝试执行一个I2C操作,而您的主线代码也在执行一个中断处理程序,那么这两个操作将发生冲突,特别是因为您必须分别执行MSB和LSB。我建议你使用一个threading.Lock来确保你的序列不会被打断。
https://stackoverflow.com/questions/73281667
复制相似问题