2016年5月19日木曜日

Nucleo F401RE(mbed)でRotary Encoderとタクトスイッチのチャタリング対策

ブレッドボード図

main.cpp

/*
 * Rotary Encoderとタクトスイッチのトグル動作のテスト
 *
 * 2016.05.19
 *
 */
#include "mbed.h"
#include "PinDetect.h"

Serial pc(SERIAL_TX, SERIAL_RX);  

PinDetect pin1(D2, PullUp);
BusIn re(A1, A0);

DigitalOut led1(D8);
BusOut leds(D9, D10, D11);

void keyPressed1()
{
    led1 = !led1;
}

//-------------------------------------------------
// ロータリーエンコーダの読み取り (Alps@akizuki)
// return: ロータリーエンコーダーの回転方向
//         0:変化なし 1:時計回り -1:反時計回り
//
int readRE()
{
    static uint8_t index;
    int retval = 0;

    index = (index << 2) | re;
    //pc.printf("%d\r\n", index);
    index &= 0b1111;

    switch (index) {
    case 0b1101:
        retval = 1;
        break;
    case 0b1000:
        retval = -1;
        break;
    }
    return retval;
}

int main()
{
    int cnt = 0;
    
    pc.printf("Nucleo Rotary Encoder & Toggle SW.\r\n");
    
    pin1.attach_asserted(&keyPressed1);
    pin1.setAssertValue(0);
    pin1.setSampleFrequency();
    
    re.mode(PullUp);
    
    while(1) {
        cnt += readRE();
        leds = cnt & 0x07;
        pc.printf("cnt:\t%d\r\n", cnt);
    }
}
    

動作としては、タクトスイッチを押すと緑色のLEDがトグル動作で点灯する。ロータリーエンコーダを回すと3bit値で赤色LEDが点灯。

チャタリング対策には「PinDetect」というライブラリを使った。ロータリーエンコーダのライブラリもあったがすぐには動かせなかったのでベタ書きにした。←実際使うときはクラス化したほうがよさそう。

C++だとデバイスも普通の変数みたいに書けるので楽だけど、変数名に規則性を持たせるとかしないと何やってるかわかりにくいかな?