You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从树莓派GPIO编码器函数中获取距离值(避免死循环)

Fixing the Infinite Loop in Your Raspberry Pi Encoder working_odo Function

Got it, let's tackle that infinite loop issue and get you the distance value you need. Here's what's going wrong and how to fix it:

The Problem with Your Current Code

Your working_odo function has an infinite while 1 loop that never exits—so it never reaches the line where you calculate distance, and even if it did, there's no way to return that value to the caller. Let's fix this with two practical solutions depending on your use case.


Solution 1: Add a Time-Based Exit Condition

If you want the encoder to count for a specific duration (e.g., 5 seconds) before returning the distance, use a timeout with the time module:

import time
import RPi.GPIO as IO  # Ensure GPIO is initialized properly first

def working_odo(run_duration=5):
    last_state = IO.input(15)
    state_count = 0
    start_time = time.time()
    
    # Run loop only for the specified duration
    while time.time() - start_time < run_duration:
        current_state = IO.input(15)
        if current_state != last_state:
            state_count += 1
            last_state = current_state
    
    # Calculate and return distance once loop exits
    distance = 0.001 * state_count
    return distance

# Call and print the result
print(working_odo())

How this works: The loop runs only until the elapsed time hits your run_duration (default 5 seconds). Once it exits, the function calculates and returns the distance value, which you can then print directly.


Solution 2: Use GPIO Interrupts (More Efficient for Encoders)

Polling with a loop wastes CPU resources. A better approach for encoders is to use GPIO interrupts—this triggers a count only when the encoder pin's state changes:

import RPi.GPIO as IO

# Initialize global variables for counting
state_count = 0
last_state = None

def encoder_callback(channel):
    global state_count, last_state
    current_state = IO.input(15)
    if current_state != last_state:
        state_count += 1
        last_state = current_state

# Set up GPIO (adjust mode to BOARD if you use physical pin numbering)
IO.setmode(IO.BCM)
IO.setup(15, IO.IN, pull_up_down=IO.PUD_UP)  # Add pull-up/down as needed for your encoder
last_state = IO.input(15)

# Attach interrupt to detect both rising and falling edges (standard for encoders)
IO.add_event_detect(15, IO.BOTH, callback=encoder_callback)

def working_odo():
    global state_count
    # Reset count before starting measurement
    state_count = 0
    # Wait for your stop trigger (here, pressing Enter—adjust to your use case)
    input("Press Enter to stop measuring distance...")
    
    # Calculate final distance
    distance = 0.001 * state_count
    # Optional: Clean up interrupt if you don't need it anymore
    IO.remove_event_detect(15)
    return distance

# Get and print the distance
print(working_odo())

How this works: The interrupt listens for any change on pin 15 and updates the count in the background. The working_odo function resets the count, waits for your stop signal, then calculates and returns the distance. This is far more efficient than a busy loop.


Quick Tips

  • Don't forget to add IO.cleanup() at the end of your script to avoid GPIO pin conflicts in future runs.
  • Calibrate the 0.001 multiplier to match your encoder's actual distance per pulse (this value depends on your hardware setup).

内容的提问来源于stack exchange,提问作者Javid Hussain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 11:47:35