Troubleshooting IR Sensor Project: Seeking Guidance
31. Červenec 2024 v 14:15
Hi everyone,
I’m working on my first Raspberry Pi project and could use some guidance. I’m building a theremin-like digital instrument using two SHARP GP2Y0A51SK0F IR sensors. Each sensor is supposed to trigger one of five audio clips based on distance.
Here’s what I’ve done so far:
- I’ve set distance thresholds for each audio clip (e.g., 14-15cm triggers Clip 1, 11-13cm triggers Clip 2, etc.).
- I’ve written code to handle sensor input and play the clips accordingly.
However, I’m encountering a few issues:
- Erratic Playback: The audio clips play erratically and seem to be cut off at the low and high ends of the distance range.
- Persistent Playback: When no object is in front of the sensors, one clip plays continuously until something comes into range.
I’m wondering if:
- There might be improvements or adjustments I can make in the code to address these issues.
- The IR sensors might not be ideal for this application, and if alternatives like ultrasonic or Time-of-Flight sensors could be better (ideally want to solve with coding before buying new hardware)
Here’s my code for reference:
import RPi.GPIO as GPIO import time import spidev from subprocess import call import threading import statistics # Setup SPI spi = spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz = 1350000 # MCP3008 channel configuration sensor1_channel = 0 sensor2_channel = 1 # Distance to audio mapping with updated intervals distance_ranges = [(14, 15), (11, 13), (8, 10), (5, 7), (2, 4)] audio_files_sensor1 = [f"/home/jss/audio_clips/s1_clip{i+1}.m4a" for i in range(len(distance_ranges))] audio_files_sensor2 = [f"/home/jss/audio_clips/s2_clip{i+1}.m4a" for i in range(len(distance_ranges))] # Smoothing parameters smoothing_window_size = 5 sensor1_data = [] sensor2_data = [] def read_adc(channel): adc = spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def get_distance(sensor_channel, sensor_data): adc_value = read_adc(sensor_channel) distance = (adc_value * 3.3 / 1024) * 30 # Smoothing the distance using a simple moving average sensor_data.append(distance) if len(sensor_data) > smoothing_window_size: sensor_data.pop(0) smoothed_distance = statistics.mean(sensor_data) print(f"Smoothed distance from sensor {sensor_channel}: {smoothed_distance}") # Debugging return smoothed_distance def play_audio(file): try: print(f"Playing audio file: {file}") # Debugging call(["mpv", file]) except Exception as e: print(f"Error playing audio file: {file}. Error: {e}") def handle_sensor(sensor_channel, audio_files, sensor_data): last_played_index = -1 while True: distance = get_distance(sensor_channel, sensor_data) for i, (low, high) in enumerate(distance_ranges): if low <= distance <= high: if i != last_played_index: play_audio(audio_files[i]) last_played_index = i break time.sleep(0.1) def main(): print("Script started...") # Debugging # Create and start threads for each sensor sensor1_thread = threading.Thread(target=handle_sensor, args=(sensor1_channel, audio_files_sensor1, sensor1_data)) sensor2_thread = threading.Thread(target=handle_sensor, args=(sensor2_channel, audio_files_sensor2, sensor2_data)) sensor1_thread.start() sensor2_thread.start() # Wait for both threads to finish (they won't in this case) sensor1_thread.join() sensor2_thread.join() if __name__ == "__main__": main()import RPi.GPIO as GPIO import time import spidev from subprocess import call import threading import statistics # Setup SPI spi = spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz = 1350000 # MCP3008 channel configuration sensor1_channel = 0 sensor2_channel = 1 # Distance to audio mapping with updated intervals distance_ranges = [(14, 15), (11, 13), (8, 10), (5, 7), (2, 4)] audio_files_sensor1 = [f"/home/jss/audio_clips/s1_clip{i+1}.m4a" for i in range(len(distance_ranges))] audio_files_sensor2 = [f"/home/jss/audio_clips/s2_clip{i+1}.m4a" for i in range(len(distance_ranges))] # Smoothing parameters smoothing_window_size = 5 sensor1_data = [] sensor2_data = [] def read_adc(channel): adc = spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def get_distance(sensor_channel, sensor_data): adc_value = read_adc(sensor_channel) distance = (adc_value * 3.3 / 1024) * 30 # Smoothing the distance using a simple moving average sensor_data.append(distance) if len(sensor_data) > smoothing_window_size: sensor_data.pop(0) smoothed_distance = statistics.mean(sensor_data) print(f"Smoothed distance from sensor {sensor_channel}: {smoothed_distance}") # Debugging return smoothed_distance def play_audio(file): try: print(f"Playing audio file: {file}") # Debugging call(["mpv", file]) except Exception as e: print(f"Error playing audio file: {file}. Error: {e}") def handle_sensor(sensor_channel, audio_files, sensor_data): last_played_index = -1 while True: distance = get_distance(sensor_channel, sensor_data) for i, (low, high) in enumerate(distance_ranges): if low <= distance <= high: if i != last_played_index: play_audio(audio_files[i]) last_played_index = i break time.sleep(0.1) def main(): print("Script started...") # Debugging # Create and start threads for each sensor sensor1_thread = threading.Thread(target=handle_sensor, args=(sensor1_channel, audio_files_sensor1, sensor1_data)) sensor2_thread = threading.Thread(target=handle_sensor, args=(sensor2_channel, audio_files_sensor2, sensor2_data)) sensor1_thread.start() sensor2_thread.start() # Wait for both threads to finish (they won't in this case) sensor1_thread.join() sensor2_thread.join() if __name__ == "__main__": main()
[link] [comments]