LoginSignup
1
2

More than 3 years have passed since last update.

ESP32 - MicroPythonを使い、ステッピングモータを制御する

Posted at

はじめに

ステッピングモータを使いたくなったので、購入をしました。
Arduinoスケッチで制御している記事は多くあるのですが、
MicroPythonで制御しているものがなかったので、
紹介させていただきます。

out_sp1.gif

作業環境

  • ホストPC
    • windows10 64bit Home
    • VSCode - 1.47.3
    • NodeJS - 12.14.1 LTS
  • ターゲットボード
    • ESP32-WROOM-32 開発ボード
    • MicroPython 1.12(esp32-idf4-20191220-v1.12.bin)

ESP32におけるMicroPythonの環境構築は、以前記載した
- [備忘録]ESP32-VSCode-microPythonでの開発環境の構築
を参考にしてください。

機材

部品名 説明 備考
ESP32-WROOM-32 開発ボード 5V
ステッピングモーター 型番:28BYJ-48、12V駆動 購入先Amazon
ULN2003ステッピングモーター駆動テストモジュールボード モータ駆動のためのボード モータとセット買い
DCアダプタ 12V モータが12V駆動のため 購入先Amazon
ジャンパーケーブル 10本程度

接続

部品名 説明 備考
ESP32-PIN25 テストモジュールボード - IN1 -
ESP32-PIN26 テストモジュールボード - IN2 -
ESP32-PIN27 テストモジュールボード - IN3 -
ESP32-PIN13 テストモジュールボード - IN4 -
ACアダプタ - GND テストモジュールボード - GND ESP32-GND
ACアダプタ - 12V テストモジュールボード - 12V
テストモジュールボード - モータコネクタ ステッピングモータ -

setuzoku.PNG

コードの作成

Arduino - StepperライブラリをベースにMicroPythonに移植します。

本ライブラリをベースしようと思ったのは、

  • Arduinoサイトでよく使われているため、極力インタフェースを同じにしたい
  • (そこまで)シビアなタイミングがない

となります。

また、本家との違いは以下となります。

  • stop()メソッドを追加している
  • step()にて、動作させた後、stop()メソッドをコール
    • 本家のライブラリでは、ユーザが能動的にstopさせないと常に電流が流れ続ける
    • 熱くなってしまうので、stop()をコールしている
  • 5pinモータ機能を削除
    • 今回は4pin構成なので、5pin部分は移植なし

ステッピングモータを制御するためのコード

以下がステッピングモータを制御するためのクラスとなります。

stepper.py
import time
from machine import Pin


class Stepper():
    def __init__(self,  number_of_steps,
                 motor_pin_1, motor_pin_2, motor_pin_3, motor_pin_4):
        self.step_number = 0                   # which step the motor is on
        self.direction = 0                     # motor direction
        self.last_step_time = 0                # time stamp in us of the last step taken
        self.number_of_steps = number_of_steps  # total number of steps for this motor

        # setup the pins on the microcontroller:
        self.motor_pin_1 = Pin(motor_pin_1, Pin.OUT)
        self.motor_pin_2 = Pin(motor_pin_2, Pin.OUT)
        self.motor_pin_3 = Pin(motor_pin_3, Pin.OUT)
        self.motor_pin_4 = Pin(motor_pin_4, Pin.OUT)

        # pin_count is used by the stepMotor() method:
        self.pin_count = 4

        self.set_speed()
        return

    def set_speed(self, what_speed=10):
        ''' Sets the speed in revs per minute
        '''
        self.step_delay = 60 * 1000 * 1000 // self.number_of_steps // what_speed
        return

    def step(self, steps_to_move, auto_stop=True):
        ''' Moves the motor steps_to_move steps.  If the number is negative,
            the motor moves in the reverse direction.
        '''
        steps_left = abs(steps_to_move)  # how many steps to take

        # determine direction based on whether steps_to_mode is + or -:
        self.direction = 1 if steps_to_move > 0 else 0

        # decrement the number of steps, moving one step each time:
        while steps_left > 0:
            now = time.ticks_us()
            # move only if the appropriate delay has passed:
            if time.ticks_diff(now, self.last_step_time) >= self.step_delay:
                # get the timeStamp of when you stepped:
                self.last_step_time = now
                # increment or decrement the step number,
                # depending on direction:
                if self.direction == 1:
                    self.step_number += 1
                    if self.step_number == self.number_of_steps:
                        self.step_number = 0
                else:
                    if self.step_number == 0:
                        self.step_number = self.number_of_steps
                    self.step_number -= 1

                # decrement the steps left:
                steps_left -= 1
                # step the motor to step number 0, 1, 2, 3
                self._step_motor(self.step_number % 4)

        if auto_stop:
            self.stop()
        return

    def _step_motor(self, this_step):
        ''' Moves the motor forward or backwards.
              if (this->pin_count == 4) {
        '''
        # 1010
        if this_step == 0:
            self.motor_pin_1.value(True)
            self.motor_pin_2.value(False)
            self.motor_pin_3.value(True)
            self.motor_pin_4.value(False)
        # 0110
        elif this_step == 1:
            self.motor_pin_1.value(False)
            self.motor_pin_2.value(True)
            self.motor_pin_3.value(True)
            self.motor_pin_4.value(False)
        # 0101
        elif this_step == 2:
            self.motor_pin_1.value(False)
            self.motor_pin_2.value(True)
            self.motor_pin_3.value(False)
            self.motor_pin_4.value(True)
        # 1001
        elif this_step == 3:
            self.motor_pin_1.value(True)
            self.motor_pin_2.value(False)
            self.motor_pin_3.value(False)
            self.motor_pin_4.value(True)
        return

    def stop(self):
        self.motor_pin_1.value(False)
        self.motor_pin_2.value(False)
        self.motor_pin_3.value(False)
        self.motor_pin_4.value(False)
        return

使い方

使用するための準備

>> from stepper import Stepper

>> MOTOR_STEPS = (2048)
>> PIN_MOTOR_1 = (25)
>> PIN_MOTOR_2 = (26)
>> PIN_MOTOR_3 = (27)
>> PIN_MOTOR_4 = (13)

>> my_motor = Stepper(MOTOR_STEPS, PIN_MOTOR_1,
                   PIN_MOTOR_3, PIN_MOTOR_2, PIN_MOTOR_4)
>> my_motor.set_speed(10)

回転させる

my_moter.step(512)
# =>ステッピングモータが90度、時計回りに回転
my_moter.step(2048)
# =>ステッピングモータが360度、時計回りに回転
my_moter.step(-512)
# =>ステッピングモータが90度、反時計回りに回転
  • MOTOR_STEPSを2048としているため、一回転あたり2048となる
  • step()にマイナス方向を指定すると反時計回りになる
  • set_speed()には、1-20あたりまでが有効

さいごに

  • 現状、回転を実行すると、止めることができません

参考

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2