AmazonでポチったロータリーエンコーダーHW-040を、Raspberry Pi Picoの割り込みとC言語で読み取る記事。ただ私は素人なので誤りが有るかも知れません。

開発環境

VSCode C/C++ Windows 11
RP2040 Raspberry Pi Pico

 

 

↓ 目標はロータリーエンコーダーでcentral_lineを上下に動かす事。

 

↓ DTの立ち上がり割り込み、又は立ち下がり割り込みの時、CLKの値を読み取り右回り、又は左回りを判断する。尚、画像中の#A、#B、#C、#Dは、ソースコードにあるそれと一致します。

 

↓ ロータリーエンコーダーの読み取りはcore1で行い、ADCとOLEDの表示はcore0で行う。次のコードはcore1で処理する部分で、ロータリーエンコーダーの読み取りをGPIOの割り込みで処理します。尚、ソースコード中の#A、#B、#C、#Dは上記画像のそれと一致します。

// コールバック関数
// ロータリーエンコーダーを回した時(割り込み発生時)に呼ばれる関数
void lxs_gpio_callback(uint gpio, uint32_t events) {

    int lxs_clk;

    // この関数実行中のみ点灯させて
    // ロータリーエンコーダーの
    // 立ち上がり
    // 立ち下がり を確認する為のLED
    gpio_put(5, 1); // GP5のLED点灯

    // 割り込みの禁止
    gpio_set_irq_enabled(gpio, GPIO_IRQ_EDGE_FALL | GPIO_IRQ_EDGE_RISE, false);

    sleep_ms(3); // 0.003秒 念の為のチャタリング対策

    // CLKの状態を取得
    lxs_clk = gpio_get(PIN_CLK);

    // DTの立ち上がり割り込み
    if (gpio == PIN_DT && events == GPIO_IRQ_EDGE_RISE) {
        if (lxs_clk == 1) {         // #A
            central_line--;
        } else if (lxs_clk == 0) {  // #C
            central_line++;
        }

    // DTの立ち下がり割り込み
    } else if (gpio == PIN_DT && events == GPIO_IRQ_EDGE_FALL) {
        if (lxs_clk == 0) {         // #B
            central_line--;
        } else if (lxs_clk == 1) {  // #D
            central_line++;
        }
    }

    // 割り込み禁止の解除
    gpio_set_irq_enabled(gpio, GPIO_IRQ_EDGE_FALL | GPIO_IRQ_EDGE_RISE, true);

    gpio_put(5, 0); // GP5のLED消灯
}

void core1_entry() {

    const uint LED_PIN = 25;
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);

    // GPIOの初期化(ロータリーエンコーダー用)
    gpio_init(PIN_CLK); // GP4
    gpio_init(PIN_DT); // GP3
    gpio_init(PIN_SW); // GP2

    // 立ち上がり、立ち下がりの割り込み確認用LED
    gpio_init(5); // GP5

    // 入出力設定
    gpio_set_dir(PIN_CLK, GPIO_IN);
    gpio_set_dir(PIN_DT, GPIO_IN);
    gpio_set_dir(PIN_SW, GPIO_IN);
    gpio_set_dir(5, GPIO_OUT);

    // 内部プルダウン設定
    gpio_pull_down(PIN_CLK);
    gpio_pull_down(PIN_DT);
    gpio_pull_down(PIN_SW);

    // ヒステレリス設定(シュミットトリガ利用)念の為のチャタリング対策
    gpio_set_input_hysteresis_enabled(PIN_CLK, true);
    gpio_set_input_hysteresis_enabled(PIN_DT, true);
    gpio_set_input_hysteresis_enabled(PIN_SW, true);

    // 割り込み用コールバック関数の登録
    gpio_set_irq_enabled_with_callback(PIN_DT, GPIO_IRQ_EDGE_FALL | GPIO_IRQ_EDGE_RISE, true, &lxs_gpio_callback);

    // 割り込み禁止の解除
    gpio_set_irq_enabled(PIN_DT, GPIO_IRQ_EDGE_FALL | GPIO_IRQ_EDGE_RISE, true);

    // 基板実装LED(GP25)の点灯用ループ
    while (true) {
        if (gpio_get(PIN_CLK) == 1) {
            gpio_put(LED_PIN, 1);
        } else {
            gpio_put(LED_PIN, 0);
        }
    }
}

 

↓ GP5に繋げた緑色のLEDは、ロータリーエンコーダーを回した時に呼ばれる関数 lxs_gpio_callback() の実行中だけ点灯。立ち上がり、立ち下がりの割り込みをLEDの点灯で分かる仕組み。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

Post Navigation