2022年12月14日 星期三

Witty Cloud ESP8266 開發板測試 (二) : 光敏電阻

這塊 Witty Cloud 去年底買來已一年了, 只測試過 RGB 全彩 LED, 最近在測試 MicroPython 常用到, 所以想先把板載的感測器都測過一遍. 此板是去年在 Aliexpress 買的, 當時買了 10 塊, 平均一塊板子才 59 元 (含 USB 底板), 算是非常便宜的 ESP8266 板子, 規格與 D1 mini 類似 (4MB Flash), 但多了全彩 LED, 光敏電阻, 與按鈕開關這三個板載模組, CP 值比 D1 mini 高很多, 參考 :


本篇要測試的是板載的光敏電阻 (light dependant resistor, 或 CdS), 其位置是在 PCB 天線的左邊 (另一邊是全彩 LED), 此光敏電阻一端串接分壓電阻, 另一端接到 ESP8266 的唯一類比輸入端 A0 腳, 此腳內部是一個 ADC (Analog-Digital Conversion) 電路, 可將 0~3.3 伏的類比輸入電壓用 10 bit 解析度轉成 0~1024 的整數 (2*10=1024), 數值越大表示輸入 A0 腳的電壓越高, 也表示光敏電阻的電阻越低, 也就是亮度越大 : 




從 A0 腳讀取數位化後的整數值要用到 machine 模組裡的 ADC 類別, 先用 import 匯入 :

from machine import ADC

然後呼叫類別建構函式 ADC() 並傳入 Pin 腳編號 (此處為 0) 建立 ADC 物件, 然後呼叫其 read() 方法即可取得 ADC 的輸出 :

MicroPython v1.19.1 on 2022-06-18; ESP module with ESP8266

Type "help()" for more information.
>>> from machine import ADC   
>>> adc=ADC(0)      
>>> type(adc)   
<class 'ADC'>   

這樣就建立了一個 ADC 物件, 用 help 檢查其內容 : 

>>> help(adc)    
object ADC(0) is of type ADC
  read_u16 -- <function>
  read -- <function>

其中的 read() 方法就是用來讀取 ADC 轉換後得到的十進位整數值, 可連續呼叫得到即時的

>>> adc.read()   
50
>>> adc.read()   
173
>>> adc.read()   
356

這是調整開發板位置使光敏電阻接受到不同的光線照射, 越亮數值越大, 越暗數值越小. 

以下參考之前用 ESP-12S 開發板做的測試在 Witty Cloud 上重做一遍, 參考 :
下列範例使用迴圈來連續讀取代表亮度的 ADC 轉換輸出, 為了不讓數字跳動太迅速使用 time (或 utime) 模組的 sleep() 函式來暫停幾秒 : 


測試 1 : 每秒測量一次亮度 (0~100%) [看原始碼  

#adc_test_1.py
import machine
import time

while True:
    adc=machine.ADC(0)    
    value=adc.read()           
    print(value, str(round(value*100/1024)) + '%')     
    time.sleep(1)

此處 print() 的第二個參數是將 ADC 的輸出 value 除以 1024 後乘以 100 變成百分比亮度值, 即 1024 為 %, 結果如下 : 

43 4%
58 6%
49 5%
81 8%
67 7%
158 15%
369 36%
81 8%
70 7%
123 12%
77 8%
127 12%
290 28%
288 28%

可見數值有時在一秒間變化甚大, 下面範例使用積分濾波器來抑制數值的突變 :


測試 2 : 每秒測量一次亮度 (0~100%) [看原始碼  

import machine
import time

while True:
    adc=machine.ADC(0)  
    value=adc.read()          
    value=0.3*value + 0.7*adc.read();    # 積分濾波
    print(value, str(round(value*100/1024)) + '%') 
    time.sleep(1)      

此處的積分濾波採用 3 分前值與 7 分現值之和計算, 結果如下 : 

489.0 48%
163.0 16%
236.0 23%
355.0 35%
360.0 35%
402.0 39%
470.0 46%
172.0 17%
507.0 50%
411.0 40%
166.0 16%


下面範例利用光敏電阻來控制板載 LED (GPIO2) 的閃爍頻率 : 


測試 3 : 利用光敏電阻量測的亮度控制 LED 閃爍頻率 [看原始碼  

from machine import Pin, ADC
import time

led=Pin(2, Pin.OUT)    

while True:
    adc=ADC(0)  
    value=adc.read()    
    value=int(0.3*value + 0.7*adc.read());  
    print(value, str(round(value*100/1024)) + '%') 
    led.value(1)                  # LED 滅
    time.sleep_ms(value)    
    led.value(0)                  # LED 亮
    time.sleep_ms(value) 

此例利用 ADC 輸出經積分濾波 (此非必要) 後之值來控制板載 LED (Pin 2) 的亮滅的暫停時間, 由於亮度越亮 value 值越大, 所以越亮會越慢, 越暗則閃爍速度越快. 注意, Witty Cloud 的板載 LED 是 Low active, 即輸出 0 點亮, 輸出 1 熄滅 (ESP32-WROOM 相反). 

下列範例以板載 LED (Pin 2) 模擬一般照明燈, 利用光敏電阻經 ADC 轉換而得的亮度 % 數值控制 LED 明滅 :


測試 4 : 利用光敏電阻控制 LED 明滅 [看原始碼  

from machine import Pin, ADC
import time

led=Pin(2, Pin.OUT)   # 板載 LED

while True:
    adc=ADC(0) 
    value=adc.read()    
    value=int(0.3*value + 0.7*adc.read());    # 積分濾波 (非必要)
    luminance=round(value*100/1024)
    print(value, str(luminance) + '%') 
    if luminance < 30:      
        led.value(0)             # 點亮 LED          
    elif luminance > 35: 
        led.value(1)              # 熄滅 LED 
    time.sleep(1)

此例是在亮度低於 30% 時點亮 LED; 高於 35% 時熄滅 LED. 

沒有留言 :