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积木中分别控制引脚电平

image

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截图:
image

D0连接P12,D1连接P13,D2连接P14,D3连接P15,D4连接P16。

由此图可见,执行顺序是以javascript代码中的顺序为准的,而此顺序与在图形化积木编辑器内创建forever积木的顺序有关。

3.3 执行digital write pin积木所需要的时间

micro:bit V1-PulseView截图:
image

micro:bit V2-PulseView截图:
image

micro:bit V1:6微秒(μs)
micro:bit V2:1微秒(μs)

3.4 从第一个forever开始运行到五个结束运行过后再次拉起第一个forever所需要的最少时间

micro:bit V1-PulseView截图:
image

micro:bit V2-PulseView截图:
image

micro:bit V1:24毫秒(ms)
micro:bit V2:20毫秒(ms)

在测试程序1中,即使只有一个forever在执行,再次拉起forever所需要的最少时间也不会改变。

3.5 从一个forever执行完毕到下一个forever开始执行所需要的间隔时间

micro:bit V1-PulseView截图:
image

image

micro:bit V2-PulseView截图:
image

image

上图分别是micro:bit V1和V2刚开机时与持续运行约20秒后的表现,发现随着运行时间的持续,forever之间的运行间隔时间变得不均匀。

4. 测试程序2 加入while循环及pause 1ms延时积木

image
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截图:
image

micro:bit V2-PulseView截图:
image

较比 3.4 中所测得的数值有显著的减少

micro:bit V1:6毫秒(ms)
micro:bit V2:4毫秒(ms)

4.2 改变pause 1ms延时积木的位置

image

将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显示积木

image

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截图:
image

micro:bit V2 表现一致。

在micro:bit 上显示数字1需要750ms,这750ms的时间里让出了纤程(fiber)让另外4个forever得以正常运行,这证明显示积木也可以像pause延时积木一样在while循环中让出纤程(fiber)。

6. 测试程序4 将所有pause 1ms延时积木换为show number显示积木

image

6.1 实机LED矩阵显示效果

micro:bit V1和V2都只能观察到LED矩阵显示数字1.

6.2 在逻辑分析仪中的表现

micro:bit V1-PulseView截图:
image

micro:bit V2-PulseView截图:
image

在micro:bit V1中仅show number 1所在的while循环还在执行,其余循环都没有执行。

在micro:bit V2中表现的比较特殊,即使LED矩阵并没有显示对应数字,也会在每一次show number 1所在的while循环完成后,依顺序每次循环执行一个forever中对引脚电平控制的积木。

7. 测试程序4 再次加入pause 1ms延时积木

image

7.1 实机LED矩阵显示效果

micro:bit V1和V2都能观察到LED矩阵按照顺序依次显示12345.

7.2 在逻辑分析仪中的表现

micro:bit V1-PulseView截图:
image

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 音乐积木

image

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截图:
image

在while循环中没有加入pause延时积木的情况下也能让出纤程(fiber)去执行其他的forever。

程序依旧按照forever积木的顺序来循环执行,但各个forever中的play tone积木将持续运行完其设置的节拍所需的时间后才会执行后续的控制引脚高低电平的积木。

9.小结

image

micro:bit 应用MakeCode进行编程时可以善用forever积木内置一层while循环积木和一个pause 1ms延时积木来增强 多工 的性能表现,pause 1ms延时积木添加在所要运行的程序开头或结尾都可以。