Python自助照相亭:投币前禁用按键,保存照片后重新禁用
Hey there! Let's work through this conditional button control for your Raspberry Pi photobooth—this is a common use case, so we can break it down into simple, manageable steps.
Core Logic to Implement
First, let's map out the state transitions you need:
- Initial state: Photo button is disabled (does nothing when pressed)
- After valid coin insertion (10 pulses on GPIO 18): Enable the photo button
- After photo is saved: Disable the photo button again
Step 1: Track Button State
We'll use a state variable (or a class attribute, for cleaner code) to track whether the photo button should work. This lets us gate the button's functionality easily.
Step 2: Handle Coin Pulses
Your coin sensor sends 10 pulses for a €1 coin. We'll count these pulses, and when we hit 10, we flip the button state to enabled.
Step 3: Gate the Photo Button
In the photo button's trigger function, we first check if the button is enabled. If not, we ignore the press; if it is, we run the photo capture/save logic, then disable the button again.
Example Code (Clean, Structured Version)
I'll use gpiozero (it's simpler for Raspberry Pi GPIO tasks than raw RPi.GPIO) and picamera for capturing photos. We'll wrap everything in a class to avoid messy global variables:
from gpiozero import Button from picamera import PiCamera import time class PhotoBooth: def __init__(self): # State management self.photo_button_enabled = False self.coin_pulse_counter = 0 # Hardware setup # Coin sensor on GPIO 18 (adjust bounce_time if you get false pulses) self.coin_sensor = Button(18, pull_up=True, bounce_time=0.1) self.coin_sensor.when_pressed = self._count_coin_pulse # Photo button on GPIO 23 (change to your actual button pin) self.photo_button = Button(23, pull_up=True, bounce_time=0.1) self.photo_button.when_pressed = self._capture_photo # Camera initialization self.camera = PiCamera() def _count_coin_pulse(self): """Increment pulse count; enable button when 10 pulses are detected""" self.coin_pulse_counter += 1 print(f"Coin pulse detected: {self.coin_pulse_counter}/10") if self.coin_pulse_counter >= 10: self.photo_button_enabled = True print("€1 received! Photo button is now enabled.") self.coin_pulse_counter = 0 # Reset for next coin def _capture_photo(self): """Capture and save photo only if button is enabled""" if not self.photo_button_enabled: print("Please insert €1 first to use the photobooth!") return # Run photo capture logic print("Preparing to take photo...") self.camera.start_preview() time.sleep(2) # Give user time to pose photo_filename = f"photobooth_shot_{time.strftime('%Y%m%d_%H%M%S')}.jpg" self.camera.capture(photo_filename) self.camera.stop_preview() print(f"Photo saved successfully as {photo_filename}!") # Disable button after photo is saved self.photo_button_enabled = False print("Photo button disabled. Insert another coin to take another shot.") def run(self): """Main loop to keep the program running""" try: print("Photobooth ready! Insert €1 to start.") while True: time.sleep(1) except KeyboardInterrupt: # Cleanup on exit self.camera.close() print("\nPhotobooth shutting down. Thanks for using it!") if __name__ == "__main__": photobooth = PhotoBooth() photobooth.run()
Key Notes to Adapt to Your Setup
- Adjust GPIO pins: Change
18(coin sensor) and23(photo button) to match your actual wiring. - Debouncing: The
bounce_time=0.1helps filter out false pulses from the coin sensor or button—tweak this if you get unexpected counts. - Coin sensor trigger type: If your sensor sends low-level pulses instead of high, change
pull_up=Truetopull_up=Falsein the Button initialization. - Error handling: Add
try-exceptblocks around the camera code if you want to handle issues like full storage gracefully.
Cleaning Up Your Existing Code
Since you mentioned your current code is messy, try refactoring it using this class structure:
- Move all hardware initialization (GPIO, camera) into the class
__init__method - Split functionality into small, single-purpose methods (like counting pulses, capturing photos)
- Use the state variable to gate button actions instead of scattering conditionals everywhere
This will make your code easier to debug and extend later!
内容的提问来源于stack exchange,提问作者Domposter

