การทำงานของโปรแกรมจะทำให้ LED กระพริบ และมีการตรวจสอบสถานะอินพุตของปุ่มกด ถ้าพบว่า มีการกดปุ่ม (ได้ค่าเป็น 0) จะหยุดการทำงานของลูป while และจบการทำงานของโปรแกรม
from micropython import constfrom machine import Pinimport utime as timeLED_GPIO =const(21)# use GPIO-21 for LED outputBTN_GPIO =const(22)# use GPIO-22 for push-button input# create an object for the LED pinled =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 statetry: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 secondsexceptKeyboardInterrupt:passfinally: led.value(0)# turn off the LEDprint('Done')
โค้ดตัวอย่างที่ 2: LED Blink + Push Button (Interrupt-Driven)
from micropython import constfrom machine import Pinimport utime as timeLED_GPIO =const(21)# use GPIO-21 for LED outputBTN_GPIO =const(22)# use GPIO-22 for push-button input# create objects from machine.Pinled =Pin( LED_GPIO, mode=Pin.OUT )btn =Pin( BTN_GPIO, mode=Pin.IN, pull=Pin.PULL_UP )defbtn_handler(pin): # callback functionglobal stop args = (pin, pin.value())print( 'callback: {} value={}'.format(*args) ) stop =True# enable interrupt handler for Button pinbtn.irq( handler=btn_handler, trigger=Pin.IRQ_FALLING )stop =False# loop condition variablestate =False# LED statetry:whilenot stop: state =not state # toggle state led.value( state )# write value to output pin time.sleep_ms( 100 )# sleep for 100 msecexceptKeyboardInterrupt:passfinally: btn.irq( handler=None )# disable interrupt for button pin led.value(0)# turn off the LEDprint('Done')
โค้ดตัวอย่างที่ 3: LED Toggle on Button Press
โค้ดตัวอย่างถัดไปสาธิตการทำให้ LED เปลี่ยนสถานะเอาต์พุตหนึ่งครั้งเมื่อมีการกดปุ่มการทำงานของโค้ดจะอาศัยการเปิดใช้งานอินเทอร์รัพท์ที่ขาอินพุต (ตรวจสอบเหตุการณ์ขอบขาลง) และมีการสร้างฟังก์ชัน btn_handler() ให้ทำหน้าที่เป็น Callback Function
from micropython import constfrom machine import Pin, Timerimport utime as timeBTN_GPIO =const(22)# use GPIO-22 for push-button inputLED_GPIO =const(21)# use GPIO-21 for LED outputled =Pin( LED_GPIO, mode=Pin.OUT )btn =Pin( BTN_GPIO, mode=Pin.IN, pull=Pin.PULL_UP )defled_toggle(timer): # callback function for timerglobal led# show elapsed system time in msecprint( '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 looptry:whileTrue:# check whether button is pressedif btn.value()==0:break time.sleep_ms(10)exceptKeyboardInterrupt:passled.value(0)# turn off LEDtimer.deinit()# stop timerprint('Done')
from micropython import constfrom machine import Pin, Timerimport utime as timeimport _thread # for multi-threadingLED_GPIO =const(21)# use GPIO-21 for LED outputBTN_GPIO =const(22)# use GPIO-22 for push-button inputbtn =Pin( BTN_GPIO, mode=Pin.IN, pull=Pin.PULL_UP )led =Pin( LED_GPIO, mode=Pin.OUT )stop =False# used as a global variabledefled_toggle(led): # thread functionglobal stop state =0whilenot stop: state =not stateprint( '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,) )defstop_led_blink(timer): # callback function for timerglobal stop stop =Truetimer =Timer( 0 )# create a Timer object# start the timer in one-shot modetimer.init( period=5000, mode=Timer.ONE_SHOT, callback=stop_led_blink )# Press the button to stop and exit the loopwhilenot stop:# check whether button is pressedif btn.value()==0: stop =Truebreak time.sleep_ms(10)led.value(0)# turn off LEDtimer.deinit()# stop timerprint('Done')
from micropython import constfrom machine import Pin, PWMimport utime as timeimport mathLED_GPIO =const(21)# use GPIO-21 for LED outputBTN_GPIO =const(22)# use GPIO-22 for push-button inputbtn =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 pinpwm =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 valuesvalues = [int(1023*math.sin(math.pi*i/N))for i inrange(N)]try: i =0whileTrue: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 )exceptKeyboardInterrupt:passpwm.duty(0)# set duty cycle to 0pwm.deinit()# important: turn off the PWM pinprint('Done')
ในตัวอย่างนี้ มีการคำนวณค่าคงตัวโดยใช้ฟังก์ชัน math.sin() และเก็บไว้ในอาร์เรย์ที่มีขนาดเท่ากับ N (N=32) แล้วนำไปใช้เพื่อกำหนดค่า Duty Cycle ทีละค่าตามลำดับในอาร์เรย์
เมื่อทดสอบการทำงานของโค้ดตัวอย่างกับอุปกรณ์จริง จะเห็นการปรับความสว่างของ LED ด้วยสัญญาณแบบ PWM
ข้อสังเกต: เนื่องจากใช้โมดูลที่มี RGB LED เพียงดวงเดียว ดังนั้นเลือกจึงใช้ 3.3V จากบอร์ด ESP32 เป็นแหล่งจ่ายแรงดันคงที่ได้ แต่ถ้าใช้ RGB LED จำนวนหลายดวงและอาจใช้กระแสไฟมาก ควรใช้แหล่งจ่ายแรงดันคงที่จากภายนอก
from micropython import constfrom machine import Pinimport utime as timefrom neopixel import NeoPixelGPIO_NUM =const(23)# use GPIO-23np_pin =Pin( GPIO_NUM, Pin.OUT )# for Neopixel outputBTN_GPIO =const(22)# use GPIO-22 for push-button inputbtn =Pin( BTN_GPIO, mode=Pin.IN, pull=Pin.PULL_UP )stop =Falsedefbtn_callback(pin):global stop stop =Truebtn.irq( trigger=Pin.IRQ_FALLING, handler=btn_callback )NUM_PIXELS =1# only one RGB LED in the strip# create a Neopixel objectnp =NeoPixel( np_pin, NUM_PIXELS )# convert an integer to a 3-tuple object for RGB valueint2rgb =lambdax: ((x >>16)&0xff,(x>>8)&0xff,(x)&0xff)# a list of predefined RGB color valuescolors = [ (255,0,0), (0,255,0), (0,0,255) ]colors += [ int2rgb(0xffff00),int2rgb(0xff00ff),int2rgb(0x00ffff) ]colors +=3*[ (0,0,0) ] # RGB off, 3 timesprint( colors)try:whilenot 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)exceptKeyboardInterrupt:passnp[0]= (0,0,0) # turn off color (black)np.write()print('Done')
from micropython import constfrom machine import Pin, ADCimport utime as timeADC_GPIO =const(34)# use GPIO-34 for ADC input channeladc =ADC(Pin(ADC_GPIO),unit=1)# create an ADC objectadc.atten(ADC.ATTN_11DB)# set 11dB attenuation for inputadc.width(ADC.WIDTH_12BIT)# set 12 bit return valuesNUM_SAMPLES =const(4)for i inrange(20):# repeat 20 times samples = []for j inrange(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 constfrom machine import Pin, ADC, DACimport utime as timeADC_GPIO =const(34)# use GPIO-34 for ADC input channeladc =ADC(Pin(ADC_GPIO))# create an ADC objectadc.atten(ADC.ATTN_11DB)# set 11dB attenuation for inputadc.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 DACNUM_SAMPLES =const(4)text ='DAC:{:4d} -> ADC:{:5d}'for value inrange(255): dac.write( value ) time.sleep_us(100) samples = []for j inrange(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 constfrom machine import Pin, PWM, time_pulse_usimport utime as timePWM_OUT_GPIO =const(19)PULSE_IN_GPIO =const(23)freq =1000# in Hzpwm_pin =Pin( PWM_OUT_GPIO, mode=Pin.OUT )# create an object from PWM for output pinpwm =PWM( pwm_pin, freq=freq, duty=0 )time.sleep_us(10)pwm_freq = pwm.freq()pwm_period =10**6//pwm_freq # in usecprint ('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 cyclefor i inrange(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 lowwhile 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 valueprint( 'Pulse width: {:4d},{:4d} usec'.format(p,t) )pwm.deinit()print('Done')
import machineimport ubinasciiimport network# get the machine ID (MAC address of ESP32)machine_id = machine.unique_id()hex_id = ubinascii.hexlify( machine_id,':' )print( hex_id.decode('ascii') )# get the MAC address of ESP32mac_addr = network.WLAN().config('mac')hex_addr = ubinascii.hexlify( mac_addr,':' )print( hex_addr.decode('ascii') )
from micropython import constfrom machine import UARTimport mathTX =const(2)# use GPIO-2 for TXDRX =const(15)# use GPIO-15 for RXDid=1uart =UART(id, tx=TX, rx=RX, baudrate=115200, timeout=1000)N =512A =100for i inrange(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 constfrom machine import UARTimport mathTX =const(2)# use GPIO-2 for TXDRX =const(15)# use GPIO-15 for RXDid=2uart =UART(id, tx=TX, rx=RX, baudrate=115200, parity=None, stop=1, timeout=1000)try:whileTrue: line = uart.readline()# read next lineif line:# if line is not Noneprint( line.decode().strip() ) uart.write( line )# send backexceptKeyboardInterrupt:passuart.deinit()
from micropython import constfrom machine import UARTimport mathTX =const(2)# use GPIO-2 for TXDRX =const(15)# use GPIO-15 for RXDid=2uart =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)whileTrue: 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 backexceptKeyboardInterrupt:passuart.deinit()
import machine, utimefrom sh1106 import*# https://github.com/robert-hh/SH1106/blob/master/sh1106.pyimport timei2c_bus =0# use either I2C bus 0 or 1i2c = machine.I2C( i2c_bus, freq=400000, scl=machine.Pin(22), sda=machine.Pin(21) )I2C_ADDR =0x3CW, H =128,64BLACK, WHITE =0,1# scan for I2C devicesif0x3Cnotin i2c.scan():raiseRuntimeError('OLED SH1106 not found!!!')display =SH1106_I2C(W, H, i2c, addr=I2C_ADDR)display.rotate(True)# fill the entire displaydisplay.fill( BLACK )display.rect(0, 0, W, H, WHITE )# write some text lines (using the default font)xpos,ypos =0,4text_lines = ["Hi!","MicroPython","ESP32"]for line in text_lines: display.text( '{:^16s}'.format(line), xpos, ypos ) ypos +=10display.show()# update the display time.sleep_ms(1000)display.poweroff()print('Done')
เผยแพร่ภายใต้ลิขสิทธิ์
Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)