import machine
import utime as time
# use the on-board LED (GP25 pin)
led = machine.Pin( 25, machine.Pin.OUT )
try:
while True:
state = not led.value()
led.value( state )
print('LED state:', state)
time.sleep(0.5)
except KeyboardInterrupt:
pass
led.value(0) # turn off LED
import utime as time
from machine import Pin
BTN_PIN = 16 # use GP16 for Button pin
button = Pin( BTN_PIN, Pin.IN, Pin.PULL_UP )
while True:
if not button.value():
print('pressed')
break
time.sleep(0.1)
import utime as time
from machine import Pin
BTN_PIN = 16 # use GP16 for Button pin
button = Pin( BTN_PIN, Pin.IN, Pin.PULL_UP )
done = False
def button_handler(pin):
global done
# disable external interrupt on the Button pin
button.irq( handler=None )
done = True
button.irq( trigger=Pin.IRQ_FALLING, handler=button_handler )
print('Press the button!')
while not done:
time.sleep(0.1)
โค้ดตัวอย่างที่ 3: Push Button + Toggle LED
ตัวอย่างนี้สาธิตการเปิดใช้งานอินเทอร์รัพท์ที่ขา GPIO-14 (GP14) ที่ต่อกับวงจรปุ่มกดบนเบรดบอร์ด เมื่อมีการกดปุ่มแล้วปล่อยแต่ละครั้ง จะทำให้ LED บนบอร์ดสลับสถานะหนึ่งครั้ง
import utime as time
from machine import Pin
BTN_PIN = 16
LED_PIN = 25
button = Pin( BTN_PIN, Pin.IN, Pin.PULL_UP )
led = Pin( LED_PIN, Pin.OUT )
led.low() # turn the LED off
def button_handler(pin):
global pressed
# disable external interrupt on the Button pin
button.irq( handler=None )
pressed = True
print( time.ticks_ms() ) # show time ticks (in msec)
pressed = False
button.irq( trigger=Pin.IRQ_FALLING, handler=button_handler )
print('Press the button!')
try:
while True:
if pressed:
while not button.value():
time.sleep(0.1)
led.toggle() # toggle LED output
button.irq( trigger=Pin.IRQ_FALLING, handler=button_handler )
pressed = False
time.sleep(0.1)
except KeyboardInterrupt:
pass
led.low() # turn off LED
import utime as time
from machine import Pin, PWM
# use onboard LED and PWM output pin
pwm = PWM( Pin(25) )
# set PWM freq. to 1kHz
pwm.freq(1000)
# set counter to 0
cnt = 0
try:
while True:
if cnt < 256:
duty = cnt
else:
duty = 511-cnt
pwm.duty_u16( duty * 256 )
cnt = (cnt+1) % 512
time.sleep(0.01)
except KeyboardInterrupt:
pass
# set duty cycle to 0 (ns)
pwm.duty_ns(0)
# deinitialize the GPIO pin used for PWM output
pwm.deinit()
ถ้าทดสอบการทำงานของโค้ดตัวอย่างนี้กับบอร์ด RPi Pico จะเห็น LED บนบอร์ดค่อย ๆ สว่างขึ้นและดับลงซ้ำไปเรื่อย ๆ
ถ้าจะลองใช้โมดูล RGB LED ที่ใช้ขาสัญญาณควบคุมแบบ 3 ขา ก็สามารถทำได้เช่นกัน โค้ดตัวอย่างนี้สาธิตการใช้ขา GPIO-11, 12, 13(GP11,GP12,GP13) เป็นขาสัญญาณเอาต์พุต นำไปต่อกับขาสัญญาณของโมดูล RGB LED (Active-High) เพื่อเปลี่ยนค่า Duty Cycle ของสัญญาณแต่ละช่องไปตามลำดับ
import utime as time
from machine import Pin, PWM
pwm_list = [ PWM( Pin(p) ) for p in [11,12,13] ]
for pwm in pwm_list:
pwm.freq(1000) # set freq. to 1kHz
pwm.duty_ns(0) # set duty cycle (high pulse) = 0ns
try:
while True:
time.sleep(0.1)
for pwm in pwm_list:
for cnt in range(512):
if cnt < 256:
duty = cnt
else:
duty = (511-cnt)
pwm.duty_u16( duty * 256 )
time.sleep(0.005)
except KeyboardInterrupt:
pass
for pwm in pwm_list:
pwm.duty_ns(0)
pwm.deinit()
โค้ดตัวอย่างที่ 5: Timer-based LED Blink
ตัวอย่างนี้สาธิตการใช้งาน Timer (ตอนนี้ใช้ได้เฉพาะ Software Timer และใช้ Timer id เท่ากับ -1) เพื่อทำคำสั่งหรือเรียกใช้ฟังก์ชันตามคาบเวลาหรือความถี่ที่ได้กำหนดไว้ ซึ่งเป็นเหตุการณ์ที่เกิดขึ้นซ้ำ (Periodic) เช่น การสลับสถานะเอาต์พุตของ LED ที่อัตรา 10 Hz
from machine import Pin, Timer
led = Pin( 25, Pin.OUT ) # use onboard LED
def tick(timer):
global led
led.toggle()
# create the hardware timer object
timer = Timer(-1)
# configure the timer object, 10Hz tick rate, periodic mode
timer.init( freq=10, mode=Timer.PERIODIC, callback=tick )
try:
while True:
pass
except KeyboardInterrupt:
pass
timer.deinit()
โค้ดตัวอย่างที่ 6: LED Blink Using a Thread
ตัวอย่างนี้สาธิตการใช้คำสั่ง _thread.start_new_thread() เพื่อสร้าง"เธรด" (Thread)ใหม่ให้ทำงานบน CPU Core อีกอันหนึ่ง โดยให้ทำหน้าที่สลับสถานะลอจิกของ LED ตามข่วงเวลาที่กำหนดไว้
from machine import Pin
import utime as time
import _thread
lock = None
done = False
def led_task(led_pin, n, delay):
global done
lock.acquire()
print( 'LED Task: Thread ID=%d' % _thread.get_ident() )
lock.release()
led = Pin( led_pin, Pin.OUT )
try:
for i in range(2*n):
led.toggle()
time.sleep(delay)
except KeyboardInterrupt:
pass
done = True
lock.acquire()
print('Task done')
lock.release()
# create a lock object
lock = _thread.allocate_lock()
# create a new thread and run it on the second CPU core
# blink the LED on GPIO-25 pin 10 times with 500ms delay time
_thread.start_new_thread( led_task, (25, 10, 0.5) )
try:
lock.acquire()
print( 'Main: Thread ID=%d' %_thread.get_ident() )
lock.release()
while not done:
pass
except KeyboardInterrupt:
pass
finally:
lock.acquire()
print('Main thread done')
lock.release()
from utime import sleep_ms
class BH1750():
"""Micropython BH1750 ambient light sensor driver."""
PWR_OFF = 0x00
PWR_ON = 0x01
RESET = 0x07
CONT_LOWRES = 0x13
CONT_HIRES_1 = 0x10
CONT_HIRES_2 = 0x11
ONCE_HIRES_1 = 0x20
ONCE_HIRES_2 = 0x21
ONCE_LOWRES = 0x23
def __init__(self, bus, addr=0x23):
self.bus = bus
self.addr = addr
self.reset()
def reset(self): # reset sensor
self.on()
self.set_mode(self.RESET)
def off(self): # turn device off
self.set_mode(self.PWR_OFF)
def on(self): # turn device on
self.set_mode(self.PWR_ON)
def set_mode(self, mode): # set sensor mode
self.mode = mode
self.bus.writeto(self.addr, bytes([self.mode]))
def read(self): # read sensor value (luminance in Lux)
sleep_ms(24 if self.mode in (0x13, 0x23) else 180)
data = self.bus.readfrom(self.addr, 2)
factor = 2.0 if self.mode in (0x11, 0x21) else 1.0
return (data[0]<<8 | data[1])/(1.2 * factor)
และโค้ดสาธิตการใช้งานไฟล์ bh1750.py
from machine import Pin, I2C
import utime as time
from bh1750 import BH1750 # import from file bh1750.py
BH1750_ADDR = 0x23
# use I2C1 and GPIO 14,15 for SDA and SCL pins
i2c = I2C( 1, scl=Pin(15), sda=Pin(14), freq=400000 )
print( [hex(addr) for addr in i2c.scan()] )
try:
dev = BH1750(i2c, addr=BH1750_ADDR)
dev.on()
dev.set_mode( BH1750.CONT_HIRES_1 )
while True:
value = int(dev.read()) # read sensor value (luminance in Lux)
text = 'BH1750 (0x{:02x}): '.format(BH1750_ADDR)
text += '{:5d} Lux'.format(value)
print(text)
time.sleep_ms(200)
except KeyboardInterrupt:
pass
import utime as time
from machine import Pin, WDT
print('Press the button on GPIO-16 to enable WDT.')
button = Pin( 16, mode=Pin.IN, pull=Pin.PULL_UP )
time.sleep_ms(1000)
wdt = None
if button.value() == 0:
# enable WDT with timeout of 2000 msec
wdt = WDT(timeout=2000)
# Note that once the WDT is running the timeout cannot be
# changed and it cannot be stopped either.
if wdt is None:
print('WDT is disabled.')
try:
while wdt is not None:
# feed the WDT to prevent it from resetting the system.
print('feed WDT @{} ms'.format( time.ticks_ms() ) )
wdt.feed()
time.sleep(1.0)
except KeyboardInterrupt:
pass
from machine import ADC
import utime as time
sensor_temp = ADC(4) # use on-chip temperature sensor
conversion_factor = 3.3 / 65535 # 3.3V -> 16-bit value
while True:
reading = sensor_temp.read_u16() * conversion_factor
# Typical value: 0.706V at 27 degrees C
# with a slope of -1.721mV (0.001721) per degree.
temperature = 27 - (reading - 0.706)/0.001721
print('On-chip tempreature: {:.2f} deg.C'.format(temperature) )
time.sleep(2.0)
import utime as time
from machine import Pin,ADC
adc_pins = [ 26,27,28,29 ]
adc_units = [ ADC(pin) for pin in adc_pins ]
vsys_adc = adc_units[-1]
try:
values = []
while True:
# read the first 3 ADC inputs
for adc in adc_units[:-1]:
values.append( (adc.read_u16()/65535)*3.3 )
# read the voltage on the VSYS pin
values.append( 3*vsys_adc.read_u16()/65535*3.3 )
print( ['{:.3f}V'.format(v) for v in values] )
values = []
time.sleep(2.0)
except KeyboardInterrupt:
pass
import utime as time
from machine import Pin, UART
# UART0_TX/RX = GPIO-0 / GPIO-1 pins
# UART1 TX/RX = GPIO-4 / GPIO-5 pins
uart = UART(0, baudrate=115200, bits=8, parity=None, stop=1,
tx=Pin(0), rx=Pin(1) )
# (115200, bits=8, parity=None, stop=1, timeout=1000 )
message = 'Hello'
uart.write( bytes( ord(ch) for ch in message) )
time.sleep_ms(1)
if uart.any():
data = uart.read( len(message) )
print( data.decode() )
โค้ดตัวอย่างที่ 14: Rotary Encoder Input
โค้ดตัวอย่างนี้ สาธิตการใช้งานโมดูล Rotary Encoder Switch ซึ่งจะได้สัญญาณดิจิทัล A, B และมีการเปลี่ยนสถานะลอจิกเมื่อมีการหมุนตามเข็มหรือทวนเข็มนาฬิกา (Clockwise / Anti-Clockwise Rotation) นอกจากนั้นแล้ว ยังมีอีกหนึ่งสัญญาณ SW ให้ผลเหมือนกับวงจรกดปุ่มหรือสวิตช์ปุ่มกด
การตรวจสอบดูว่า มีการหมุนเปลี่ยนตำแหน่งหรือไม่ และเปลี่ยนไปในทิศทางใด เราจะใช้อินเทอร์รัพท์เพื่อดูการเปลี่ยนสถานะที่ขา A ทั้งขอบขาขึ้นและขาลง (Both Rising Edge & Falling Edge) ถ้าไม่มีการเปลี่ยนตำแหน่ง สถานะลอจิกของขา A และ B จะเป็น High
เมื่อเกิดเหตุการณ์ในแต่ละครั้ง ก็ทำให้ฟังก์ชันที่เป็น ISR Handler ที่เกี่ยวข้องทำงาน โดยตรวจสอบดูว่า สถานะของขา A และ B เป็นอย่างไร แล้วใช้ในการเพิ่มหรือลดค่าของตัวนับ (Incremental / Decremental Counter)
from machine import Pin, I2C
import utime as time
from sh1106 import *
# use I2C0 and GPIO 16,17 for SDA and SCL pins
i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=400000)
print(i2c.scan())
I2C_ADDR = 0x3C # the I2C address of SH1106 display module
W, H = 128, 64 # the screen size (128 x 64 pixels)
BLACK, WHITE = 0,1
# scan for I2C devices
if I2C_ADDR not in i2c.scan():
raise RuntimeError('OLED SH1106 not found!!!')
# create an SH1106 object
disp = SH1106_I2C( W, H, i2c, addr=I2C_ADDR )
# rotate the screen
disp.rotate( True )
# fill the entire display
disp.fill( BLACK )
# draw a white frame
disp.rect( 0, 0, W, H, WHITE )
# write some text lines (using the default font)
xpos,ypos = 0, 6
text_lines = ["Hi!", "MicroPython", "Raspberry Pi", "RP2040"]
for line in text_lines:
disp.text( '{:^16s}'.format(line), xpos, ypos )
ypos += 12
disp.show() # update the display
time.sleep_ms(1000)
#disp.poweroff()
ฟังก์ชัน send_byte() ใช้สำหรับการส่งข้อมูลขนาดหนึ่งไบต์เท่านั้นไปยัง 74HC595 และเลือกได้ว่าจะเลื่อนข้อมูลออกแบบ MSB First หรือ LSB First
import utime as time
from machine import Pin
load_pin = Pin( 9, Pin.OUT ) # load pin
sda_pin = Pin(11, Pin.OUT ) # serial data
sclk_pin = Pin(10, Pin.OUT ) # serial clock
def send_byte( data, msb_first=False ):
sda_pin.low()
sclk_pin.low()
load_pin.low()
for i in range(8):
# shift-out data to the SDA pin, LSB first
if msb_first:
bit = (data & 0x80) == 0x80
data <<= 1
else:
bit = (data & 0x01) == 0x01
data >>= 1
# send data bit
if bit:
sda_pin.high()
else:
sda_pin.low()
# send a clock pulse
sclk_pin.high()
sclk_pin.low()
# send a pulse to load pin
load_pin.high()
load_pin.low()
for data in [0x00,0x01,0x81,0x42,0x24,0x18,0x55,0xaa,0xff]:
send_byte( data ^ 0xff, True ) # MSB first, use inverted bits
time.sleep(0.5)