import time
import board
import math
import pwmio
###########################################################
class PWMArray:
def __init__(self,pwm_objects):
self.pwm_objects = pwm_objects
def __iter__(self):
self.index = 0
return self
def __next__(self):
current = self.index
self.index = (self.index+1) % len(pwm_objects)
return pwm_objects[current]
###########################################################
led_pins = [board.A0, board.A1, board.A2]
pwm_objects = [
pwmio.PWMOut(pin=led_pin,duty_cycle=65535,frequency=500)
for led_pin in led_pins ]
# create an iterator for the list of three PWMOut objects
pwm_iter = iter(PWMArray(pwm_objects))
# create a table of (N+1) sine-wave values
N=128
sine_int = lambda i: int(65535*(1-math.sin(math.pi*i/N)))
values = [sine_int(i) for i in range(N+1)]
try:
level = 0 # 0..N
pwm = next(pwm_iter) # select the first PWM output
t = int(1000*time.monotonic()) # time in msec
while True:
now = int(1000*time.monotonic()) # time in msec
if now - t < 15:
continue
t = now # update timestamp
pwm.duty_cycle = values[level]
if level == N:
level = 0
pwm = next(pwm_iter) # select next PWM output
else:
level += 1
except KeyboardInterrupt:
pass
for pwm in pwm_objects:
pwm.deinit()
print('Done')
โค้ดตัวอย่างที่ 2: RGB LED + Push Button
ตัวอย่างนี้สาธิตการตรวจสอบการกดปุ่มจำนวน 1 ปุ่ม เมื่อมีการกดปุ่มแต่ละครั้ง จะทำให้ RGB LED เปลี่ยนสีไปตามลำดับ วงจรปุ่มกดภายนอกที่ได้นำมาต่อเพิ่มนั้นรับอินพุตแบบดิจิทัลที่ขา B8 / PB08 และขาเอาต์พุตสำหรับ RGB LED (active-low, common anode) คือ A0 / PA00, A1 / PA01, A2 / PA02 ตามลำดับ
คำสั่งที่ใช้สำหรับ Digital I/O มาจากไลบรารี digitalio (API)
import time
import board
import digitalio
button_pin = board.B8
button = digitalio.DigitalInOut(button_pin)
button.direction = digitalio.Direction.INPUT
button.pull = digitalio.Pull.UP
led_pins = [board.A0, board.A1, board.A2]
leds = [ digitalio.DigitalInOut(pin) for pin in led_pins]
for led in leds:
led.direction = digitalio.Direction.OUTPUT
led.drive_mode = digitalio.DriveMode.PUSH_PULL
led.value = True
try:
index = 0
while True:
if button.value == 0: # button pressed
while button.value != 1: # wait until released
pass
leds[index].value = True
index = (index+1) % len(leds)
leds[index].value = False
time.sleep(0.05)
except KeyboardInterrupt:
pass
button.deinit()
for led in leds:
led.value = True
led.deinit()
print('Done')
พฤติกรรมการทำงานของโค้ดตัวอย่างมีดังนี้ เริ่มต้นให้ LED หนึ่งดวงอยู่ในสถานะ ON (ตรงกับตำแหน่ง LSB) จากนั้นตำแหน่งของ LED ที่อยู่ในสถานะ ON จะเลื่อนไปทางซ้ายทีละตำแหน่ง เมื่อไปจนถึงซ้ายสุด (ตรงกับตำแหน่ง MSB) ให้เลื่อนกลับไปทางขวา และทำในลักษณะนี้ซ้ำไปเรื่อย ๆ
import time
import busio
from board import SCL, SDA
PCF8574_ADDR = 0x20
i2c = busio.I2C(SCL, SDA,frequency=100000) # 100kHz speed
# attempt to lock the i2c bus
while not i2c.try_lock():
pass
addr_found = []
addr_found = i2c.scan()
print("I2C found:", [hex(addr) for addr in addr_found])
i2c.unlock()
if PCF8574_ADDR not in addr_found:
print('PCF8574 not found')
shift_left = lambda x: ((x << 1) | (x >> 7)) & 0xff
shift_right = lambda x: ((x >> 1) | (x << 7)) & 0xff
try:
data = 0x01
direction = 1 # shift left
buf = bytearray(1)
while True:
if i2c.try_lock():
buf[0] = data ^ 0xff # inverting output
i2c.writeto(PCF8574_ADDR, buffer=buf,start=0,end=1)
i2c.unlock()
if data == 0x80: # MSB is 1.
direction = 0 # change direction to shift-right
elif data == 0x01: # LSB is 1.
direction = 1 # change direction to shift-left
if direction == 1:
data = shift_left(data)
else:
data = shift_right(data)
time.sleep(0.1)
except KeyboardInterrupt:
pass
i2c.deinit()
import time
import busio
from board import *
from adafruit_bus_device.i2c_device import I2CDevice
PCF8574_ADDR = 0x20
i2c = busio.I2C(SCL, SDA, frequency=100000)
dev = I2CDevice(i2c, PCF8574_ADDR)
shift_left = lambda x: ((x << 1) | (x >> 7)) & 0xff
shift_right = lambda x: ((x >> 1) | (x << 7)) & 0xff
try:
data = 0x01
direction = 1 # shift left
buf = bytearray(1)
while True:
buf[0] = data ^ 0xff # inverting output
with dev:
dev.write(buf)
if data == 0x80: # MSB is 1.
direction = 0 # change direction to shift-right
elif data == 0x01: # LSB is 1.
direction = 1 # change direction to shift-left
if direction == 1:
data = shift_left(data)
else:
data = shift_right(data)
time.sleep(0.1)
except KeyboardInterrupt:
pass
i2c.deinit()
import time
import busio
from board import *
from adafruit_bus_device.i2c_device import I2CDevice
PCF8574_ADDR = 0x20
i2c = busio.I2C(SCL, SDA, frequency=100000)
dev = I2CDevice(i2c, PCF8574_ADDR)
STATES = ['LOW','HIGH']
try:
buf = bytearray(1)
t = int(1000*time.monotonic()) # time in msec
last_value = 0xff
while True: # press Ctrl+C to stop
now = int(1000*time.monotonic()) # time in msec
if now - t < 50:
continue
# update every 50 msec
t = now
buf[0] = 0xff # must be 1's for input checking
with dev:
dev.readinto(buf)
value = buf[0]
change = value ^ last_value
if change != 0: # state change detected
if change & 1 != 0: # SW1
print('SW1:', STATES[value & 1])
if change & 2 != 0: # SW2
print('SW2:', STATES[value>>1 & 1])
if change & 4 != 0: # SW3
print('SW3:', STATES[value>>2 & 1])
last_value = value
except KeyboardInterrupt:
pass
i2c.deinit()
print('Done')
เผยแพร่ภายใต้ลิขสิทธิ์
Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)