การทำงานของโปรแกรมจะทำให้ LED กระพริบ และมีการตรวจสอบสถานะอินพุตของปุ่มกด ถ้าพบว่า มีการกดปุ่ม (ได้ค่าเป็น 0) จะหยุดการทำงานของลูป while และจบการทำงานของโปรแกรม
from micropython import const
from machine import Pin
import utime as time
LED_GPIO = const(21) # use GPIO-21 for LED output
BTN_GPIO = const(22) # use GPIO-22 for push-button input
# create an object for the LED pin
led = Pin( LED_GPIO, mode=Pin.OUT )
# create an object for button pin (with pull-up enabled)
btn = Pin( BTN_GPIO, mode=Pin.IN, pull=Pin.PULL_UP )
state = False # used to keep the output state
try:
while btn.value() != 0: # check input button
state = not state # toggle state
led.value( state ) # write value to output pin
time.sleep_ms(100) # sleep for 0.1 seconds
except KeyboardInterrupt:
pass
finally:
led.value(0) # turn off the LED
print('Done')
โค้ดตัวอย่างที่ 2: LED Blink + Push Button (Interrupt-Driven)
from micropython import const
from machine import Pin
import utime as time
LED_GPIO = const(21) # use GPIO-21 for LED output
BTN_GPIO = const(22) # use GPIO-22 for push-button input
# create objects from machine.Pin
led = Pin( LED_GPIO, mode=Pin.OUT )
btn = Pin( BTN_GPIO, mode=Pin.IN, pull=Pin.PULL_UP )
def btn_handler(pin): # callback function
global stop
args = (pin, pin.value())
print( 'callback: {} value={}'.format(*args) )
stop = True
# enable interrupt handler for Button pin
btn.irq( handler=btn_handler, trigger=Pin.IRQ_FALLING )
stop = False # loop condition variable
state = False # LED state
try:
while not stop:
state = not state # toggle state
led.value( state ) # write value to output pin
time.sleep_ms( 100 ) # sleep for 100 msec
except KeyboardInterrupt:
pass
finally:
btn.irq( handler=None ) # disable interrupt for button pin
led.value(0) # turn off the LED
print('Done')
โค้ดตัวอย่างที่ 3: LED Toggle on Button Press
โค้ดตัวอย่างถัดไปสาธิตการทำให้ LED เปลี่ยนสถานะเอาต์พุตหนึ่งครั้งเมื่อมีการกดปุ่มการทำงานของโค้ดจะอาศัยการเปิดใช้งานอินเทอร์รัพท์ที่ขาอินพุต (ตรวจสอบเหตุการณ์ขอบขาลง) และมีการสร้างฟังก์ชัน btn_handler() ให้ทำหน้าที่เป็น Callback Function
from micropython import const
from machine import Pin, Timer
import utime as time
BTN_GPIO = const(22) # use GPIO-22 for push-button input
LED_GPIO = const(21) # use GPIO-21 for LED output
led = Pin( LED_GPIO, mode=Pin.OUT )
btn = Pin( BTN_GPIO, mode=Pin.IN, pull=Pin.PULL_UP )
def led_toggle(timer): # callback function for timer
global led
# show elapsed system time in msec
print( 'timer ticks: {} msec'.format(time.ticks_ms()) )
led.value( not led.value() ) # toggle LED
timer = Timer( -1 ) # create a Timer object
# use the timer in periodic mode (period = 500 msec)
timer.init( period=500,
mode=Timer.PERIODIC,
callback=led_toggle )
# Press the button to stop and exit the loop
try:
while True:
# check whether button is pressed
if btn.value() == 0:
break
time.sleep_ms(10)
except KeyboardInterrupt:
pass
led.value(0) # turn off LED
timer.deinit() # stop timer
print('Done')
from micropython import const
from machine import Pin, Timer
import utime as time
import _thread # for multi-threading
LED_GPIO = const(21) # use GPIO-21 for LED output
BTN_GPIO = const(22) # use GPIO-22 for push-button input
btn = Pin( BTN_GPIO, mode=Pin.IN, pull=Pin.PULL_UP )
led = Pin( LED_GPIO, mode=Pin.OUT )
stop = False # used as a global variable
def led_toggle(led): # thread function
global stop
state = 0
while not stop:
state = not state
print( 'LED state: {}'.format( int(state) ))
led.value(state) # update LED output
time.sleep_ms(100) # sleep for 0.1 seconds
# create and start a new thread
_thread.start_new_thread( led_toggle, (led,) )
def stop_led_blink(timer): # callback function for timer
global stop
stop = True
timer = Timer( 0 ) # create a Timer object
# start the timer in one-shot mode
timer.init( period=5000,
mode=Timer.ONE_SHOT,
callback=stop_led_blink )
# Press the button to stop and exit the loop
while not stop:
# check whether button is pressed
if btn.value() == 0:
stop = True
break
time.sleep_ms(10)
led.value(0) # turn off LED
timer.deinit() # stop timer
print('Done')
from micropython import const
from machine import Pin, PWM
import utime as time
import math
LED_GPIO = const(21) # use GPIO-21 for LED output
BTN_GPIO = const(22) # use GPIO-22 for push-button input
btn = Pin( BTN_GPIO, mode=Pin.IN, pull=Pin.PULL_UP )
led = Pin( LED_GPIO, mode=Pin.OUT )
# create an object from PWM for the LED pin
pwm = PWM( led, freq=500, duty=0 )
time.sleep_us(10)
print ('PWM freq: {} Hz'.format( pwm.freq() ))
N = const(32)
# create a list of precomputed duty-cyle values
values = [int(1023*math.sin(math.pi*i/N)) for i in range(N)]
try:
i = 0
while True:
if btn.value() == 0: # is button pressed ?
break
value = values[i]
pwm.duty( value ) # set the duty cycle value
percent = 100*( pwm.duty()/1024.0 )
print( 'Duty cycle: {:4d} ({:4.1f}%)'.format(value, percent) )
i = (i+1) % N
time.sleep_ms( 50 )
except KeyboardInterrupt:
pass
pwm.duty(0) # set duty cycle to 0
pwm.deinit() # important: turn off the PWM pin
print('Done')
ในตัวอย่างนี้ มีการคำนวณค่าคงตัวโดยใช้ฟังก์ชัน math.sin() และเก็บไว้ในอาร์เรย์ที่มีขนาดเท่ากับ N (N=32) แล้วนำไปใช้เพื่อกำหนดค่า Duty Cycle ทีละค่าตามลำดับในอาร์เรย์
เมื่อทดสอบการทำงานของโค้ดตัวอย่างกับอุปกรณ์จริง จะเห็นการปรับความสว่างของ LED ด้วยสัญญาณแบบ PWM
ข้อสังเกต: เนื่องจากใช้โมดูลที่มี RGB LED เพียงดวงเดียว ดังนั้นเลือกจึงใช้ 3.3V จากบอร์ด ESP32 เป็นแหล่งจ่ายแรงดันคงที่ได้ แต่ถ้าใช้ RGB LED จำนวนหลายดวงและอาจใช้กระแสไฟมาก ควรใช้แหล่งจ่ายแรงดันคงที่จากภายนอก
from micropython import const
from machine import Pin
import utime as time
from neopixel import NeoPixel
GPIO_NUM = const(23) # use GPIO-23
np_pin = Pin( GPIO_NUM, Pin.OUT ) # for Neopixel output
BTN_GPIO = const(22) # use GPIO-22 for push-button input
btn = Pin( BTN_GPIO, mode=Pin.IN, pull=Pin.PULL_UP )
stop = False
def btn_callback(pin):
global stop
stop = True
btn.irq( trigger=Pin.IRQ_FALLING,
handler=btn_callback )
NUM_PIXELS = 1 # only one RGB LED in the strip
# create a Neopixel object
np = NeoPixel( np_pin, NUM_PIXELS )
# convert an integer to a 3-tuple object for RGB value
int2rgb = lambda x: ((x >> 16)&0xff,(x>>8)&0xff,(x)&0xff)
# a list of predefined RGB color values
colors = [ (255,0,0), (0,255,0), (0,0,255) ]
colors += [ int2rgb(0xffff00),
int2rgb(0xff00ff),
int2rgb(0x00ffff) ]
colors += 3*[ (0,0,0) ] # RGB off, 3 times
print( colors)
try:
while not stop:
for color in colors:
if stop:
break
# set color value to the first RGB LED
np[0] = color
# apply the color value
np.write()
time.sleep_ms(1000)
except KeyboardInterrupt:
pass
np[0] = (0,0,0) # turn off color (black)
np.write()
print('Done')
from micropython import const
from machine import Pin, ADC
import utime as time
ADC_GPIO = const(34) # use GPIO-34 for ADC input channel
adc = ADC(Pin(ADC_GPIO),unit=1) # create an ADC object
adc.atten(ADC.ATTN_11DB) # set 11dB attenuation for input
adc.width(ADC.WIDTH_12BIT) # set 12 bit return values
NUM_SAMPLES = const(4)
for i in range(20): # repeat 20 times
samples = []
for j in range(NUM_SAMPLES):
samples.append( adc.read() )
# calcuate the average value from N samples
value_avg = round(sum(samples)/NUM_SAMPLES)
print( 'ADC: {:4d}'.format(value_avg))
time.sleep_ms(200)
print('Done')
from micropython import const
from machine import Pin, ADC, DAC
import utime as time
ADC_GPIO = const(34) # use GPIO-34 for ADC input channel
adc = ADC(Pin(ADC_GPIO)) # create an ADC object
adc.atten(ADC.ATTN_11DB) # set 11dB attenuation for input
adc.width(ADC.WIDTH_10BIT) # set 10 bit return values
# GPIO25 (Channel 2) and GPIO26 (Channel 1)
DAC_NUM = const(26) # GPIO26
dac = DAC( Pin(DAC_NUM) ) # 8-bit DAC
NUM_SAMPLES = const(4)
text = 'DAC:{:4d} -> ADC:{:5d}'
for value in range(255):
dac.write( value )
time.sleep_us(100)
samples = []
for j in range(NUM_SAMPLES):
samples.append( adc.read() )
# calcuate the average value from N samples
value_avg = round(sum(samples)/NUM_SAMPLES)
print( text.format(value, value_avg) )
print('Done')
โค้ดตัวอย่างที่ 11: Pulse Width Measurement
ตัวอย่างถัดไปสาธิตการวัดความกว้างของพัลส์ช่วงที่เป็น High โดยใช้คำสั่ง machine.time_pulse_us() และสร้างสัญญาณ PWM เพื่อใช้ในการทดสอบ
from micropython import const
from machine import Pin, PWM, time_pulse_us
import utime as time
PWM_OUT_GPIO = const(19)
PULSE_IN_GPIO = const(23)
freq = 1000 # in Hz
pwm_pin = Pin( PWM_OUT_GPIO, mode=Pin.OUT )
# create an object from PWM for output pin
pwm = PWM( pwm_pin, freq=freq, duty=0 )
time.sleep_us(10)
pwm_freq = pwm.freq()
pwm_period = 10**6//pwm_freq # in usec
print ('PWM freq: {:6d} Hz'.format( pwm_freq ))
print ('PWM period: {:6d} usec'.format( pwm_period ))
pulse_in = Pin( PULSE_IN_GPIO )
N = 10 # total steps for the PWM duty cycle
for i in range(1,N):
p = pwm_period*i//N # pulse with in usec
pwm.duty( 1023*p//pwm_period ) # set duty cycle
time.sleep_us( 2*pwm_period )
# wait until the input signal goes low
while pulse_in.value()==1: pass
# measure the next high pulse width
t = time_pulse_us( pulse_in, 1, pwm_period )
# show the set value against the measured value
print( 'Pulse width: {:4d},{:4d} usec'.format(p,t) )
pwm.deinit()
print('Done')
from micropython import const
from machine import UART
import math
TX = const(2) # use GPIO-2 for TXD
RX = const(15) # use GPIO-15 for RXD
id = 1
uart = UART(id, tx=TX, rx=RX,
baudrate=115200, timeout=1000)
N = 512
A = 100
for i in range(N): # repeat N times
x = A*(math.sin(2*math.pi*i/N))
uart.write('{}\n'.format( round(x)) )
uart.deinit()
print('Done')
ถ้าใช้โปรแกรมอย่างเช่น Arduino IDE และเปิดใช้งาน Serial Plotter จะเห็นการแสดงข้อมูลในรูปของกราฟ
from micropython import const
from machine import UART
import math
TX = const(2) # use GPIO-2 for TXD
RX = const(15) # use GPIO-15 for RXD
id = 2
uart = UART(id, tx=TX, rx=RX,
baudrate=115200, parity=None, stop=1,
timeout=1000)
try:
while True:
line = uart.readline() # read next line
if line: # if line is not None
print( line.decode().strip() )
uart.write( line ) # send back
except KeyboardInterrupt:
pass
uart.deinit()
from micropython import const
from machine import UART
import math
TX = const(2) # use GPIO-2 for TXD
RX = const(15) # use GPIO-15 for RXD
id = 2
uart = UART(id, tx=TX, rx=RX,
baudrate=115200, parity=None, stop=1)
BUF_SIZE = const(64)
try:
# create buffer for UART RX
buf = bytearray( BUF_SIZE )
# set timeout to 100 msec
uart.init(timeout=100)
while True:
n = uart.readinto( buf )
if n: # check the number of bytes received
line = buf[:n].decode()
print( line.strip() ) # show line
uart.write( line ) # send back
except KeyboardInterrupt:
pass
uart.deinit()
from machine import TouchPad, Pin
import utime as time
THRESHOLD_LEVEL = 200
pins = [0,4] # use GPIO-0 and GPIO-4 as touchpad pins
touch_pads = [ TouchPad( Pin(p) ) for p in pins ]
stop = False
text = 'Touched, GPIO{}, value={}'
while not stop:
for i,tp in enumerate(touch_pads):
value = tp.read() # read touchpad input
if value < THRESHOLD_LEVEL:
pin = pins[i]
print( text.format(pin,value) )
stop = True
time.sleep_ms(100)
print('Done')
import machine, utime
from sh1106 import *
# https://github.com/robert-hh/SH1106/blob/master/sh1106.py
import time
i2c_bus = 0 # use either I2C bus 0 or 1
i2c = machine.I2C( i2c_bus, freq=400000,
scl=machine.Pin(22), sda=machine.Pin(21) )
I2C_ADDR = 0x3C
W, H = 128,64
BLACK, WHITE = 0,1
# scan for I2C devices
if 0x3C not in i2c.scan():
raise RuntimeError('OLED SH1106 not found!!!')
display = SH1106_I2C(W, H, i2c, addr=I2C_ADDR)
display.rotate(True)
# fill the entire display
display.fill( BLACK )
display.rect(0, 0, W, H, WHITE )
# write some text lines (using the default font)
xpos,ypos = 0, 4
text_lines = ["Hi!", "MicroPython", "ESP32"]
for line in text_lines:
display.text( '{:^16s}'.format(line), xpos, ypos )
ypos += 10
display.show() # update the display
time.sleep_ms(1000)
display.poweroff()
print('Done')
เผยแพร่ภายใต้ลิขสิทธิ์
Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)