稼働中

マイクロビット(e_42)フォトインタラプタ GR-YM-227

GR-YM-227(フォトインタラプタ)

前回、micro:bitを使ってDCモータを動かして正転、逆転の基本動作を確認しました。
モータの回転数を測定しようとフォトインタラプタセンサーモジュールGR-YM-227を入手しました。
フォトインタラプタだけでも良かったのですが、エンコーダやケーブルも付属しているのでモジュールを買いました。
メーカーはよくわからない「Youmile」とありました。とりあえず動作確認をしたので記載します。

GR-YM-227

フォトインタラプタは発光素子と受光素子を持ったデバイスで、物体による光の遮断を検出します。
GR-YM-227の場合、透過ならHIGH、遮光ならLOWを出力します。
外観
GR-YM-227の外観です。他にケーブルやエンコーダ(20個のスリット付き円板)も付属してます。
GR-YM-227 外観 GR-YM-227 外観

接続例

前回のTA7291Pを使ったDCモータ動作に使った接続にGR-YM-227(フォトインタラプタモジュール)を加えただけです。
GR-YM-227の電源はmicro:bitの3.3V出力を使いました。GR-YM-227の出力をmicro:bitのピン8に接続しました。
TA7291Pなどの接続は前回の記事を参照ください。
接続例
※micro:bitのピン配置図は「https://tech.microbit.org/hardware/edgeconnector/」からの引用です。

実体図

使用したDCモータはギヤードモータDG01Dです。
実体図
エンコーダ(20個スリット円板)をモータの車軸に止めました。フォトインタラプタは両面テープでモータに固定した。写真ではエンコーダのスリットに合っているのでモジュールの赤のチップLEDが点灯している状態です。
取付状態

スクリプト

GR-YM-227の出力による無負荷のDG01Dモータのperiodをmicro:bitで測定しました。
スクリプトは以下のようにしました。※thonny-microbitのMicroPythonを使っています。


dcm_encode_test_01b.py
from microbit import *
import machine
# 正転 PWM値を変えてエンコーダのPeriod値測定
HS=pin6       # PWM >> TP7291P IN1
LS=pin7       # PWM >> TP7291P IN2
EN=pin8       # ISO_ encoder-out pin8 エラーが出るようならpin0等に変更してみて下さい。
# FWD IN1(H/PWM)IN2(L/0) 正転
def FWD(pwm):
    LS.write_analog(0)            # analogモード、出力は’0’V
    HS.set_analog_period(20)      # 周期を設定 20msec
    HS.write_analog(pwm)          # 0 ~ 1023  128~
    sleep(5)                      # 切替100us~
def STP():
    HS.write_digital(0) # IN1
    LS.write_digital(0) # IN1
    sleep(5)
# pin6,7を使うのでdisplayをオフ
display.off()
cnt=0                       # 繰返し回数
STP()                       # 停止

EN.set_pull(EN.PULL_DOWN)   # time_pulse_us測定 ピンの使用予約
s_time=running_time()       # ここの時間 START時間

FWD(256)                    # PWM値で正転

while True:
    cnt=cnt+1
    sleep(200)
    d = machine.time_pulse_us(EN,1)   # Ton時間測定
    c_time=running_time()             # ここの時間
    d_time=(c_time-s_time)            # 経過時間(動作時間)
    # 回数、動作時間(msec)、測定したperiod周期(usec)
    print('%3d' %cnt,'%5.1f' % float(d_time/1000),'%6.1f' % float(d/1000) ) # msec
    # 動作時間が以下の設定時間を超えれば終了 60*1000=60sec
    if d_time > (60*1000):
        print('break')
        break
print('END')
STP()

periodの測定は machine.time_pulse_us(pin,1) でパルスのHighの持続時間を測定しています。
前回のDCモータを動かすスクリプトを正転、停止動作の部分を抜粋して使っています。※詳細は前回のスクリプトを参照下さい。

実行結果

FWD(256)で10sec動作させてperiod周期を測定しました。バラツキますが測定できています。
Thonnyのshellに表示された結果です。


>>> %Run dcm_encode_test_01b.py
  1   0.3   74.1        # 回数、動作時間(msec)、測定したperiod周期(msec)
  2   0.5   56.6
  3   0.8   51.9
  4   1.1   35.4
  5   1.3   27.1
  6   1.5   31.7
省略

 43   9.9    9.5
 44  10.1   21.3
break
END
>>> 

PWM値を変えて10sec間測定したperiod周期を平均してグラフ化してみました。
period-pwm

periodの制御

PWM値を指定して一定の回転数を得るのではなく、periodを指定してモータを回転させたいと思います。
periodを測定しながら指定のperiod値に合わせて行きます。

スクリプト

スクリプトは以下のようにしました。


from microbit import *
import machine
# 正回転だけでperiod測定テスト
HS=pin6       # PWM >> TP7291P IN1
LS=pin7       # PWM >> TP7291P IN2
EN=pin8       # pTr_ encoder-out pin8 msec 差分
    
    # 差分に対して加減するPWM値
    add=int( abs(dif) * mag)          # mag k減算の倍率
    
    if (d==-2 ) or (d==-1):
        dat=lpw+10*c_ng   # ギリ動く エラー回数でPWM値を増やす
        print(cnt, 'error', d, dat)
        c_ng=c_ng+1
        continue
    
    if abs(dif) < 2:   # muhannou iki  differnce msec
        # 回数、コメント、period(usec)、PWM値、加減値、差分
        print(cnt,'cont', d, dat, add, dif)
        continue
    # 測定値の方が小さい・・遅くする・・pwmをUP
    # 減算後が下限PWM値以下なら下限値にする
    if dif > 0 :
        dat=dat-add
        if dat < lpw:
            dat=lpw   # giri ugoku
        # 回数、コメント、period(usec)、PWM値、加減値、差分
        print(cnt,'dif>0', d, dat, add, dif)
    # 加算後がPWM値1023超えなら上限1023にする
    else:
        dat=dat+add
        if dat > 1023:
            dat=1023
        print(cnt,'dif<0',d, dat, add, dif)

    # 動作時間が以下の設定時間を超えれば終了 
    if d_time > (60*1000):          # 60sec--------(3)
        print(cnt,'break')
        break
print('END')
STP()               # 停止

部分説明

(1)差分にmag値を掛けてPWM値を加減算します。
(2)目標値TGT(period)
(3)動作時間
(4)結果的にコメントアウト部分を追加

実行結果

以下の結果はmag(1/5)、TGT(50msec)、動作時間(3)を15secにしています。
Thonnyのshellに表示された結果


>>> %Run dcm_encode_cont_02b.py
1 error -1 128                  # timeout エラー続くならpin8をpin0などに変更
2 error -1 138
3 dif>0 25758 134 4 24          # 回数、コメント、period(usec)、PWM値、加減値、差分
4 error -1 148
5 dif<0 90852 155 7 -40         # どうにか動き出す
6 dif<0 331967 211 56 -281      # 差分-281/5=56.2=56が加減値、前回の155+56=211のPWM値を送る
7 dif<0 72290 215 4 -22
省略
46 cont 50466 191 0 0           # 目標値に近づいている
47 cont 48851 191 0 1
48 dif<0 54294 191 0 -4 48 break END >>> 

動作例

mag(1/5)、TGT(50msec)、動作時間15sec
まあまあ制御しているような感じ。

mag(5)、TGT(50msec)、動作時間15sec
制御できない状態になっています。

もう少し動作を確認

動作時間を60secにしてTGT(50msec)でmag(1/5)、mag(5)を測定してグラフ化してみました。
mag(1/5)では、ほぼ50msecに制御できていると思います。mag(5)では遅発振のような状態で制御できていません。
50msecのperiodに制御するにはmag値は1/5が良さそうです。
グラフ1
グラフ2

次に回転数の早いTGT(10msec)でmag(1/5)、mag(5)を測定してグラフ化してみました。
mag(1/5)ではPWM値は一定値になっていますが、実際のperiodはばらついて制御が不十分です。
mag(5)では、ほぼ10msecに制御できているようです。10msecのperiodに制御するにはmag値は5が良さそうです。
グラフ3
グラフ4
この結果から、目標値によってmag値を分け(4)部を追加しました。コメントアウトを外して使います。
もう一段の場合分けを追加するとさらに制御性が上がるかも知れません。

まとめ

フォトインタラプタセンサーモジュール(GR-YM-227)を使って、DCモータの回転をmicro:bitで制御することが出来たと思います。