iT邦幫忙

2024 iThome 鐵人賽

DAY 10
0
Python

在AWS上進行物聯網與人工智慧實作系列 第 10

D10-使用 MicroPython 控制燈號、撰寫 ISR - machine

  • 分享至 

  • xImage
  •  

使用 MicroPython 控制燈號、撰寫 ISR - machine

目錄

MicroPython 特定模組

因為MicroPython主要是應用在單晶片上,所以與硬體有關的模組,需要根據不同的硬體來提供不同的實現的方式,以下是常見的特定模組功能。

  • bluetooth — 低級藍牙
  • btree – 簡單的 BTree 數據庫
  • cryptolib——加密密碼
  • framebuf — 幀緩衝區操作
  • machine — 與硬體相關的函數
  • micropython – 訪問和控制 MicroPython 內部
  • network — 網絡配置
  • ntptime --- 時間同步

machine - 與硬體相關的功能

該 machine 模組包含與特定電路板上的硬體相關的特定功能。該模組中的大多數功能允許直接和不受限制地訪問和控制系統上的硬體塊(如CPU,定時器,總線等)。使用不當,可能導致故障,鎖定,電路板崩潰,以及在極端情況下硬體損壞。
以下是與硬體相關的類別:

  • Pin -- 控制 I/O 針腳
  • ADC -- 模數轉換
  • TouchPad -- 觸摸面板
  • PWM -- 脈衝寬度調制
  • UART -- 雙工串行通信總線
  • I2C -- 雙線串行協定
  • SPI -- 串行外設接口總線協定 (主端)
  • Timer -- 控制硬體定時器
  • RTC -- 即時時鐘
  • WDT -- 看門狗定時器

Pin -- 控制 I/O 針腳

針腳對象用於控制 I/O 針腳(也稱為GPIO - 通用輸入/輸出)。針腳對象通常與可以驅動輸出電壓和讀取輸入電壓的物理針腳相關聯。 針腳類具有設置針腳模式(IN,OUT等)的方法以及獲取和設置數位邏輯電平的方法。通過使用明確指定某個 I/O 針腳的識別碼來構造針腳對象。允許的識別碼形式和識別碼映射到的物理針腳是特定於端口的。識別碼的可能性是整數,字串或具有端口和針腳號的元組。

ESP32-CAM 內建有兩個發光二極管(light-emitting diode, 以下簡稱 LED)外設,分別是接在通用型之輸入輸出 (General-purpose input/output, 以下簡稱 GPIO) 4, 33,一個是閃光燈 LED,一個是紅燈 LED。以下示例代碼為針對 I/O 針腳 33 進行輸出 (output) 操作。因為針腳 33在 ESP32-CAM 中視對應到它的紅色LED燈,而這個裝置是低電壓的時候會觸動,高電壓是關閉。

參考代碼

from machine import Pin

# create an output pin on pin #33
p0 = Pin(33, Pin.OUT)

# set the value low then high
# 打開 ESP32-CAM 的紅色LED
p0.value(0)
# 關閉 ESP32-CAM 的紅色LED
p0.value(1)

class Pin.Pin(id, mode=1, pull=1, value, drive, alt)
訪問與給定相關的針腳外設(GPIO針腳) id 。如果在構建對象中給出了其他參數,則它們用於初始化針腳。 未指定的任何設置將保持其先前的狀態。

參數:

  • id 是強制性的,可以是任意對象。可能的值類型包括:int(內部針腳識別碼),str(針腳名稱)和元組([port,pin]對)。如是使用mPython,可用Pin.P(0~20),例如(Pin.P0)P0針腳提供映射為GPIO。
  • mode 指定針腳模式,可以是以下之一:
    • Pin.IN - 針腳配置為輸入。如果將其視為輸出,則針腳處於高阻態。
    • Pin.OUT - 針腳配置為(正常)輸出。
    • Pin.OPEN_DRAIN -針腳配置為開漏輸出。開漏輸出以下列方式工作:如果輸出值設置為0,則針腳處於低電平有效; 如果輸出值為1,則針腳處於高阻態。並非所有端口都實現此模式,或某些端口可能僅在某些針腳上實現。
    • Pin.ALT_OPEN_DRAIN - 針腳配置為漏極開路。
  • pull 指定針腳是否連接了(弱)拉電阻,可以是以下之一:
    • None - 無上拉或下拉電阻
    • Pin.PULL_UP - 上拉電阻使能
    • Pin.PULL_DOWN - 下拉電阻使能
  • value 僅對 Pin.OUT 和 Pin.OPEN_DRAIN 模式有效,並指定初始輸出針腳值,否則針腳外設的狀態保持不變。

Pin.on()
設置針腳為高電平

Pin.off()
設置針腳為低電平

PWM -- 脈衝寬度調制

machine.PWM(pin, freq, duty)
創建與設定針腳關聯的 PWM 對象。這樣就可以寫該針腳上的模擬值。

  • pin: 支持 PWM 的針腳 GPIO0、GPIO2、GPIO4、GPIO5、GPIO10、GPIO12~19、GPIO21、GPIO22、GPIO23、GPIO25~27。詳見 ESP32針腳功能表.
  • freq: 頻率,0 < freq <= 78125 Hz,代表充電頻率,數值低的話會閃爍,數值高的話高源比較穩定。
  • duty: 佔空比, 0 ≤ duty ≤ 0x03FF (十進制:0 ≤ duty ≤ 1023),代表亮度,數值越高,越亮。

PWM.init(freq, duty)
初始化 PWM的 freq 與 duty。

PWM.freq([freq_val])
當沒有參數時,函數獲得並返回PWM頻率。當設置參數時,函數用來設置PWM頻率,無返回值。

PWM.deinit()
關閉PWM。PWM使用完了之後,需要註銷 deinit() 。

以下示例代碼為針對 I/O 針腳 4,白色 LED 燈進行脈衝寬度調制操作,而這個裝置是高電壓的時候會觸動,低電壓是關閉,取得原始頻率,並改為 10,暫停 5 秒,觀察改變後效果,再設定 duty 為 5 ,暫停 5 秒,觀察改變後效果,最後關閉PWM。

參考代碼

from machine import Pin, PWM
import time
pwm = PWM(Pin(4))         # create PWM object from a pin
print(pwm.freq())          # get current frequency (default 5kHz)
time.sleep(5)
pwm.freq(10)            # set PWM frequency from 1Hz to 40MHz
time.sleep(5)

print(pwm.duty())         # get current duty cycle, range 0-1023 (default 512, 50%)
pwm.duty(5)             # set duty cycle from 0 to 1023 as a ratio duty/1023, (now 25%)
time.sleep(5)
pwm.deinit()

輸出結果為:

5000
512

Timer 計時器

在合適的硬體上,MicroPython 提供了用 Python 編寫中斷處理程序的能力。中斷處理程序——也稱為中斷服務程序 (ISR)——被定義為回調函數。這些是為了響應諸如定時器觸發引腳上的電壓變化之類的事件而執行的。此類事件可能發生在程序代碼執行過程中的任何一點。這會帶來重大後果,其中一些是 MicroPython 語言特有的。其他的對於能夠響應實時事件的所有系統都是通用的。

定時器與引腳觸發示例

from machine import Timer, Pin
# 緊急異常緩衝區
import micropython
micropython.alloc_emergency_exception_buf(100)
# LED狀態反轉
def toggle_led(led_pin):
    led_pin.value(not led_pin.value())

def led_blink_timed(timer, led_pin, millisecond):
    '''
    led 按照特定的頻率進行閃爍
    LED閃爍週期 = 1000ms / 頻率
    狀態變換間隔(period) = LED閃爍週期/ 2 
    '''
    # 計算狀態變換間隔時間 ms
    period = int(0.5 * millisecond)
    # 初始化定時器
    # 這裡回調是使用了lambada表達式,因為回調函數需要傳入led_pin
    timer.init(period=period, mode=Timer.PERIODIC, callback=lambda t: toggle_led(led_pin))


# 聲明引腳 D2 作為LED的引腳
led_pin = Pin(33, Pin.OUT)
timer = Timer(1)  # 創建定時器對象
# 定時器觸發
led_blink_timed(timer, led_pin, millisecond=500)
# 引腳上的電壓變化觸發
led_pin.irq(trigger=Pin.IRQ_FALLING, handler=lambda t:print("IRQ_FALLING"))

參考資料


上一篇
D09-使用 MicroPython 檔案存取 - io
下一篇
D11-使用 MicroPython 連接 Wi-Fi、同步 NTP
系列文
在AWS上進行物聯網與人工智慧實作30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言