🏍️

micropythonでステッピングモーター 28BYJ-48を制御する書き方

2023/12/19に公開

28BYJ-48は安価なステッピングモーターです

3Dプリンタに使われるNemaと比べて性能的には劣りますが、電子工作にはよく使います

励磁方式

原理などは以下のサイトを参考
https://burariweb.info/electronic-work/arduino-learning/arduino-stepping-motor-control.html

1相励磁(waveモード)・・・4つあるコイルのうち、1つのコイルに電流を流し磁化(励磁)させる。
       最もシンプルな制御方式で、トルクは弱いが省電力
2相励磁(fullモード)・・・2つのコイルを同時にONする事により回転させる。
       1相励磁と比べて、強いトルクは得られるが、そのぶん消費電力も大きい
1-2相励磁(halfモード)・・・1相励磁と2相励磁を交互に繰り返す。
       1相励磁と2相励磁の動作角が半分になり、回転する角度を細かく制御することが可能

動かす

一番シンプルな1相励磁で動かしてみましょう。

pin1 = Pin(18,Pin.OUT)
pin2 = Pin(19,Pin.OUT)
pin3 = Pin(20,Pin.OUT)
pin4 = Pin(21,Pin.OUT)

for i in range(100):
   ## これで1ステップ
   pin1.on()
   pin2.off()
   pin3.off()
   pin4.off()
   sleep_ms(2)
   
   ## これで1ステップ
   pin1.off()
   pin2.on()
   pin3.off()
   pin4.off()
   sleep_ms(2)

   ## これで1ステップ
   pin1.off()
   pin2.off()
   pin3.on()
   pin4.off()
   sleep_ms(2)

   ## これで1ステップ
   pin1.off()
   pin2.off()
   pin3.off()
   pin4.on()
   sleep_ms(2)

回転速度をあげるには、各ステップごとのキープ時間を短くすれば良いのですが、最低2msはキープするようにしましょう。
(2ms未満にすると動かなくなります)

書き方としては、上記の書き方でも良いのですが、もう少し見やすくしましょう。

各ピンの出力をタプルにすると、以下のように短く書くことができます。

pins = (pin1, pin2, pin3, pin4)

set_pins = lambda vals: [pin.value(vals[i]) for i,pin in enumerate(pins)]

for i in range(100):
   set_pins((1,0,0,0))
   sleep_ms(2)

   set_pins((0,1,0,0))
   sleep_ms(2)

  set_pins((0,0,1,0))
   sleep_ms(2)

   set_pins((0,0,0,1))
   sleep_ms(2)

各ピンの値をタプルで書いたことで、2相励磁もわかりやすく書けます。

for i in range(100):
   set_pins((1,1,0,0))
   sleep_ms(2)

   set_pins((0,1,1,0))
   sleep_ms(2)

   set_pins((0,0,1,1))
   sleep_ms(2)

   set_pins((1,0,0,1))
   sleep_ms(2)

これでもまだ各ステップで同じようなことを書いているので、set_pinsの引数を関数とすることでもっと短く書くことができます。
(ただ、可読性を重視するなら上記の書き方で留めておいたほうが良いかも)

# waveモード
value_to_tuple= lambda val: tuple( int(i == val) for i in range(4)) 
# fullモード
value_to_tuple= lambda val: tuple( int( (i == val) or (i == val+1) or (i==0 and val==4)) for i in range(4))

for i in range(100):
    pin_values = value_to_tuple(i%4)
    set_pins(pin_values)
    sleep_ms(2)

まとめ

pin1 = Pin(18,Pin.OUT)
pin2 = Pin(19,Pin.OUT)
pin3 = Pin(20,Pin.OUT)
pin4 = Pin(21,Pin.OUT)


pins = (pin1, pin2, pin3, pin4)

set_pins = lambda vals: [pin.value(vals[i]) for i,pin in enumerate(pins)]

# 28BYJ-48ステッピングモーターのモーターは、1相励磁・2相励磁では32ステップで1回転。1-2相励磁では64ステップで1回転
# ギア比64なので、1相励磁・2相励磁では32*64=2048ステップで1回転、1-2相励磁では64*64=4096ステップで1回転

rotate = 1/4
clockwise = True
tim = 2 # 2以上

# wave=1相励磁、full=2相励磁(トルクと消費電力大)、half=1-2相励磁(より細かいステップサイズを指定できる)
# モードに合わせてコメントアウト
value_to_tuple= lambda val: tuple( int(i == val) for i in range(4)) # waveモード
#value_to_tuple= lambda val: tuple( int( (i == val) or (i == val+1) or (i==0 and val==4)) for i in range(4)) # fullモード

for i in range(rotate*2048):
    pin_values = value_to_tuple(i%4)
    if not clockwise:
      pin_values = tuple(reversed(pin_values))
    set_pins(pin_values)
    sleep_ms(tim)

# 各ピンをオフにすることで、トルク解放できる
set_pins((0,0,0,0))

Discussion