micro:bit与事件驱动
文章目录
在微软的makecode编辑器中,我们可以轻松为micro:bit写出这种事件驱动风格的代码:当按钮A被按下的时候打印字符A,当按钮B被按下的时候打印字符B
生成的代码(javascript)十分简单:
|
|
当我们使用Python来为micro:bit编程时,却很难写出这种事件驱动风格的代码,如果我们要做到上边类似的事,一般的教程里会让你用while+if/else
来做。尽管可以做到类似的事,但思维方式/语义其实并不相同。
Why
makecode将积木映射为JavaScript代码,JavaScript是一个事件驱动型语言,所以在makecode可以很轻松进行事件驱动风格的编程。而Python对事件驱动的关注主要集中在网络编程方面,在Python中做事件驱动风格的编程,并不是那么常见。
要在图形化中,自动生成事件驱动风格的代码,自然就更不易了
我们看到micro:bit官方的bbcmicrobit/PythonEditor中积木化界面(blockly)就不支持:当按钮A被按下的时候打印字符A,当按钮B被按下的时候打印字符B
how
由于目前micro:bit的micropython固件并不支持多线程(pyboard倒是有个固件支持_thread
),要实现事件驱动,可能只有协程供你选择了。
micro:bit官方对此并没有很好的解决方案
mblock/makeblock的方案倒是十分漂亮,值得我们好好学习(ps:mblock在工程上十分出色,有许多聪明的做法值得学习)
我们先在mblock中来为micro:bit编写事件驱动风格的程序
接着我们来看看积木generate出的Python代码:
代码十分规整,规整的好处是从积木到代码的转化将很简单。这种从积木generate出代码的方式,是典型的blockly app风格,尽管长着scratch3.0的样子,关于两者的差异可以参考我此前的文章:Blockly与Scratch3.0的比较分析及选型建议
观察这个代码(注意yeild
),如果你熟悉python的协程,应该可以轻松猜到,mblock很聪明地使用协程来做事件驱动风格的编程
至于为何不用async/await,是因为MicroPython是Python 3.4的一个实现,在python3.4中,你不能使用async/await关键字,直到Python在3.5版本才引入关于协程的语法糖async和await
这段代码尽管十分工整,但它并不能运行,它需要一个调度器来调度它们。
经过预处理之后,可运行代码为:
|
|
当然,在进入micro:bit之前,它要连同内核一同被编译为hex文件。
可以看出,mblock在generate出代码之后,还有一个预处理的过程(实际上webduino也干过类似的事,我之前的分析有分析过,他们的做法如出一辙)。
尽管我们可以用一些hack的手段拿到这部分的源码,但我们不打算在此讨论细节(mblock这部分并未开源,出于尊重和规避法律风险的考虑,我们不准备公开他们这部分的代码。大家自己动手去实现吧,按照以上分析,这部分实现起来十分简单,mblock是个很酷的团队,也许之后会开放)
mblock对程序进行预处理的部分使用js来做,如下图,大家把这个转化器当黑盒来看吧
通过简单的正则,你很快可以写出来:)
参考
文章作者 种瓜
上次更新 2018-06-19