TigerJython4Kids
robotics Robotik
appendix
Deutsch   English   

APPENDIX: 7-SEGMENT DIGITAL DISPLAY

 

 

SPECIFICATIONS AND CONNECTION TO THE MICRO:BIT

 

The display unit uses the driver module TM1637 and a 4-digit seven-segment display with a colon in the middle. In addition to the power supply with 3.3V and GND, only 2 lines named Clock (CLK) and Data (DIO) are required

A special protocol is used (similar but not identical with I2C). There are many sources of supply (Arduino/Raspberry Pi suppliers, Grove, eBay, the price varies between $1 and $10. Some displays are specified for 5V and may not work with 3.3V.).
 

GND and VCC are connected to the GND and 3.3V pins of the micro:bit. Any ports P0, P1, P2, P8, P12, P16 can be used for CLK and DIO, but P0 is common for CLK and P1 for DIO.

On a seven-segment display, only a limited set of characters can be displayed.

 
To control the display, a Python module mb7seg is used, which isolates the programmer from tricky communication issues and provides some simple rendering capabilities (see API documentation below). You can download mb7seg.zip from here. It contains mb7seg.py and a minimal version mb7segmin.py, which you can use if you get a "memory allocation failed" because of the size of the program. You have to download the modules to the micro:bit by choosing the Tools | Download module menu option in the TigerJython.

 

 

EXAMPLES

 

 


1. Count up from 0 to 9999

First, a display object  is created with d = FourDigit(pin0, pin1) where the ports for CLK and DIO are specified. (If you omit the parameters, P0 is assumed for CLK and P1 for DIO.) The show(text) method can also display integers directly.

 

Program:

from mb7seg import FourDigit
from microbit import *
 
d = FourDigit(pin0, pin1)

for n in range(10000):
    d.show(n)
► Copy to clipboard

You'll realize that it takes about 30 ms to display a single number. With a format specification, you can write out the numbers right-aligned, use d.show ("%4d" % n).

2. Show the acceleration

The digital display is often used to display values measured by a sensor, for example the x component of the acceleration. To do this, poll the sensor in an endless loop. sleep() is used to define the measurement period, but note this value is only approximate because other calls in the loop also require processor time.

Program:

from mb7seg import FourDigit
from microbit import *
 
d = FourDigit()
while True:
    acc = accelerometer.get_x()
    d.show(acc)
    sleep(100)
► Copy to clipboard

Here, the display object is created without parameter values, assuming that the terminals CLK and DIO are at P0 and P1.

The decimal number is formatted to four-digits with 2 decimals and leading zeros (the decimal point is included in the length specification). Then the decimal point must be removed, because it is replaced by the display's colon sign. The acceleration is shown in m/s2.

Program:

from mb7seg import FourDigit
from microbit import *
 
d = FourDigit()
d.setColon(True)
while True:
    acc = accelerometer.get_x() / 100
    v = "%05.2f" %acc
    v1 = v.replace(".", "")
    d.show(v1)
    sleep(100)
► Copy to clipboard

3. Show a prompt

After the start, the prompt text is written out in scrolling text. Then the program loops until the button A is pressed. It would be inconvenient to use the blocking method scroll(), because the user would have to wait after pressing the button until the whole text is finished. Rather, it is preferable to scroll the text with toLeft(), so you can check the button every 300 ms.. To quit the repeating loops, use the keyword break.

Program:

from mb7seg import FourDigit
from microbit import *
 
d = FourDigit()
d.show("Press A to start")
while True:
     while d.toLeft() > 0 and not button_a.is_pressed():
        sleep(300)
     if button_a.is_pressed():
        break   
     d.toStart()   
     sleep(500)
d.show("Go")
► Copy to clipboard (Ctrl+C copy, Ctrl+V paste)

You can not use button_a.was_pressed() instead of is_pressed() here because you call it twice.

4. Show the time

With a cheap clock module (Real Time Clock, RTC), you can turn your micro:bit into a precisely running digital clock. The module uses the DS3231 chip. There are many sources of supply (Arduino/Raspberry Pi suppliers, Grove, eBay, the price varies between $1 and $10). The module uses that I2C protocol with 4 ports GND, VCC, SCL and SDA.

You connect it to the micro:bit as follows:
GND ⇒ GND
VCC ⇒ 3V
SCL ⇒ P19
SDA ⇒ P20

After inserting the battery, you must first set the current date and time with a program. The module works in BCD format (Binary Coded Decimal).

 


Program:

from microbit import *

s = 0 # Seconds
m = 33 # Minutes
h = 15 # Hours
w = 2 # Day of week (Sunday = 1)
dd = 3 # Day
mm = 11 # Month
yy = 2018 # Year

def dec2bcd(dec):
    tens, units = divmod(dec, 10)
    return (tens << 4) + units
 
addr = 0x68
t = bytes([s, m, h, w, dd, mm, yy - 2000])
for i in range(0,7):
    i2c.write(addr, bytes([i, dec2bcd(t[i])]))
print("Datetime set to %d-%d-%d %d:%d:%d" %(dd, mm, yy, h, m, s)) 
► Copy to clipboard

Your program calls i2c.write(addr, 0) to send the command to the RTC module to return the current  date-time. It then catches the reply with buf = i2c.read(). After the conversion to decimal format, hours and minutes are displayed on the seven-segment display. The colon flashes approximately every second.

Program:

from mb7seg import FourDigit
from microbit import *

def bcd2dec(bcd):
    return ((bcd & 0xf0) >> 4) * 10 + (bcd & 0x0f)
 
d = FourDigit()
showColon = False
while True:
    addr = 0x68
    i2c.write(addr, b'\x00')
    buf = i2c.read(addr, 7)
    mm = bcd2dec(buf[1])
    hh = bcd2dec(buf[2])
    d.show("%02d%02d"  %(hh, mm)) # show leading zeros
    if showColon:
        d.setColon(False)
        showColon = False
    else:
        d.setColon(True)
        showColon = True
    sleep(1000)
► Copy to clipboard

Remark: The functions to handle the RTC are encapsulated in the Python module rtc that is downloaded as part of the micro:bit flashing procedure. (See TigerJython's micro:bit documentation).

 

 

API DOCUMENTATION OF MODULE mb7seg

 

Module import:
from mb7seg import FourDigit
(*) not available in module mb7segmin

Class FourDigit

 Constructor/Methods  Action
 FourDigit() creates a display instance with default values:
Clock port: P0, Data port: P1, Brightness: 4
 show(text, pos = 0) writes text with first characters at the given position (0: digit
far left, 3: rightmost digit). The text can be any length,
but only 4 characters are displayed. The text is saved and can be moved with toLeft() and toRight(). Integers are left justified
 setColon(True) shows/hides the colon
 (*)erase() deletes the text and the colon
 (*)toLeft() shifts the text one place to the left and returns the number of characters, that are not yet shown  on the right side
 (*)toRight() shifts the text one place to the right and returns the number of characters that are not yet shown on the left side
 (*)toStart() sets the text to the position where it was when show() was called
 (*)scroll(text) shows the text with the first character at position 0 and then scrolls the text to the left until all characters have been displayed (blocking method)
 (*)setLuminosity(lum)  sets the brightness to the given value (0..7)

 

11-1
Technical information:

Character set seven blessed display:

Display-mapping.pdf

3-2
Professional advice:

From the three acceleration components you can calculate pitch and roll angles as shown below. Start the following program and tilt the board sideways or forwards and backwards. In the terminal window, the values of pitch and roll are written out in degrees.

from microbit import *
from math import *

def getPitch():
    a = accelerometer.get_values()
    pitch = atan2(a[1], -a[2])
    return int(degrees(pitch))

def getRoll():
    a = accelerometer.get_values()
    anorm = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2])
    roll = asin(a[0] / anorm)
    return int(degrees(roll))
   
while True:
    pitch = getPitch()
    roll = getRoll()
    print("p: " + str(pitch))
    print("r: " + str(roll))
    print()
    sleep(100)