<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># puppet-show.py

# Sample code for operating a mechanical puppet show.  Two pushbutton switches
# and two indicator LEDS are attached as the user interface.  A single MOSFET
# transistor drive circuit switches on all the DC motor.

# Related documentation:
# https://circuitpython.readthedocs.io/en/latest/shared-bindings/pwmio/index.html#module-pwmio

# Wiring notes:

# GPIO22 - pin 29 - PWM output to MOSFET
#
# GPIO12 - pin 16 - input from start switch
# GPIO13 - pin 17 - input from stop switch
# GND    - pin 18
# GPIO14 - pin 19 - output to start LED
# GPIO15 - pin 20 - output to stop LED

# ----------------------------------------------------------------
# Import standard Python modules.
import time, math

# Load the CircuitPython hardware definition module for pin definitions.
import board

# Load the CircuitPython pulse-width-modulation module for driving hardware.
import pwmio

# Load the CircuitPython digital input/output module for reading and writing pin voltages.
import digitalio

# ----------------------------------------------------------------
# Initialize hardware.

# Create a PWMOut object on GP22.  This will create a pulsing signal with
# variable duty cycle.  The switching rate of 20kHz is chosen to be
# supra-audible.
pwm = pwmio.PWMOut(board.GP22, duty_cycle=0, frequency=20000)

# Utility function to calculate and apply a new duty cycle setting.  Converts a
# unit-range (0.0 to 1.0) pwm_level to a 16-bit integer representing a fraction
# needed by the PWM driver.
def set_motor_speed(pwm_device, pwm_level):
    pwm_device.duty_cycle = min(max(int(pwm_level * 2**16), 0), 2**16-1)
    print("Applied duty cycle of %d for pwm_level %f" % (pwm_device.duty_cycle, pwm_level))

# ----------------------------------------------------------------
# Set up digital inputs.

start_switch = digitalio.DigitalInOut(board.GP12)
start_switch.direction = digitalio.Direction.INPUT

stop_switch = digitalio.DigitalInOut(board.GP13)
stop_switch.direction = digitalio.Direction.INPUT

# Set up digital inputs.

start_LED = digitalio.DigitalInOut(board.GP14)
start_LED.direction = digitalio.Direction.OUTPUT

stop_LED = digitalio.DigitalInOut(board.GP15)
stop_LED.direction = digitalio.Direction.OUTPUT

# ----------------------------------------------------------------
# Enter the main event loop.
while True:

    # turn on stop LED
    stop_LED.value = True

    # wait for start switch; it is wired active-low, so it will become False when pressed
    while start_switch.value is True:
        pass

    # turn off stop LED, turn on start LED
    stop_LED.value = False
    start_LED.value = True

    # turn the motor on
    set_motor_speed(pwm, 1.0)

    # wait for stop switch; it is wired active-low, so it will become False when pressed
    while stop_switch.value is True:
        pass

    # turn the motor off again
    set_motor_speed(pwm, 0.0)

    # turn off start LED
    start_LED.value = False
</pre></body></html>