highlight.js

星期四, 3月 19, 2020

ESP8266 MicroPython 所有的 PWM 都是同一頻率

下午看了一下 ESP8266 MicroPython 的原始碼, 才發現原來所有的 PWM 都是共同頻率, 無法個別設計, 無論使用哪一個 PWM 物件叫用 freq(), 都會影響到所有的 PWM 物件。原始碼中實際設定頻率的程式如下:
void ICACHE_FLASH_ATTR
pwm_set_freq(uint16 freq, uint8 channel) {
    LOCK_PWM(critical);   // enter critical
    if (freq > PWM_FREQ_MAX) {
        pwm.freq = PWM_FREQ_MAX;
    } else if (freq < 1) {
        pwm.freq = 1;
    } else {
        pwm.freq = freq;
    }

    pwm.period = PWM_1S / pwm.freq;
    UNLOCK_PWM(critical);   // leave critical
}
你可以看到雖然函式有 channel 參數, 但在函式內根本不會用到這個參數, 而且頻率是記錄在 pwm.freq 中, 不會區分是那個 channel 的頻率。

星期三, 3月 18, 2020

改用 highlight.js 為文章中的程式碼加上語法顏色標示

原本使用的 SyntaxHighlighter 在 Blogger 上一整個炸壞掉, 現在改用 highlight.js, 快速簡單, 中間也考慮過 Google 的 code-prettify, 但是會有程式過長疊到右邊側欄內容的問題。

ESP8266 MicroPython PWM 的奇怪現象

同事在使用 ESP8266 的 MicroPython 時, 使用 PWM 製作呼吸燈, 但卻遇到了奇怪的狀況, 程式如下:
from machine import Pin, PWM
import utime

# R:D5 G:D6 B:D7
r = PWM(Pin(14, Pin.OUT), freq=500, duty=0)
# this line would make PWM work in a strange way
g = PWM(Pin(12, Pin.OUT), freq=500, duty=0)
b = PWM(Pin(13, Pin.OUT), freq=500, duty=0)

while True:
    for i in range(512):
        b.duty(i)
        #g.duty(i)
        r.duty(i)
        utime.sleep_ms(1)        
    for i in reversed(range(512)):
        b.duty(i)
        #g.duty(i)
        r.duty(i)
        utime.sleep_ms(1)

其實就是簡單的用 2 個腳位 PWM 從 0~512 再回到 0 製作陽春的呼吸燈效果, 不過執行後卻發現其中一個燈看起來一直亮著、另外一個燈卻偶而才閃一下,  根本沒有 PWM 漸次變化的效果。

經過實驗測試後發現, 程式一開始建立了 3 個 PWM 物件, 但是 g 這個 PWM 物件卻沒有用到, 如果不要建立這個多餘的 PWM 物件 g , 或是在實際上有使用到 g 物件, 例如把程式中 for 迴圈內的註解符號移除, 結果就正常了。目前還不知道實際發生問題的原因。

20200830 補充:這個問題我有貼到 MicroPython 論壇上, 經過善心人士回饋到 MicroPython github 上後, 已經把 bug 解掉了, 如果你改用 2020/3/27 之後的韌體版本, 就不會發生一樣的問題了。

20200909 補充:在 2020/09/02 發佈的 1.13 版韌體中, 已經將上述修正併入正式版本了。