類比訊號轉換(ADC)對控制器領域來說是非常重要的機制,它可以將真實世界的訊號,利用數位的方式進行轉換,使其變成系統較易判讀的標準,後續得進行控制或保存。而影響 ADC 的數值的因素眾多,像解析度、輸入電壓範圍等,今天這篇主要來分享如何使用 ADC Function,並針對我們的需求,對相關設定進行調整。
1. ADC Function 使用
MicroPython 在 ESP32 平台上類比訊號轉換可以使用的腳位從 Gpio 32~39,以Nodemcu-32s 來說也就是 Gpio32、33、34、 35、36、39 這六支腳位可以使用,下面為建立 ADC 物件的範例:
from machine import ADC,Pin adc0=ADC(Pin(32)) adc_value=adc0.read()
這邊注意一下,ADC 物件跟 PWM 的類別一樣,因有指定腳位,所以需要同時import Pin 類別,在初始化時需同時指定腳位編號,如果要讀取 ADC 的數值就需要使用到 adc0.read()
這個方法( adc0 為自訂的物件名稱),軟體基本上就可以開始使用。
實務上來說,我們同時還會設定兩個參數,一個輸入的電壓範圍,另一個就是解析度。這兩個參數會決定我們轉換的數值的精度。舉個實際的例子說明,如果有一個輸入訊號,它的輸入範圍是 0-1V,此時如果我們選擇最大 3.3V 的電壓範圍,並採用 9bit 解析度的採樣(也就得到數位值最大511),0-1V 的類比電壓轉換成數位值時的範圍就是 0-155,每一個數位值代表就是 0.006V(3.3/512),這在一般的運用已經是 OK 的,但如果在某些特殊應用想要在提高我們轉換時的精度應該如何做?
很簡單,適當的選擇輸入電壓範圍與解析度 bit,既然我們的類比電壓上限是 1V,所以我們就選擇 1V 的電壓範圍,在搭配上 12bit 的取樣,結果每個數位值就會變成 1/4056=0.00024V,這樣就可以獲得更為精確的電壓轉換值,不過在實務當然要考量的東西更多,並不是一昧的提高就是好,像是現實世界的雜訊、ADC 轉換時間等等,待日後有機會再來分享。回到上述討論的兩個參數,ESP32 也提供了對應的方法可以設定:
- ADC 電壓輸入範圍:這個就是可以設定輸入的電壓範圍,因為 ESP32 的內部類比數入電壓可以接收的範圍就是 1V,所以這邊有提供 4 個將調整外部電壓範圍的設定:ADC.ATTN_0DB、ADC.ATTN_2_5DB、ADC.ATTN_6DB、ADC.ATTN_11DB,可以參考 MicorPython 官網的ADC使用說明 來進行調整,程式方法如下:
adc0.atten(ADC.ATTN_11DB)
- ADC取樣解析度:一樣有4種參數可以設定 ADC.WIDTH_9BIT、ADC.WIDTH_10BIT、ADC.WIDTH_11BIT、ADC.WIDTH_12BIT,設定的方法為
adc0.width(ADC.WIDTH_9BIT)
2. 電路接法
現在我們來實際利用一個簡單的可變電阻來進行實驗,或者可找一個輸出類比電壓上限為 3.3V 的感測器模組也行,記得 ESP32 硬體的腳位上限電壓是 3.6V,超過就會損壞IC腳位(而且通常是不可恢復的),下面為利用可變電阻的實驗範例:(利用 Gpio32 讀取電壓)
3. 程式功能
這次我們練習一個簡單的功能,利用 Gpio32 讀取可變電阻的分壓,當電壓低於0.8V 時,開啟 ESP32 模組內建的 LED(Gpio2),分壓大於 0.8V 時就關閉 LED,這個應用其實就是類似小夜燈的概念,把可變電阻換成光敏電阻的模組即可。
from machine import ADC,Pin import time adc0=ADC(Pin(32)) adc0.atten(ADC.ATTN_11DB) led0=Pin(2,Pin.OUT) try: while 1: adc_val=(adc0.read()/4095*3.3) if adc_val>0.8: led0.value(0) else: led0.value(1) print('{}v'.format(adc_val)) time.sleep(0.5) except Exception as e: print(e)
> 程式講解
from machine import ADC,Pin import time adc0=ADC(Pin(32)) adc0.atten(ADC.ATTN_11DB) led0=Pin(2,Pin.OUT)
匯入 machine 的 ADC、Pin 模組,並建立 Gpio32 的類比轉換物件 adc0,設定該腳位的輸入電壓上限為 3.6V,JIMI哥沒有設定 ADC 的解析度是因為預設為 12 bit輸出值(adc0.width(ADC.WIDTH_12BIT)
)。同時將 Gpio2 設為 output 輸出。
while 1: adc_val=(adc0.read()/4095*3.3) if adc_val>0.8: led0.value(0) else: led0.value(1) print('{}v'.format(adc_val)) time.sleep(0.5)
在 while 的主要迴圈內,第 9 行讀取該腳位的轉換值後,將其轉換成實際的電壓值放入 adc_val 這個變數內;第 10-13 行判斷電壓的準位決定是否點亮 LED 或關閉,接續程式碼每隔 0.5 秒印出目前的電壓值。
4. 結語
ADC 可以應用的範圍廣泛,像光敏電阻、聲音感測模組等,數值取樣進控制器後,也可以搭配所謂的演算法濾波,實踐純硬體較難實現的功能,而 ESP32 目前可以提供 6 支腳位可以進行類比轉換功能,一般應用應該足夠,如果不夠的話,也可以用所謂外接ADC IC 透過 I2C 或 SPI 通訊協定進行擴充也是可以的,今天這篇就先分享到這邊,如果各位朋友實驗上有遇到任何問題,歡迎下面留言討論,謝謝囉!
↓↓↓↓↓↓賣場連結↓↓↓↓↓↓
歡迎大家有需要的話,可以多多支持一下我們的蝦皮賣場喔! 😀
吉米家官方店-創客機器人材料專賣 https://shopee.tw/jimirobot.tw
Follow JIMI哥 Twitter : https://twitter.com/jimirobot <–得到最新文章通知