mbedの基本的なI/O方法と実例。
この記事ではエンコーダの読み出しを行います。
興味があるところを読む
エンコーダを使う
元々はSHで使ってたのをチョイ改造してmbed用にした。
ハードウエアでチャタリングを取る回路を入れるのが面倒なので、インターバルタイマーで読み出すタイプ。
手動のエンコーダ程度ならこれで十分動く。
使ったエンコーダは秋月の3色LEDと押しボタンSW内蔵のタイプ(LEDとSWは使ってない)。
プログラムは例によって「結果オーライ」タイプ。
動いてるから良しとしよう(^^;
正統派の理屈や美しいプログラムはELMさんのところにあります。ELMさんの作る物は美しい、素晴らしい。
DigitalIn DGI_EncA(p30); // A相
DigitalIn DGI_EncB(p29); // B相
Ticker TimerIntr; // タイマー割込み(1mSで使用)
// 1mSごとに実行される関数
static void TimerLoop(void)
{
EncRead(); // エンコーダ読み出し
}
// エンコーダの状態を読んで変数にセットする
#define _ENCRESET 1000000UL // マイナスにしないため適当にでかい値をセット
static volatile ulong _encCnt = _ENCRESET;
static void EncClr(void)
{
_encCnt = _ENCRESET;
}
static ulong EncGet(void)
{
return _encCnt / 4UL;
}
// インターバルタイマーで1mSごとに実行する
static void EncRead(void)
{
static BYTE old;
BYTE pd = (BYTE)(DGI_EncA | (DGI_EncB << 1));
// 時計回り
if (old==0x0 && pd==0x2) --_encCnt;
else if (old==0x2 && pd==0x3) --_encCnt;
else if (old==0x3 && pd==0x1) --_encCnt;
else if (old==0x1 && pd==0x0) --_encCnt;
// 反時計回り
if (old==0x0 && pd==0x1) ++_encCnt;
else if (old==0x1 && pd==0x3) ++_encCnt;
else if (old==0x3 && pd==0x2) ++_encCnt;
else if (old==0x2 && pd==0x0) ++_encCnt;
old = pd;
}
// 動作テスト用
void main(void)
{
TimerIntr.attach_us(&TimerLoop, 1000.0f);
EncClr();
ulong encCnt = EncGet();
while (1) {
long p = EncGet() - encCnt;
if (p < 0) { // Encが左回転したら・・・
;
} else if (p > 0) { // Encが右回転したら・・・
;
}
encCnt = EncGet();
}
}
mbedの使い方|エンコーダを使う2|マイコン入門
mbedの基本的なI/O方法と実例。この記事ではエンコーダ(ハードウエアでチャタリングを取ったタイプ)の読み出しを行います。 【エンコーダを使う2】 今回はハードウ…
コメント