micro:bitで、ロータリーエンコーダを使うテストをしました。
これには、割り込みを使う方法と使わない方法があります。
今回は、後者の割り込みを使わない方法をテストします。
pin0とpin1をプルアップして、下の図のようにロータリーエンコーダを接続します。
ロータリーエンコーダを回すと、A,Bがずれながら、3.3Vと0Vを繰り返します。
そのパターンで回転方向を判定します。具体的な方法は、JH7UBCホームページのここで解説していますので、ご覧ください。
スクリプトです。ロータリーエンコーダを右側(時計回り)に回すとカウンタの値がUPし、左側(反時計回り)に回すとカウンタの値がDOWNします。その値は、シリアル通信でTeraTermに表示します。
-------------------------------------------
'''
micro:bit MicroPython ロータリーエンコーダ テスト
2019.12.06
JH7UBC Keiji Hata
'''
micro:bit MicroPython ロータリーエンコーダ テスト
2019.12.06
JH7UBC Keiji Hata
'''
from microbit import *
# シリアル通信初期化
uart.init(baudrate=9600, bits=8, parity=None, stop=1)
uart.init(baudrate=9600, bits=8, parity=None, stop=1)
# pin0とpin1をプルアップ
pin0.set_pull(pin0.PULL_UP)
pin1.set_pull(pin1.PULL_UP)
pin0.set_pull(pin0.PULL_UP)
pin1.set_pull(pin1.PULL_UP)
# ロータリーエンコーダ関係定義
befDat = 0
inputMatch = 0
matchCnt = 0
rotPat = 0
Count = 0
befDat = 0
inputMatch = 0
matchCnt = 0
rotPat = 0
Count = 0
# エンコーダの回転方向判定
def CheckEnc(dat):
global rotPat
rotPat <<= 2 # 左に2ビットシフト
rotPat &= 0xFF # 下位8ビットを取り出す
rotPat |= dat # datを加える
if rotPat == 0x4B:
return 1 # 時計回り(CW))
elif rotPat == 0x87:
return -1 # 反時計回り(CCW)
else:
return 0 # どちらでもない
def CheckEnc(dat):
global rotPat
rotPat <<= 2 # 左に2ビットシフト
rotPat &= 0xFF # 下位8ビットを取り出す
rotPat |= dat # datを加える
if rotPat == 0x4B:
return 1 # 時計回り(CW))
elif rotPat == 0x87:
return -1 # 反時計回り(CCW)
else:
return 0 # どちらでもない
# ロータリーエンコーダ初期値設定
if pin0.read_digital() == 0:
befDat |= 2
if pin1.read_digital() == 0:
befDat |= 1
if pin0.read_digital() == 0:
befDat |= 2
if pin1.read_digital() == 0:
befDat |= 1
while True:
# ロータリーエンコーダ処理
val = 0
curDat = 0
if pin0.read_digital():
curDat |= 2
if pin1.read_digital():
curDat |= 1
if befDat == curDat:
# befDatとcurDatが一致したときの処理
if inputMatch == 0:
matchCnt += 1
if matchCnt >= 2: # 2回以上一致したらフラッグを立てる
inputMatch = 1
val = CheckEnc(curDat)
if val != 0:
Count += val
uart.write(str(Count) + '\r\n')
else:
# befDatとcuDatが一致しなかった時の処理
sleep(1) # 1ms待つ
befDat = curDat
matchCnt = 0
inputMatch = 0
# ロータリーエンコーダ処理
val = 0
curDat = 0
if pin0.read_digital():
curDat |= 2
if pin1.read_digital():
curDat |= 1
if befDat == curDat:
# befDatとcurDatが一致したときの処理
if inputMatch == 0:
matchCnt += 1
if matchCnt >= 2: # 2回以上一致したらフラッグを立てる
inputMatch = 1
val = CheckEnc(curDat)
if val != 0:
Count += val
uart.write(str(Count) + '\r\n')
else:
# befDatとcuDatが一致しなかった時の処理
sleep(1) # 1ms待つ
befDat = curDat
matchCnt = 0
inputMatch = 0
-------------------------------------------
micro:bitにロータリーエンコーダを接続した様子です。
TeraTermの画面です。
時計回りに回してから、半時計回りに回しました。
良く動作します。
※コメント投稿者のブログIDはブログ作成者のみに通知されます