Python 霍尔传感器监视器 - 太高 CPU 使用率
Python Hall Sensor Monitor - Too High CPU Usage
我正在做一个项目,我需要监控多个霍尔传感器以进行位置编码。逻辑非常简单,但数字信号速度很快:每秒可能有多达 350 次位置变化。
我希望我可以简单地编写一个监视 GPIO 的霍尔传感器监视程序,但如果我以必要的频率进行监视,这些程序似乎会消耗相当多的 CPU。我曾希望在每次投票之间暂停 CPU 会有所帮助,但它似乎并没有太大的区别。
这是我目前正在做的轮询循环。它“有效”,但 CPU 使用率太高了。我 运行 在一个与内存映射文件上的其他进程共享“位置”变量的进程上。
REFRESH_RATE = .0005
while True:
new_p1_state = GPIO.input(hall_p1)
new_p2_state = GPIO.input(hall_p2)
if new_p1_state != p1_state or new_p2_state != p2_state:
if p1_state == GPIO.HIGH:
if new_p2_state == GPIO.HIGH:
position -= 1
else:
position += 1
else:
if new_p2_state == GPIO.LOW:
position -= 1
else:
position += 1
p1_state = new_p1_state
p2_state = new_p2_state
time.sleep(REFRESH_RATE)
有人可以推荐一种更有效的方法吗?我应该避免 python 并使用更快的东西吗?如果是什么?
您为这项工作使用了错误的硬件和软件。 Jetson Nano 可以被视为功能齐全的 PC。据我了解,它适用于高级算法、图像处理和神经网络评估。裸机编程对于这种设备没有多大意义,因此你有 Linux 运行。您需要注意,在非实时操作系统存在的情况下,您无法获得可靠的延迟时间。
读取正交编码器是具有严格硬实时要求的低级任务。为此,您需要微控制器(如 PIC、AVR、ARM Cortex M)、C/C++、裸机编程或 RTOS,最好是能够直接读取正交编码器的专用硬件。
轮询输入引脚不是连接编码器的正确方法。请记住,您需要比预期的脉冲频率更快地轮询引脚。在微控制器中,您使用中断来代替轮询。甚至中断也跟不上高分辨率和快速旋转的编码器。当中断不够用时,您需要专用的编码器接口硬件,它会自动为您计算脉冲数。
您能做的最好的事情就是选择一个微控制器并将编码器计数工作外包给它。由于您的编码器分辨率低,您不需要特殊的正交接口硬件模块。你可以选择一个 Arduino 并让它计算脉冲。然后你的 Jetson Nano 可以使用串行端口、I2C 或 SPI 查询 Arduino 以检索最新的脉冲计数。
我想跟进一下。我能够将其重写为基于中断的内核驱动程序。它比 python 版本好得多,但仍然不够好 - 当设备用力过大时,正交计数器会错过事件和漂移。
我现在正在尝试应用 PREEMPT-RT 补丁以启用对 linux 内核的完全实时抢占。希望这能在没有单独的微控制器的情况下满足我的需求。
我正在做一个项目,我需要监控多个霍尔传感器以进行位置编码。逻辑非常简单,但数字信号速度很快:每秒可能有多达 350 次位置变化。
我希望我可以简单地编写一个监视 GPIO 的霍尔传感器监视程序,但如果我以必要的频率进行监视,这些程序似乎会消耗相当多的 CPU。我曾希望在每次投票之间暂停 CPU 会有所帮助,但它似乎并没有太大的区别。
这是我目前正在做的轮询循环。它“有效”,但 CPU 使用率太高了。我 运行 在一个与内存映射文件上的其他进程共享“位置”变量的进程上。
REFRESH_RATE = .0005
while True:
new_p1_state = GPIO.input(hall_p1)
new_p2_state = GPIO.input(hall_p2)
if new_p1_state != p1_state or new_p2_state != p2_state:
if p1_state == GPIO.HIGH:
if new_p2_state == GPIO.HIGH:
position -= 1
else:
position += 1
else:
if new_p2_state == GPIO.LOW:
position -= 1
else:
position += 1
p1_state = new_p1_state
p2_state = new_p2_state
time.sleep(REFRESH_RATE)
有人可以推荐一种更有效的方法吗?我应该避免 python 并使用更快的东西吗?如果是什么?
您为这项工作使用了错误的硬件和软件。 Jetson Nano 可以被视为功能齐全的 PC。据我了解,它适用于高级算法、图像处理和神经网络评估。裸机编程对于这种设备没有多大意义,因此你有 Linux 运行。您需要注意,在非实时操作系统存在的情况下,您无法获得可靠的延迟时间。
读取正交编码器是具有严格硬实时要求的低级任务。为此,您需要微控制器(如 PIC、AVR、ARM Cortex M)、C/C++、裸机编程或 RTOS,最好是能够直接读取正交编码器的专用硬件。
轮询输入引脚不是连接编码器的正确方法。请记住,您需要比预期的脉冲频率更快地轮询引脚。在微控制器中,您使用中断来代替轮询。甚至中断也跟不上高分辨率和快速旋转的编码器。当中断不够用时,您需要专用的编码器接口硬件,它会自动为您计算脉冲数。
您能做的最好的事情就是选择一个微控制器并将编码器计数工作外包给它。由于您的编码器分辨率低,您不需要特殊的正交接口硬件模块。你可以选择一个 Arduino 并让它计算脉冲。然后你的 Jetson Nano 可以使用串行端口、I2C 或 SPI 查询 Arduino 以检索最新的脉冲计数。
我想跟进一下。我能够将其重写为基于中断的内核驱动程序。它比 python 版本好得多,但仍然不够好 - 当设备用力过大时,正交计数器会错过事件和漂移。
我现在正在尝试应用 PREEMPT-RT 补丁以启用对 linux 内核的完全实时抢占。希望这能在没有单独的微控制器的情况下满足我的需求。