pimoroni-pico/micropython/examples/breakout_encoder_wheel/gpio_pwm.py

68 wiersze
2.0 KiB
Python

2023-04-27 19:51:44 +00:00
import math
import time
from pimoroni_i2c import PimoroniI2C
2023-05-04 13:10:12 +00:00
from pimoroni import BREAKOUT_GARDEN_I2C_PINS # or PICO_EXPLORER_I2C_PINS or HEADER_I2C_PINS
2023-04-27 19:51:44 +00:00
from breakout_encoder_wheel import BreakoutEncoderWheel, CENTRE, GPIOS, NUM_GPIOS
2023-05-04 13:10:12 +00:00
from breakout_ioexpander import PWM
2023-04-27 19:51:44 +00:00
2023-04-27 20:39:08 +00:00
"""
2023-04-27 19:51:44 +00:00
Output a sine wave PWM sequence on the Encoder Wheel's side GPIO pins.
Press the centre button or Ctrl+C to stop the program.
2023-04-27 20:39:08 +00:00
"""
2023-04-27 19:51:44 +00:00
2023-05-04 13:10:12 +00:00
# Constants
2023-04-27 19:51:44 +00:00
SPEED = 5 # The speed that the PWM will cycle at
UPDATES = 50 # How many times to update LEDs and Servos per second
2023-05-02 16:31:11 +00:00
UPDATE_RATE_US = 1000000 // UPDATES
2023-04-27 19:51:44 +00:00
FREQUENCY = 1000 # The frequency to run the PWM at
# Create a new BreakoutEncoderWheel
2023-05-04 13:10:12 +00:00
i2c = PimoroniI2C(**BREAKOUT_GARDEN_I2C_PINS)
2023-04-27 19:51:44 +00:00
wheel = BreakoutEncoderWheel(i2c)
# Set the PWM frequency for the GPIOs
period = wheel.gpio_pwm_frequency(FREQUENCY)
# Set the GPIO pins to PWM outputs
for g in GPIOS:
2023-05-04 13:10:12 +00:00
wheel.gpio_pin_mode(g, PWM)
2023-04-27 19:51:44 +00:00
2023-05-04 13:10:12 +00:00
# Variables
2023-04-27 19:51:44 +00:00
offset = 0.0
# Sleep until a specific time in the future. Use this instead of time.sleep() to correct for
# inconsistent timings when dealing with complex operations or external communication
def sleep_until(end_time):
2023-05-02 16:31:11 +00:00
time_to_sleep = time.ticks_diff(end_time, time.ticks_us())
if time_to_sleep > 0:
time.sleep_us(time_to_sleep)
2023-04-27 19:51:44 +00:00
# Make PWM waves until the centre button is pressed
while not wheel.pressed(CENTRE):
# Record the start time of this loop
2023-05-02 16:31:11 +00:00
start_time = time.ticks_us()
2023-04-27 19:51:44 +00:00
offset += SPEED / 1000.0
# Update all the PWMs
for i in range(NUM_GPIOS):
angle = ((i / NUM_GPIOS) + offset) * math.pi
duty = int(((math.sin(angle) / 2) + 0.5) * period)
# Set the GPIO pin to the new duty cycle, but do not load it yet
wheel.gpio_pin_value(GPIOS[i], duty, load=False)
# Have all the PWMs load at once
wheel.gpio_pwm_load()
# Sleep until the next update, accounting for how long the above operations took to perform
2023-05-02 16:31:11 +00:00
sleep_until(time.ticks_add(start_time, UPDATE_RATE_US))
2023-04-27 19:51:44 +00:00
# Turn off the PWM outputs
for g in GPIOS:
wheel.gpio_pin_value(g, 0)