掌握micro:bit的时间(micropython)

micro:bit编程、教学、展示
STEM
回复
头像
shaoziyang
帖子: 3917
注册时间: 2019年 10月 21日 13:48

掌握micro:bit的时间(micropython)

#1

帖子 shaoziyang »

翻译自:https://blog.groklearning.com/be ... ro-bit-c4b8b4e2d747

micro:bit可以用来显示时间,如:
 
掌握microbit的时间1.jpg
掌握microbit的时间1.jpg (75.28 KiB) 查看 2526 次
 

但对于掌握了MicroPython基础知识的人来说,我们所看到的主要问题之一就是“如何让我的程序做更多的事情”。例如:一个程序可能希望在屏幕上显示一定的时间,但在这段时间内也会响应按钮按下。或者,也许还需要记住在将来的某个时候做点什么,但是到那时继续做它的主要功能。

问题?

这个限制出现了,因为大部分可用的方法都会暂停程序直到完成。一个简单的例子如下所示,程序首先滚动消息,然后开始响应按钮按下。

代码: 全选

from microbit import *
display.scroll('hello micro:bit')
while True:
  if button_a.was_pressed():
    display.show(Image.HEART)
这意味着当消息在屏幕上滚动时,将无法响应用户输入,while循环直到 display.scroll 完成后才会启动。或者说 display.scroll 方法“阻塞”程序直到执行完成。

代码: 全选

from microbit import *
n = 0
while True:
  if button_a.was_pressed():
    n += 1
    display.scroll(str(n))
计数器与按下的次数不符。


不再等待!

在某些情况下使用 wait=False,可以变为非阻塞模式。详细说明请参阅http://microbit-micropython.readthedocs ... splay.html

代码: 全选

from microbit import *
n = 0
while True:
  if button_a.was_pressed():
    n += 1
    display.scroll(str(n), wait=False)
现在display.scroll函数不再被阻塞,而且我们正确地计算了按下的次数,但是每次按下按钮时仍然有“重置”显示的问题。如果你按下按钮足够快,你永远不会在屏幕上看到任何东西。

而我们通常希望的是让显示器定期显示当前计数 - 可能每10秒钟一次。在后面我们将看到如何做到这一点。


用MicroPython做定时器

下面想要显示一段固定的时间(例如一个计时器),如果我们再次按下按钮,定时器应该重置。

代码: 全选

from microbit import *
while True:
  if button_a.was_pressed():
    display.show(Image.SQUARE)
    s leep(5000)
    display.clear()
这个程序是正确的,但是时间是错误的。如果按下按钮,并在两秒钟后再按一下按钮,结果显示屏将保持10秒钟。令人困惑的是,如果按一次按钮,再按多次,它仍然保持10秒钟。此外,如果程序想要响应不同的输入(例如按钮B立即关闭显示器),则不能同时进行 s leep()。

代码: 全选

from microbit import *
while True:
  if button_a.was_pressed():
    display.show(Image.SQUARE)
    s leep(5000)
    display.clear()
  if button_b.was_pressed():
    display.clear()
这可以再次利用来解决wait=False连同两个额外的参数-  delay=5000和clear=True。

代码: 全选

from microbit import *
while True:
  if button_a.was_pressed():
    display.show(Image.SQUARE, wait=False, clear=True, delay=5000)
  if button_b.was_pressed():
    display.clear()
现在显示屏会自最后一次按下按钮后始终保持5秒钟,但是由于show函数没有“阻塞”,所以它可以响应两个按钮函数。但是,当程序一次执行多个事件时,这会变得非常复杂,而且一些函数不支持等待/延迟选项(例如,发送命令到串口/ SPI / I2C)。如果micro:bit作为定时器控制的灯或报警器,那么这种情况下更现实的例子是。

代码: 全选

from microbit import *
while True:
  if button_a.was_pressed():
    pin0.write_digital(1)
    s leep(5000)
    pin0.write_digital(0)
  if button_b.was_pressed():
    pin0.write_digital(0)
上面的例子假设一个灯或蜂鸣器插入到引脚0和1,但是没有相当的等待/清除/延迟write_digital,所以它具有与上述第一个例子相同的问题。


使用running_time()

running_time()返回自启动micro:bit以来的毫秒数。请注意,micro:bit没有“实时时钟”,所以它没有“时间”的概念,只有运行的时间。时间是足够准确的,能够制作一个简单的时钟或手表,但是每次打开micro:bit时我们都必须重新设置它。

代码: 全选

from microbit import *
while True:
  display.show(str(running_time() // 1000))
上面的程序只计算了秒数(//在Python 3中用于“整数除法”)。而不是s leep()那样使用阻塞(或者)来使程序在特定的时间内执行某些操作,我们可以使用它running_time()来查看已经过了多少时间。大多数情况下,我们的代码需要计算两次调用running_time之间的时间。

代码: 全选

from microbit import *
time_last_press = 0
while True:
  if button_a.was_pressed():
    time_now = running_time()
    display.show(str(time_now - time_last_press))
    time_last_press = time_now
该程序将显示每次按下按钮之后所经过的时间。让我们再来看看前面的例子,打开一个五秒钟的引脚,然后重新写入使用running_time()。我们的目标是每按一下按钮A使引脚保持5秒钟,然后按钮B立即关闭引脚。

代码: 全选

from microbit import *
while True:
  if button_a.was_pressed():
    pin0.write_digital(1)
    start = running_time()
    while running_time() - start < 5000:
      pass
    pin0.write_digital(0)
  if button_b.was_pressed():
    pin0.write_digital(0)
这仍然有同样的错误,我们所做的一切都是有效地实现了我们自己的sleep版本,它与前面的例子完全相同。(注意:这正是在MicroPython中实现的s leep()函数的方式)。


设置定时器

现在我们有办法修改这个代码来实现我们想要的功能。

代码: 全选

from microbit import *
LIGHT_MS = 5000
pin_off_time = 0
while True:
  if running_time() > pin_off_time:
    pin0.write_digital(0)
  if button_a.was_pressed():
    pin0.write_digital(1)
    pin_off_time = running_time() + LIGHT_MS
  if button_b.was_pressed():
    pin_off_time = running_time()
我们可以把它pin_off_time看作将来会发生的事情的“计时器”。这种方法推广到多个定时器,只需添加更多的变量。你甚至可以编写包含定时器列表的程序 - 例如将来计划一个命名事件的元组(time, name)。


周期计时器

回到我们一开始的例子。我们希望程序每10秒钟显示一次按键的次数,同时还能响应按键按下。这将结合两者wait=False和running_time()。

代码: 全选

from microbit import *
UPDATE_INTERVAL = 10000
next_update = 0
n = 0
while True:
  if running_time() > next_update:
    display.scroll(str(n), wait=False)
    next_update = running_time() + UPDATE_INTERVAL
  if button_a.was_pressed():
    n += 1
现在这个next_update变量被用来计算下一次显示计数的时间,通过设置wait=Falseon display.scroll,它会在后台判断,让我们可以继续检测按钮按下动作。

 

回复

  • 随机主题
    回复总数
    阅读次数
    最新文章