28BYJ-48って何?
これのことです。
Ren He 5V ステッピングモータ+ 28BYJ-48 ULN2003ドライバーボード セット Arduino用 3個セット
https://www.amazon.co.jp/Ren-He-%E3%82%B9%E3%83%86%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0%E3%83%A2%E3%83%BC%E3%82%BF-28BYJ-48-ULN2003%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89/dp/B07LBRNZB6
28BYJ-48
というステッピングモーターと、ULN2003
なるトランジスタアレイとやらが搭載されたドライバーボードです。Arduino言語やMicroPythonにてこれを用いている作例はweb上でいくつか見つかるのですが、CircuitPythonでは見つかりませんでした。
そこで今回、これをCircuitPythonでどうにか動かすためのライブラリを書いてみましたので、備忘録も兼ねてこちらに置いておこうと思います。
コード
その手作りライブラリがこちら。
import digitalio, time
"""
このステッピングモーターの場合、
1ステップは`5.625° /64`なようなので、
64ステップで`5.625°`、
512ステップで`45°`、
4096ステップで`360°`、即ち1周分となります。
"""
deg45 = 512
deg90 = 1024
deg180 = 2048
deg360 = 4096
class stepper:
def __init__(self, IN1, IN2, IN3, IN4):
self.DIG_OUT = [
digitalio.DigitalInOut(pin) for pin in [IN1, IN2, IN3, IN4]
]
for p in self.DIG_OUT:
p.direction = digitalio.Direction.OUTPUT
self.SEQ_CLOCK = [
[1, 0, 0, 1],
[1, 0, 0, 0],
[1, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 1, 0],
[0, 0, 1, 0],
[0, 0, 1, 1],
[0, 0, 0, 1]
]
self.POSITION = 0
self.STEP_COUNT = len(self.SEQ_CLOCK)
self.STEP_DIR = 1
self.STEP_COUNTER = 0
def rotate(self, clockwise=True, LIMIT=deg180):
COUNT = 0
SEQ = self.SEQ_CLOCK if clockwise else self.SEQ_CLOCK[::-1]
while COUNT < LIMIT:
COUNT += 1
for i in range(0, 4):
pin = self.DIG_OUT[i]
pin.value = SEQ[self.STEP_COUNTER][i] != 0
self.STEP_COUNTER += self.STEP_DIR
if self.STEP_COUNTER >= self.STEP_COUNT:
self.STEP_COUNTER = 0
if self.STEP_COUNTER < 0:
self.STEP_COUNTER = self.STEP_COUNT + self.STEP_DIR
# sleepを挟まないと、モーターが不穏な音をたてながらビクンビクン震えます。絶対に抜かないように。
time.sleep(0.0005)
self.POSITION += LIMIT if clockwise else (-1 * LIMIT)
def reset(self):
if self.POSITION < 0:
self.rotate(True, (-1 * self.POSITION) % deg360)
else:
self.rotate(False, self.POSITION % deg360)
これをこう!
import board, digitalio
# 先程のライブラリをインポート
from CPython_28BYJ48_ULN2003 import *
# タクトスイッチ
switch = digitalio.DigitalInOut(board.GP18)
switch.direction = digitalio.Direction.INPUT
switch.pull = digitalio.Pull.UP
motor = stepper(
board.GP14, # IN1に繋いでいるピン
board.GP15, # IN2
board.GP16, # IN3
board.GP17 # IN4
)
while True:
# タクトスイッチを押したとき
if not switch.value:
# (時計回りかどうか, ステップ数)
motor.rotate(False, deg45)
# 初期化時の位置に戻る
motor.reset()
サンプルコードの通りに動かすと、モーターは車のワイパーのような動きをします。
ドライバーにはIN1
, IN2
, IN3
, IN4
, VCC (+)
, GND (-)
がありますので、前者4つをデジタル出力が可能なピンに、後者2つを5Vの電源供給に繋げて下さい。