MakeCode圖形編程應用在micro:bit上的多工性能實測
1. 簡述
本文不涉及對測試中所用到的設備或軟件的推廣。
micro:bit 是一款由英國廣播電視公司(BBC)為青少年編程教育設計,並由微軟,三星,ARM,英國蘭卡斯特大學等合作夥伴共同完成開發的微型電腦,目前推出V1,V2兩款,後者較比前者性能稍強。
MakeCode 是微軟所推行的應用於編程教育的圖形編程語言,也是micro:bit 目前主流應用的編程語言。
其編輯器主要由三個部分組成,圖形化積木(blocks)編輯器,仿真模擬器,圖形化積木所對應的JavaScript代碼編輯器。
我對其中關於forever積木在micro:bit 上實機運行的多工性能用邏輯分析儀進行了測試,由於micro:bit V1及V2版本性能有差異,將分別測試並記錄。
2. 測試環境
micro:bit V1及V2版本各一塊,將micro:bit 的引腳全部引出的擴展板,SX24M8邏輯分析儀,PulseView。

3. 測試程序1 在五個forever積木中分別控制引腳電平
javascript代碼:
pins.digitalWritePin(DigitalPin.P12, 0)
pins.digitalWritePin(DigitalPin.P13, 0)
pins.digitalWritePin(DigitalPin.P14, 0)
pins.digitalWritePin(DigitalPin.P15, 0)
pins.digitalWritePin(DigitalPin.P16, 0)
basic.pause(2000)
basic.forever(function () {
pins.digitalWritePin(DigitalPin.P12, 1)
pins.digitalWritePin(DigitalPin.P12, 0)
})
basic.forever(function () {
pins.digitalWritePin(DigitalPin.P13, 1)
pins.digitalWritePin(DigitalPin.P13, 0)
})
basic.forever(function () {
pins.digitalWritePin(DigitalPin.P14, 1)
pins.digitalWritePin(DigitalPin.P14, 0)
})
basic.forever(function () {
pins.digitalWritePin(DigitalPin.P15, 1)
pins.digitalWritePin(DigitalPin.P15, 0)
})
basic.forever(function () {
pins.digitalWritePin(DigitalPin.P16, 1)
pins.digitalWritePin(DigitalPin.P16, 0)
})
3.1 關於forever積木
在on start內的程序執行完後,forever內的程序會被循環執行。
forever內沒有while(True)死循環的時候,執行完自身內部的程序後會讓出纖程(fiber),此時允許執行其他的forever,即可以在後台存在多個forever,而多個forever將在系統中組成一個「大循環」。
3.2 五個forever的執行順序
micro:bit V1-測試程序1-PulseView截圖:
D0連接P12,D1連接P13,D2連接P14,D3連接P15,D4連接P16。
由此圖可見,執行順序是以javascript代碼中的順序為準的,而此順序與在圖形化積木編輯器內創建forever積木的順序有關。
3.3 執行digital write pin積木所需要的時間
micro:bit V1-PulseView截圖:
micro:bit V2-PulseView截圖:
micro:bit V1:6微秒(μs)
micro:bit V2:1微秒(μs)
3.4 從第一個forever開始運行到五個結束運行過後再次拉起第一個forever所需要的最少時間
micro:bit V1-PulseView截圖:
micro:bit V2-PulseView截圖:
micro:bit V1:24毫秒(ms)
micro:bit V2:20毫秒(ms)
在測試程序1中,即使只有一個forever在執行,再次拉起forever所需要的最少時間也不會改變。
3.5 從一個forever執行完畢到下一個forever開始執行所需要的間隔時間
micro:bit V1-PulseView截圖:
micro:bit V2-PulseView截圖:
上圖分別是micro:bit V1和V2剛開機時與持續運行約20秒後的表現,發現隨着運行時間的持續,forever之間的運行間隔時間變得不均勻。
4. 測試程序2 加入while循環及pause 1ms延時積木
javascript代碼:
pins.digitalWritePin(DigitalPin.P12, 0)
pins.digitalWritePin(DigitalPin.P13, 0)
pins.digitalWritePin(DigitalPin.P14, 0)
pins.digitalWritePin(DigitalPin.P15, 0)
pins.digitalWritePin(DigitalPin.P16, 0)
basic.pause(2000)
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P12, 1)
pins.digitalWritePin(DigitalPin.P12, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P13, 1)
pins.digitalWritePin(DigitalPin.P13, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P14, 1)
pins.digitalWritePin(DigitalPin.P14, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P15, 1)
pins.digitalWritePin(DigitalPin.P15, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P16, 1)
pins.digitalWritePin(DigitalPin.P16, 0)
basic.pause(1)
}
})
4.1 再次拉起第一個forever所需要的最少時間
micro:bit V1-PulseView截圖:
micro:bit V2-PulseView截圖:
較比 3.4 中所測得的數值有顯著的減少
micro:bit V1:6毫秒(ms)
micro:bit V2:4毫秒(ms)
4.2 改變pause 1ms延時積木的位置
將pause 1ms延時積木的位置調換到頂部,經過邏輯分析儀測試對結果沒有影響,但如果放置在需要運行的兩個積木中間則會改變運行時間。
4.3 加入while循環及pause 1ms延時積木提高了運行效率
while(Ture)循環積木單獨加入forever中將形成死循環無法讓出纖程(fiber),而再在while中加入pause延時積木,則會使程序運行到此處時,在等待延時的時間同時讓出纖程(fiber),允許其他forever的運行,且延時結束並運行完一次while循環內的程序後並不會退出到while循環外等待forever積木再次被系統喚起(除非加入了break的條件),while循環內的程序將立即循環執行,多個forever中都如此設計將極大提高系統運行效率。
並非一定要將pause延時設置為1ms,只要在micro:bit V1中設置低於6ms,micro:bit V2中設置低於4ms,實際執行都將等於這個最低值,而若超出這個值後將按照設置的值來等待延時。
5. 測試程序3 將第一個forever中的pause 1ms延時積木換為show number顯示積木
javascript代碼:
pins.digitalWritePin(DigitalPin.P12, 0)
pins.digitalWritePin(DigitalPin.P13, 0)
pins.digitalWritePin(DigitalPin.P14, 0)
pins.digitalWritePin(DigitalPin.P15, 0)
pins.digitalWritePin(DigitalPin.P16, 0)
basic.pause(500)
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P12, 1)
pins.digitalWritePin(DigitalPin.P12, 0)
basic.showNumber(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P13, 1)
pins.digitalWritePin(DigitalPin.P13, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P14, 1)
pins.digitalWritePin(DigitalPin.P14, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P15, 1)
pins.digitalWritePin(DigitalPin.P15, 0)
basic.pause(1)
}
})
basic.forever(function () {
while (true) {
pins.digitalWritePin(DigitalPin.P16, 1)
pins.digitalWritePin(DigitalPin.P16, 0)
basic.pause(1)
}
})
5.1 show number顯示積木在邏輯分析儀中的表現
micro:bit V1-PulseView截圖:
micro:bit V2 表現一致。
在micro:bit 上顯示數字1需要750ms,這750ms的時間裏讓出了纖程(fiber)讓另外4個forever得以正常運行,這證明顯示積木也可以像pause延時積木一樣在while循環中讓出纖程(fiber)。
6. 測試程序4 將所有pause 1ms延時積木換為show number顯示積木
6.1 實機LED矩陣顯示效果
micro:bit V1和V2都只能觀察到LED矩陣顯示數字1.
6.2 在邏輯分析儀中的表現
micro:bit V1-PulseView截圖:
micro:bit V2-PulseView截圖:
在micro:bit V1中僅show number 1所在的while循環還在執行,其餘循環都沒有執行。
在micro:bit V2中表現的比較特殊,即使LED矩陣並沒有顯示對應數字,也會在每一次show number 1所在的while循環完成後,依順序每次循環執行一個forever中對引腳電平控制的積木。
7. 測試程序4 再次加入pause 1ms延時積木
7.1 實機LED矩陣顯示效果
micro:bit V1和V2都能觀察到LED矩陣按照順序依次顯示12345.
7.2 在邏輯分析儀中的表現
micro:bit V1-PulseView截圖:
micro:bit V2 表現一致。
與5.1,6.2中所測得的結果相比較,表明show number顯示積木可以在while循環中讓出纖程(fiber)允許其他forever中的積木執行,卻無法允許相同的show number顯示積木執行。
只有加入pause 1ms延時積木才可將讓出纖程(fiber)讓其他的show number顯示積木所在的forever得以執行,且必須等到前一個show number顯示積木執行完畢後才可以執行後續的show number顯示積木。
另外show leds,show icon,show arrow顯示積木與之相同,但同樣用於控制LED矩陣顯示的plot X0 Y0積木及其相關聯的積木則無法在while循環中讓出纖程(fiber)。
8. 測試程序5 音樂積木
javascript代碼:
pins.digitalWritePin(DigitalPin.P12, 0)
pins.digitalWritePin(DigitalPin.P13, 0)
pins.digitalWritePin(DigitalPin.P14, 0)
pins.digitalWritePin(DigitalPin.P15, 0)
pins.digitalWritePin(DigitalPin.P16, 0)
music.setVolume(25)
music.setTempo(60)
basic.pause(500)
basic.forever(function () {
while (true) {
music.playTone(262, music.beat(BeatFraction.Whole))
pins.digitalWritePin(DigitalPin.P12, 1)
pins.digitalWritePin(DigitalPin.P12, 0)
}
})
basic.forever(function () {
while (true) {
music.playTone(294, music.beat(BeatFraction.Half))
pins.digitalWritePin(DigitalPin.P13, 1)
pins.digitalWritePin(DigitalPin.P13, 0)
}
})
basic.forever(function () {
while (true) {
music.playTone(330, music.beat(BeatFraction.Quarter))
pins.digitalWritePin(DigitalPin.P14, 1)
pins.digitalWritePin(DigitalPin.P14, 0)
}
})
basic.forever(function () {
while (true) {
music.playTone(349, music.beat(BeatFraction.Eighth))
pins.digitalWritePin(DigitalPin.P15, 1)
pins.digitalWritePin(DigitalPin.P15, 0)
}
})
basic.forever(function () {
while (true) {
music.playTone(392, music.beat(BeatFraction.Sixteenth))
pins.digitalWritePin(DigitalPin.P16, 1)
pins.digitalWritePin(DigitalPin.P16, 0)
}
})
8.1 實際發聲效果
僅測試了micro:bit V2,因為其板載蜂鳴器,如果是micro:bit V1則需痛過引腳外接音響設備。
從聽覺上大致能判斷實際播放的是「和聲」,即多個音調同時響起,並不會按照forever的順序逐一播放。
8.2 在邏輯分析儀中的表現
micro:bit V2-PulseView截圖:
在while循環中沒有加入pause延時積木的情況下也能讓出纖程(fiber)去執行其他的forever。
程序依舊按照forever積木的順序來循環執行,但各個forever中的play tone積木將持續運行完其設置的節拍所需的時間後才會執行後續的控制引腳高低電平的積木。
9.小結
micro:bit 應用MakeCode進行編程時可以善用forever積木內置一層while循環積木和一個pause 1ms延時積木來增強 多工 的性能表現,pause 1ms延時積木添加在所要運行的程序開頭或結尾都可以。