RP2040-UNOまたはSTM32-UNOにDML-STACK3Vを接続した場合を例として、MicroPythonでのDML-STACKのプログラミング例を紹介します。

これらのプログラミング例は、RP2040-UNOに弊社のMicroPythonのファームウェアを書き込んでいることを前提としています。
このページの目次
ドットマトリックスLEDの全点点灯
DML-STACKのドットマトリックスLEDは、操作に必要な信号線を削減するために、ダイナミック表示方式を取っています。このため、信号線の単純な操作では、横一列の8個のLEDのみを点灯させることができません。
まずは、ダイナミック表示方式で、ドットマトリックスLEDを全点点灯させる例を示します。
from machine import Pin
import time
# ドットマトリックスLEDのカラム端子を出力に設定
col = []
for i in range(2,5):
col.append(Pin('D'+str(i), Pin.OUT))
# ドットマトリックスLEDのロウ端子を出力に設定
row = []
for i in range(5,13):
row.append(Pin('D'+str(i), Pin.OUT))
for i in range(0,8):
row[i].off()
# 表示するカラムを高速に切り替えダイナミック表示を行う
while True:
for i in range(0,8):
col[0].value(i & 1)
col[1].value(i & 2)
col[2].value(i & 4)
time.sleep_ms(2)
最後の行のsleep_ms()の引数2を1000などの大きな数に変更すると、横一列の8個のLEDずつ点灯され、点灯される列が順番に切り替わる様子を確認できます。
ドット絵の表示
上記の例では、ドットマトリックスのすべてのLEDを点灯させましたが、任意のLEDの点灯・消灯を個別に制御する方法を示します。具体的には、単純な8x8ドットのモノクロのドット絵のデータを0,1で定義したデータ配列を定義し、0は消灯、1は点灯でLEDの表示を行う例を示します。
from machine import Pin
import array
import time
# ドットマトリックスに表示するデータバッファ
matrix = array.array('B',
[
0b00111100,
0b01000010,
0b10100001,
0b11010111,
0b10000101,
0b10111001,
0b01000010,
0b00111100 ])
# ドットマトリックスLEDのカラム端子を出力に設定
col = []
for i in range(2,5):
col.append(Pin('D'+str(i), Pin.OUT))
# ドットマトリックスLEDのロウ端子を出力に設定
row = []
for i in range(5,13):
row.append(Pin('D'+str(i), Pin.OUT))
while True:
for i in range(0,8):
for r in range(0,8): # いったん全灯消灯
row[r].on()
col[0].value(i & 1) # 表示対象行を変更
col[1].value(i & 2)
col[2].value(i & 4)
for r in range(0,8): # 新たな行に対応した点灯データを設定
row[r].value(not (matrix[7-i] & (1 << (7-r))))
time.sleep_ms(2)
matrixに記録されるデータの0,1を書き換えることにより、望みの絵を表示させることができます。この場合も、最後のsleep_ms()の2を大きな数に変更することにより、ドット絵の横一列の8個のLEDずつ点灯され、点灯される列が順番に切り替わる様子を確認できます。
文字表示
A,B,Cの3種類だけですが、ドットマトリックスLEDに文字を表示させる例を示します。
from machine import Pin
import array
import time
# ドットマトリックスに表示するデータバッファ
matrix = array.array('B',
[0, 1, 3, 7, 15, 31, 63, 127])
# フォントデータ
font = array.array('B',
[0b00010000, # A
0b00101000,
0b01000100,
0b01000100,
0b01111100,
0b01000100,
0b01000100,
0b00000000,
0b01111000, # B
0b01000100,
0b01000100,
0b01111000,
0b01000100,
0b01000100,
0b01111000,
0b00000000,
0b00111000, # C
0b01000100,
0b01000000,
0b01000000,
0b01000000,
0b01000100,
0b00111000,
0b00000000,
])
# フォントデータを表示バッファに書き込む
def set_font(n):
for i in range(0,8):
matrix[i] = font[n*8+i]
# ドットマトリックスLEDのカラム端子を出力に設定
col = []
for i in range(2,5):
col.append(Pin('D'+str(i), Pin.OUT))
# ドットマトリックスLEDのロウ端子を出力に設定
row = []
for i in range(5,13):
row.append(Pin('D'+str(i), Pin.OUT))
fi = 0
ct = time.ticks_ms() // 1000
while True:
lt = ct
ct = time.ticks_ms() // 1000
if lt != ct: # 1秒に1回
set_font(fi)
fi += 1
if fi > 2:
fi = 0
for i in range(0,8):
for r in range(0,8):
row[r].on()
col[0].value(i & 1)
col[1].value(i & 2)
col[2].value(i & 4)
for r in range(0,8):
row[r].value(not (matrix[7-i] & (1 << (7-r))))
time.sleep_ms(2)
ボールの表示
ボール(点)を表示する例を示します。ドットマトリックスLEDの左上を原点として、指定した座標のLEDを点灯させる方法が確認できます。
from machine import Pin
import array
import time
# ドットマトリックスに表示するデータバッファ
matrix = array.array('B',
[0, 1, 3, 7, 15, 31, 63, 127])
def display_ball(x, y):
for i in range(0,8): # まず全灯消灯
matrix[i] = 0
matrix[y] = 1 << x # 指定座標のLEDを点灯
# ドットマトリックスLEDのカラム端子を出力に設定
col = []
for i in range(2,5):
col.append(Pin('D'+str(i), Pin.OUT))
# ドットマトリックスLEDのロウ端子を出力に設定
row = []
for i in range(5,13):
row.append(Pin('D'+str(i), Pin.OUT))
# 左上が原点、座標値を変えて表示を確認して!
display_ball(0,0)
while True:
for i in range(0,8):
for r in range(0,8):
row[r].on()
col[0].value(i & 1)
col[1].value(i & 2)
col[2].value(i & 4)
for r in range(0,8):
row[r].value(not (matrix[7-i] & (1 << r)))
time.sleep_ms(2)
display_ball(x,y)の引数を変更して、指定した座標のLEDが点灯することを確認してみてください。
ボールの移動操作:スイッチと圧電スピーカーの利用
表示されているボールを、スイッチを使って移動操作するプログラムを示します。
- sw1を押すと上に、sw3を押すと下に移動
- sw2を押した状態で、sw1を押すと左に、sw3を押すと右に移動
スイッチの初期化の際には、入力に設定するだけでなく内部プルアップも有効にします。これは、スイッチが接続されているA0-A2の信号線に外部プルアップ抵抗が接続されていないためです。外部プルアップ抵抗が接続されていないため、今回のプログラムと異なりスイッチを使用しないのであれば、A0-A2はデジタル入出力や、アナログ入力に使用することができます。(信号線を取り出しにくいですが…)
このプログラムでは、ボールがドットマトリックスLEDの上下左右の端にぶつかるとビープ音を出すようにしています。
from machine import Pin
import array
import sys
import time
from tone import TONE
if sys.platform.startswith('rp2'):
snd = TONE('A3') #RP2040-UNO
else:
snd = TONE('PA7') # STM32-UNO
# ドットマトリックスに表示するデータバッファ
matrix = array.array('B',
[0, 1, 3, 7, 15, 31, 63, 127])
def display_ball(x, y):
for i in range(0,8):
matrix[i] = 0
matrix[y] = 1 << x
# ドットマトリックスLEDのカラム端子を出力に設定
col = []
for i in range(2,5):
col.append(Pin('D'+str(i), Pin.OUT))
# ドットマトリックスLEDのロウ端子を出力に設定
row = []
for i in range(5,13):
row.append(Pin('D'+str(i), Pin.OUT))
sw1 = Pin('A0', Pin.IN, Pin.PULL_UP) # 内部プルアップを有効化
sw2 = Pin('A1', Pin.IN, Pin.PULL_UP)
sw3 = Pin('A2', Pin.IN, Pin.PULL_UP)
bx = 3
by = 3
ct = time.ticks_ms() // 50
while True:
# ボールの位置の更新
lt = ct
ct = time.ticks_ms() // 50
if lt != ct: # 0.05秒に1回
if (sw1.value() == False) and (sw2.value() == False):
bx += 1
if bx > 7:
snd.on(1000)
bx = 7
time.sleep_ms(5)
snd.off()
elif (sw3.value() == False) and (sw2.value() == False):
bx -= 1
if bx < 0:
snd.on(1000)
bx = 0
time.sleep_ms(5)
snd.off()
if (sw1.value() == False) and (sw2.value() == True):
by += 1
if by > 7:
snd.on(1000)
by = 7
time.sleep_ms(5)
snd.off()
elif (sw3.value() == False) and (sw2.value() == True):
by -= 1
if by < 0:
snd.on(1000)
by = 0
time.sleep_ms(5)
snd.off()
display_ball(bx,by)
# ダイナミック表示処理
for i in range(0,8):
for r in range(0,8):
row[r].on()
col[0].value(i & 1)
col[1].value(i & 2)
col[2].value(i & 4)
for r in range(0,8):
row[r].value(not (matrix[7-i] & (1 << r)))
time.sleep_ms(2)
ボールの跳ね返り
ドットマトリックスLED内で、ボールを壁で跳ね返らせ、壁に当たるたびに衝突音を出す例を示します。
from machine import Pin
import array
import sys
import time
from tone import TONE
if sys.platform.startswith('rp2'):
snd = TONE('A3') #RP2040-UNO
else:
snd = TONE('PA7') # STM32-UNO
# ドットマトリックスに表示するデータバッファ
matrix = array.array('B',
[0, 1, 3, 7, 15, 31, 63, 127])
def display_ball(x, y):
for i in range(0,8):
matrix[i] = 0
matrix[y] = 1 << x
# ドットマトリックスLEDのカラム端子を出力に設定
col = []
for i in range(2,5):
col.append(Pin('D'+str(i), Pin.OUT))
# ドットマトリックスLEDのロウ端子を出力に設定
row = []
for i in range(5,13):
row.append(Pin('D'+str(i), Pin.OUT))
bx = 0
dx = 0.6
by = 0
dy = 0.4
ct = time.ticks_ms() // 50
while True:
# ボールの位置の更新
lt = ct
ct = time.ticks_ms() // 50
if lt != ct: # 0.05秒に1回
bx += dx
by += dy
if (bx > 8) or (bx < 0):
snd.on(1000)
dx = -dx
bx += dx
time.sleep_ms(5)
snd.off()
if (by > 8) or (by < 0):
snd.on(1000)
dy = -dy
by += dy
time.sleep_ms(5)
snd.off()
display_ball(int(bx),int(by))
# ダイナミック表示処理
for i in range(0,8):
for r in range(0,8):
row[r].on()
col[0].value(i & 1)
col[1].value(i & 2)
col[2].value(i & 4)
for r in range(0,8):
row[r].value(not (matrix[7-i] & (1 << r)))
time.sleep_ms(2)
ボールの転がり:加速度センサーの利用
DML-STACKに搭載されている加速度センサーを利用して、基板を傾けた方にボールが転がる例を示します。
from machine import Pin, I2C
import array
import sys
import time
from kxtj3 import KXTJ3
from tone import TONE
i2c = I2C(1)
acc = KXTJ3(i2c)
if sys.platform.startswith('rp2'):
snd = TONE('A3') #RP2040-UNO
else:
snd = TONE('PA7') # STM32-UNO
# ドットマトリックスに表示するデータバッファ
matrix = array.array('B',
[0, 1, 3, 7, 15, 31, 63, 127])
def display_ball(x, y):
for i in range(0,8):
matrix[i] = 0
matrix[y] = 1 << x
# ドットマトリックスLEDのカラム端子を出力に設定
col = []
for i in range(2,5):
col.append(Pin('D'+str(i), Pin.OUT))
# ドットマトリックスLEDのロウ端子を出力に設定
row = []
for i in range(5,13):
row.append(Pin('D'+str(i), Pin.OUT))
bx = 0
by = 0
ct = time.ticks_ms() // 50
while True:
# ボールの位置の更新
lt = ct
ct = time.ticks_ms() // 50
if lt != ct: # 0.05秒に1回
vacc = acc.getXYZ()
ax = int(vacc[0] / 32768 * 255) # 最大変位量を255に
ay = int(vacc[1] / 32768 * 255)
if ay < -10:
bx += 1
if bx > 7:
snd.on(1000)
bx = 7
time.sleep_ms(5)
snd.off()
elif ay > 10:
bx -= 1
if bx < 0:
snd.on(1000)
bx = 0
time.sleep_ms(5)
snd.off()
if ax > 10:
by += 1
if by > 7:
snd.on(1000)
by = 7
time.sleep_ms(5)
snd.off()
elif ax < -10:
by -= 1
if by < 0:
snd.on(1000)
by = 0
time.sleep_ms(5)
snd.off()
display_ball(int(bx),int(by))
# ダイナミック表示処理
for i in range(0,8):
for r in range(0,8):
row[r].on()
col[0].value(i & 1)
col[1].value(i & 2)
col[2].value(i & 4)
for r in range(0,8):
row[r].value(not (matrix[7-i] & (1 << r)))
time.sleep_ms(2)
タイマー割り込みの利用
ドット絵の表示
ダイナミック表示の表示行の更新処理をタイマー割り込みで行う例を示します。
from machine import Pin, Timer
import array
import time
# ドットマトリックスに表示するデータバッファ
matrix = array.array('B',
[
0b00111100,
0b01000010,
0b10000001,
0b11101111,
0b10000001,
0b10100101,
0b01011010,
0b00111100 ])
# ドットマトリックスLEDのカラム端子を出力に設定
col = []
for i in range(2,5):
col.append(Pin('D'+str(i), Pin.OUT))
# ドットマトリックスLEDのロウ端子を出力に設定
row = []
for i in range(5,13):
row.append(Pin('D'+str(i), Pin.OUT))
rowix = 0
def dml_refresh(t):
global col, row, rowix, matrix
for r in range(0,8): # いったん全灯消灯
row[r].on()
col[0].value(rowix & 1) # 表示対象行を変更
col[1].value(rowix & 2)
col[2].value(rowix & 4)
for r in range(0,8): # 新たな行に対応した点灯データを設定
row[r].value(not (matrix[7-rowix] & (1 << (7-r))))
rowix += 1
if rowix > 7:
rowix = 0
timer = Timer()
timer.init(period=2, callback=dml_refresh)
文字の表示
from machine import Pin, Timer
import array
import time
# ドットマトリックスに表示するデータバッファ
matrix = array.array('B',
[0, 1, 3, 7, 15, 31, 63, 127])
# ドットマトリックスLEDのカラム端子を出力に設定
col = []
for i in range(2,5):
col.append(Pin('D'+str(i), Pin.OUT))
# ドットマトリックスLEDのロウ端子を出力に設定
row = []
for i in range(5,13):
row.append(Pin('D'+str(i), Pin.OUT))
rowix = 0
def dml_refresh(t):
global col, row, rowix, matrix
for r in range(0,8): # いったん全灯消灯
row[r].on()
col[0].value(rowix & 1) # 表示対象行を変更
col[1].value(rowix & 2)
col[2].value(rowix & 4)
for r in range(0,8): # 新たな行に対応した点灯データを設定
row[r].value(not (matrix[7-rowix] & (1 << (7-r))))
rowix += 1
if rowix > 7:
rowix = 0
# ここまでは前のプログラムと同じ
# フォントデータ
font = array.array('B',
[0b00010000, # A
0b00101000,
0b01000100,
0b01000100,
0b01111100,
0b01000100,
0b01000100,
0b00000000,
0b01111000, # B
0b01000100,
0b01000100,
0b01111000,
0b01000100,
0b01000100,
0b01111000,
0b00000000,
0b00111000, # C
0b01000100,
0b01000000,
0b01000000,
0b01000000,
0b01000100,
0b00111000,
0b00000000,
])
timer = Timer()
timer.init(period=2, callback=dml_refresh)
# フォントデータを表示バッファに書き込む
def set_font(n):
for i in range(0,8):
matrix[i] = font[n*8+i]
fi = 0
while True:
set_font(fi)
fi += 1
if fi > 2:
fi = 0
time.sleep_ms(1000)
関連製品
DML-STACK
RP2040-UNO
STM32-UNO
STM32-UNOには、MCUの異なるいくつかの開発ボードがあります。どの開発ボードも同様にDML-STACKのプログラミングを楽しむことができます。