在MicroPython中用面向对象方法控制microbit显示

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

在MicroPython中用面向对象方法控制microbit显示

#1

帖子 shaoziyang »

翻译自:http://blog.rareschool.com/2017/ ... edge-using-o-o.html

据拉里·沃尔(一位非常著名的程序员)说,懒惰是一种美德。懒惰的程序员提出节省劳力的解决方案。

如果你想节省自己和别人的时间,让micropython代码易于重复使用、阅读。

本文假设您已经熟悉对象、类和组合的概念,并且知道如何用Python编写类定义。如果您不熟悉Python的对象定位(O O),您可能会发现代码很难遵循。我在本文后面对O作了简短的介绍。

有几种学习Python的方法。这里有一个“官方”教程,但是我不确定初学者是否会觉得很容易理解。有一本看起来不错的书。它需要大量的时间和金钱投入,但是我认为如果你需要提高你的Python技能是值得的。

我可能会着手写我自己的介绍,但这是一个重大项目,需要一段时间。现在,即使您不熟悉O,也应该能够跟踪大多数文章并运行示例代码。

Python(micropython)对物理计算非常有用
  • Python是当之无愧的物理计算应用中一个非常流行的语言。
  • Python很容易学习,它很有表现力,可以在Linux、Mac OS和微软Windows上免费使用。
  • Python让树莓派充满活力,大量代码树莓派的代码都是用Python实现的。
  • 最近,micropython带来了语言的几个流行的单片机平台,包括BBC microbit。
但…

大多数已发表micropython脚本使用Python程序风格。大多数程序员都是这么开始的,它是教程中使用最广泛的一种风格。

当以程序式编程时,您可以逐步地完成计算机所希望的工作,而程序则是指定这些步骤的过程。

值得探索其他编程风格,在本文中,您将看到如何开发一个简单的Python应用程序,它可以使用面向对象风格。在面向对象的程序中,通过创建对象来编程,即将数据和代码结合起来执行简单任务的小程序包。为了进行更复杂的任务,对象相互协作(相互交互)。通过编写类的定义,指定特定对象的类型(数据)和它能做什么(方法),指定程序所需的对象类型。

您可以看到运行的应用程序:

[bbvideo]https://www.youtube.com/embed/KS65avMj91U[/bbvideo]


这个想法很简单。应用程序使用microbit的LED点阵显示计数器的值,并且可以通过使用按钮来更改它。稍后,您将看到如何将这个简单的想法应用于实际项目中。

您可以用简短的脚本实现演示,但脚本的组成部分在其他应用程序中不易使用。

以下是一些可能需要实现的变化,而不必从scratch开始:
  • 使用 LED 灯柱显示
  • 显示当前光线等级或温度
  • 一个时钟样式,当参数上升到9时跳到0
  • 使用不同类型LED的类似显示器
  • 一次只打开一个LED显示值的显示器
  • 用不同颜色的显示不同值的显示器
当然,您可以通过创建原始脚本的多个变体来实现这一点,但如果您在原始脚本中发现了bug,那么会发生什么?你必须在每一份拷贝上做同样的修改!

这就是为什么有经验的程序员试图避免代码重复拷贝的原因之一。甚至有一个缩写词可以帮助你记住它:DRY(Don’t repeat yourself),代表“不要重复你自己”。

还有一个很好的理由,可以用简单的组件来编写代码。每个组件都很容易自己测试。这可以帮助您避免bug,跟踪并删除任何在代码中爬虫。


让我们开始编码

您将需要查看按钮的代码,并告诉应用程序中的计数器在按下其中一个按钮时计数或向上或向下计数。

没有必要用一个类来实现它。

应用程序代码中创建和SimpleDisplayer实例连在一起的计数器,以达到预期的结果。

代码: 全选

max_count = 10
disp = SimpleDisplayer()
counter = Counter(disp, max_count)
while True:
   if button_a.is_pressed():
       counter.up()
   if button_b.is_pressed():
         counter.down()
   sleep(200)
最后一部分应该是不言自明的。它创建了一个SimpleDisplayer和计数器的代码。让我们从计数器开始。

Counter类

在这个应用程序中,计数器是一个简单的对象,它知道它的当前计数,并且可以在它的初始值为零和某些最大值之间上下计数。在我们的例子中,最大值是10。

计数器知道另一个对象,每当计数器的值发生变化时就会被通知。最初,这将是一个SimpleDisplayer对象并在microbit上显示。

下面是计数器类的代码:

代码: 全选

class Counter():
  # count ranges from 0 to max.
  # when the count changes disp (the displayer) is notified
  def __init__(self, disp, max):
      self._disp = disp
      self._max = max
      self._count = 0

  def update(self):
      self._disp.value(self._count)

  def up(self):
      if self._count < self._max:
          self._count += 1
          self.update()

  def down(self):
      if self._count > 0:
          self._count -= 1
          self.update()
计数器向显示器发送消息,这是一个SimpleDisplayer使用内置的LED显示数值的代码:

代码: 全选

# SimpleDisplayer shows the latest value on the micro:bit's LEDs
class SimpleDisplayer():
      def value(self, num):
          display.show(str(num))
面向对象编程易于更改

这种方法使我们的应用程序很容易适应一个代码的变化。假设您希望使用类似于Proto-pic EDGE的LED阵列显示计数器的当前状态。

下面是运行的新版本

[bbvideo]https://www.youtube.com/embed/t4daK42Cmro[/bbvideo]

下面是驱动修订应用程序的代码:

代码: 全选

from microbit import *
import neopixel

...

max_count = 10
leds = neopixel.NeoPixel(pin0, max_count)
disp = BarGraph(leds, BarGraph.YELLOW)
counter = Counter(disp, max_count)
while True:
   if button_a.is_pressed():
       counter.up()
   if button_b.is_pressed():
       counter.down()
   sleep(200)
最后一部分不变。使用了两个新的类的代码:neopixel和BarGraph。

neopixel类是microbit的micropython版的一部分,所以我们只需要导入neopixel模块。BarGraph是我们应用程序新的部分,我们需要写它的定义并插入到上面。

这里是BarGraph类的代码:

代码: 全选

# BarGraph uses an array of Neopixels or other similar LEDs
# to show the latest value
class BarGraph():
    # colo(u)r constants.
    # we use low values so the we don't strain the micro:bit's power supply
    WHITE  = (50,50,50)
    RED    = (50,0,0)
    BLUE   = (0,0,50)
    GREEN  = (0,50,0)
    YELLOW = (100,50,0)
    CLEAR  = (0,0,0)
    def __init__(self, leds, on_colour=WHITE):
        self._leds = leds
        self._count = len(leds)
        self._on_colour = on_colour

    def value(self, num):
        for i in range(self._count):
           if i < num:
               self._leds[i] = self._on_colour
           else:
               self._leds[i] = self.CLEAR
           self._leds.show()
应用程序代码(前面所示)创建实例并将和计数器和BarGraph连接起来,从而达到预期的结果。

模块化代码更容易更改。在这篇文章的下一部分,我们将看到改变光感应LDR的输入和添加更多的颜色到BarGraph显示。

我们还将看到这种方法的另一个主要好处:易于测试。
 

回复

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