Control microbit display with object-oriented method in MicroPython

According to Larry Wall (a very famous programmer), laziness is a virtue. Lazy programmers come up with labor-saving solutions.

If you want to save yourself and others time, make micropython code easy to reuse and read.

This article assumes that you are already familiar with the concepts of objects, classes, and composition, and know how to write class definitions in Python. If you are not familiar with Python's Object Orientation (OO), you may find the code difficult to follow. I give a brief introduction to O later in this article.

There are several ways to learn Python. There is an " official " tutorial here, but I'm not sure if beginners will find it easy to understand. There is a book that looks good . It requires a lot of time and money investment, but I think it's worth it if you need to improve your Python skills.

I might start writing my own introduction, but this is a major project and will take a while. Now, even if you are not familiar with O, you should be able to follow most articles and run example code.

Python (micropython) is very useful for physical computing
 

  • Python is well deserved a very popular language for physical computing applications.
  • Python is easy to learn, expressive, and available for free on Linux, Mac OS, and Microsoft Windows.
  • Python energizes the Raspberry Pi, and a lot of code for the Raspberry Pi is implemented in Python.
  • More recently, micropython has brought the language to several popular microcontroller platforms, including the BBC microbit.


But...

most published micropython scripts use the Python procedural style. This is how most programmers start, and it is the most widely used style in tutorials.

When programming procedurally, you do what the computer wants you to do step by step, and a program is the process of specifying those steps.

It's worth exploring other programming styles, and in this article, you'll see how to develop a simple Python application that can use an object-oriented style. In object-oriented programming, programming is done by creating objects, which are small packages of data and code that combine data and code to perform simple tasks. To perform more complex tasks, objects cooperate (interact with each other). By writing a class definition, specifying the type of a particular object (data) and what it can do (methods), specify the type of object a program needs.

You can see running applications:




 

The idea is simple. The app uses the microbit's LED dot matrix to display the counter's value, and it can be changed by using a button. Later, you will see how this simple idea can be applied to real projects.

You can implement the demo with a short script, but the components of the script are not readily available in other applications.

Here are some changes that might need to be implemented without having to start with scratch:

  • Display with LED light post
  • Displays current light level or temperature
  • A clock style that jumps to 0 when the parameter goes up to 9
  • Similar displays using different types of LEDs
  • Turn on the display with only one LED showing the value at a time
  • Displays showing different values ​​in different colors


Of course, you can do this by creating multiple variations of the original script, but what happens if you find a bug in the original script? You must make the same modifications on every copy!

This is one of the reasons why experienced programmers try to avoid duplicating code. There's even an acronym to help you remember it: DRY (Don't repeat yourself), which stands for "don't repeat yourself."

There is also a good reason to code with simple components. Each component is easy to test by itself. This helps you avoid bugs, track down and remove any crawlers in your code.


Let's start coding

You will need to look at the code for the buttons and tell the counter in the application to count up or down when one of the buttons is pressed.

There is no need to implement it with a class.

The application code creates a counter linked to the SimpleDisplayer instance to achieve the desired result.

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)

The last part should be self-explanatory. It creates a SimpleDisplayer and counter code. Let's start with the counter.

Counter class

In this application, a counter is a simple object that knows its current count and can count up and down between its initial value of zero and some maximum value. In our case, the maximum value is 10.

The counter is aware of another object and will be notified whenever the value of the counter changes. Initially, this will be a SimpleDisplayer object and displayed on the microbit.

Here is the code for the counter class:

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()

The counter sends a message to the display, here is a SimpleDisplayer code that uses the built-in LED to display the value:

# SimpleDisplayer shows the latest value on the micro:bit's LEDs
class SimpleDisplayer():
      def value(self, num):
          display.show(str(num))

 

Object-Oriented Programming Ease of Change

This approach makes it easy for our application to adapt to a code change. Suppose you want to display the current state of the counter using an LED array similar to a Proto-pic EDGE.

Here's the new version running:

Here is the code that drives the revision application:
 

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)

The last part is unchanged. Code using two new classes: neopixel and BarGraph.

The neopixel class is part of the micropython version of the microbit, so we just need to import the neopixel module. BarGraph is a new part of our application, we need to write its definition and insert it.

Here is the code for the BarGraph class:

# 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()

The application code (shown earlier) creates the instance and connects it with the counter and BarGraph to achieve the desired result.

Modular code is easier to change. In the next part of this post, we'll see changing the input of the light-sensing LDR and adding more colors to the BarGraph display.

We'll also see another major benefit of this approach: ease of testing.

 

Translated from: http://blog.rareschool.com/2017/04/program-proto-pic-edge-using-oo.html

 

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324377640&siteId=291194637