aimdevel’s blog

勉強したことを書きます

Raspberry Pi PicoのRGB LED実験 with Zephyr OS

概要

ラズパイ入門キット「SunFounder Da Vinci Kit for Raspberry Pi」に入っている機器をRaspberr Pi Pico + Zephyr OSで動かしてみた。
今回は、RGB LEDを試した。

環境

Raspberr Pi PicoとLEDを以下のように接続する。接続方法はSunFounderのチュートリアルを参考にした。

rgb_led

使用したソフトはZephyr OSの以下のサンプルコードで、デバイスツリーのみ上記の回路に合わせて変更した。

https://github.com/zephyrproject-rtos/zephyr/blob/main/samples/basic/rgb_led/src/main.c

使用方法

作成したソースコードを以下に格納したので、これを使用する。

GitHub - aimdevel/my-zephyr-applications

Zephyrの開発環境構築については公式ドキュメントを参照。

Getting Started Guide — Zephyr Project Documentation

環境をセットアップ

 west init -m https://github.com/aimdevel/my-zephyr-applications.git --mr main my-workspace
cd my-workspace/
west update

この手順はこのリポジトリを利用するときに1回だけ実施すればよい。

ビルド

 west build -b rpi_pico apps/apps/rgb_led/

基板に焼いて動作確認

時間経過でLEDの色が変化する様子を確認できる。

ソースコード説明

devicetree

devicetreeは以下。

https://github.com/aimdevel/my-zephyr-applications/blob/main/apps/rgb_led/boards/rpi_pico.overlay

全体は以下のようになっている。

/{
    aliases {
        red-pwm-led = &red_pwm_led;
        green-pwm-led = &green_pwm_led;
        blue-pwm-led = &blue_pwm_led;
    };
    pwmleds {
        compatible = "pwm-leds";

        red_pwm_led: red_pwm_led {
            pwms = <&pwm 2 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
        };
        green_pwm_led: green_pwm_led {
            pwms = <&pwm 3 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
        };
        blue_pwm_led: blue_pwm_led {
            pwms = <&pwm 4 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
        };
    };
};

&pwm {
    status = "okay";
    divider-frac-1 = <15>;
    divider-int-1 = <255>;
    divider-frac-2 = <15>;
    divider-int-2 = <255>;
};

&pwm_ch4b_default {
    group2 {
        pinmux = <PWM_1A_P2>, <PWM_1B_P3>, <PWM_2A_P4>;
    };
};

aliases

各ノードに別名をつける設定。
アプリのコードからデバイスツリーにアクセスする際に使用できる。
ここでは、各色に対応するノードに設定を行っている。

aliases {
        red-pwm-led = &red_pwm_led;
        green-pwm-led = &green_pwm_led;
        blue-pwm-led = &blue_pwm_led;
    };

pwmleds

それぞれの色にPWMを割り当てている。
1つだけ取り出して見る。

     red_pwm_led: red_pwm_led {
            pwms = <&pwm 2 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
        };

これは赤色をpwmの2番(GPIO2のピン)で制御することを表している。ほかの色も同様である。
細かい設定は公式ドキュメントを参照。

Pulse Width Modulation (PWM) — Zephyr Project Documentation

pwm

pwmの設定。

&pwm {
    status = "okay";
    divider-frac-1 = <15>;
    divider-int-1 = <255>;
    divider-frac-2 = <15>;
    divider-int-2 = <255>;
};

status = "okay"; でpwmを有効にしている。
そのほかは分周の設定で、Zephyr OS公式を参考に設定した。

pwm_ch4b_default

ピンの設定。
名前はch4bだが、それ以外のチャネルもここで設定できる。

&pwm_ch4b_default {
    group2 {
        pinmux = <PWM_1A_P2>, <PWM_1B_P3>, <PWM_2A_P4>;
    };
};

この1Aなどの値がPWMのチャネルなのだが、この値とGPIOの関係はデータシートによると以下のようになっている。

pico_pwm

今回はGPIO2, 3, 4をPWMとして使用するので、対応するpwmのチャネルは1A, 1B, 2Aとなっており、上記のピン設定となる。

サンプルコード

公式のサンプルコードから全く手を加えていない。
pwmを制御する際に行っているのは以下の部分。

  • バイスツリーから情報を取得。
static const struct pwm_dt_spec red_pwm_led =
    PWM_DT_SPEC_GET(DT_ALIAS(red_pwm_led));
static const struct pwm_dt_spec green_pwm_led =
    PWM_DT_SPEC_GET(DT_ALIAS(green_pwm_led));
static const struct pwm_dt_spec blue_pwm_led =
    PWM_DT_SPEC_GET(DT_ALIAS(blue_pwm_led));

DT_ALIASでaliasesで設定した名前を使用できるはずだが、ここではアンダースコア表記。

  • pwmの値を設定
ret = pwm_set_pulse_dt(&red_pwm_led, pulse_red);

pwm_set_pulse_dt関数にデバイスの構造体とパルスの値を渡して制御する。

まとめ

バイスツリーの対応だけでサンプルコードを動かせることを確認した。
pwmの制御だけなので、前回のサーボモータを動かすサンプルとほぼ同じ内容だった。
ラズパイ入門キットには、ほかにも多くのデバイスが含まれているのでそれらの動作にも挑戦していく。

参考

GitHub - zephyrproject-rtos/zephyr: Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.

1.1.2 RGB LED — SunFounder davinci-kit-for-raspberry-pi ドキュメント

Zephyr Project Documentation — Zephyr Project Documentation