Joycon-rs の使い方 - 側面LED, HOMEボタンのライト制御

Posted on
Rust JoyCon Joycon-rs Joycon-rs-v0.3.1 NintendoSwitch

joycon_rs_logo (本記事はv0.3.1時点でのものである)

TL;DR

examples/player_lights.rs

Joycon-rsを使ってJoy-Con側面のLEDを制御する

Joycon-rsを用いれば, Joy-Conの側面にあるLEDを制御する ことができる.

player_lights

Joy-Conのライトを制御する機能の実装は, joycon_rs::joycon::lightsモジュールに集約されている. 主軸となるのは, [Lights]トレイトである. それぞれのfunctionについて解説しよう.

以降, Joy-Conの側面にあるLEDのことをplayer lightsと呼称する.

Lights::set_player_lights()

文字通り, player lightsの点灯状態をセットする.

use joycon_rs::prelude::{*, lights::*};

// some code omitted
joycon_driver.set_player_lights(&vec![LightUp::LED0],&vec![Flash::LED2]).unwrap();

enumであるLightUpおよびFlashはどちらもLED0~LED3の4つのバリアントを持っている. それぞれのバリアントと, Joy-Con上のplayer lightsの対応は次のとおりである.

joycon_player_lights

また, 点灯と点滅の両方を一つのLEDに対して命じた場合, 点灯のほうが優先される.

joycon_driver.set_player_lights(&vec![LightUp::LED1], &vec![Flash::LED1]).unwrap();

上記のコードを実行すると, [SL Button] 🤔💡🤔🤔 [SR Button]となる.

Lights::get_player_lights()

Joy-Conのplayer lightsの点灯状況を知ることもできる.

use joycon_rs::prelude::{*, lights::*};

let player_lights_status = joycon_driver.get_player_lights()
    .unwrap()
    .extra
    .reply;
dbg!(player_lights_status);

この関数はJoyConResult<StandardInputReport<SubCommandReport<LightsStatus>>>型の値を返す. 型がごちゃごちゃしていて分かりづらいが, 肝心なのは[LightsStatus]である. これはlight_upflashという2つのフィールドを持っていて、それぞれ点灯中, 点滅中のLEDの一覧を表している.

StandardInputReport<T>型, SubCommandReport<T>型については今後取り扱う.

Joycon-rsを使ってJoy-ConのHOMEボタンのライトを制御する

Joycon-rsを用いれば, Joy-ConのHOMEボタンのライトを制御する ことができる.

home_light

このメソッドも[Lights]トレイトに実装されている.

Lights::get_home_light()

use joycon_rs::prelude::{*, lights::{*, home_button::*}};

let pattern =
    // loop pattern forever
    LightEmittingPattern::new(100, 0, 0u8.into())
        // 0.5 seconds to light up
        .add_phase(100,500,0)
        // 0.5 seconds to turn off
        .add_phase(0,500,0);
let player_lights_status = joycon_driver.set_home_light(&pattern);

[LightEmittingPattern]::new()の第一引数は, 発光パターンのフェーズ(小さな区切り)の基準となる時間で, 0~175msである.
第二引数は一番最初のLEDの発光の強さで, 0~100%で表す.
一番最後は発光パターンのリピート回数で, 0~15回の中から指定する. 0回にすると, 新たな発光パターンを指定されるまで同じ発光パターンを永遠に繰り返す.

[LightEmittingPattern]::add_phase()第一引数 は, そのパターンで到達するLEDの発光の強さである. 0~100%で表す. 内部的には4bit unsigned intで表されるので, だいたい7%刻みで段階的に指定できると考えてほしい1.
第二引数 は, 指定したLEDの発光の強さまでの遷移にかける時間である. ミリ秒で指定できるが, こちらも内部的には4bit unsigned intで表され, なおかつ[LightEmittingPattern]::new()の第一引数で指定した「基準となる時間」の倍率として扱われる. そのため, 「基準となる時間」と指定した値の組み合わせによっては, 違う値でも4bit unsigned intに変換したときに同じ値と見做され, 発光パターンに差が出ないことがある. 第三引数 は, LEDの強度が遷移して第一引数で指定した目標値に達したあと, どのぐらいの時間その明るさを維持するかの数値であり, ミリ秒で指定できる. 内部的な話は第二引数と同一である.

発光フェイズは15個まで[LightEmittingPattern]のインスタンスに登録できる. コンパイルを通すだけなら16個以上の登録が可能だが, Joy-Conには送信されず動作に影響しない2.

次回

次回は, Joy-Conのバイブレーションを制御する方法について解説する.

Joycon-rs v0.3.1の解説記事一覧はこちら.
tags/joycon-rs-v0.3.1


  1. たとえば0%を指定したときと1%を指定したときでは, どちらも4bit unsigned intに圧縮すると0になるため違いがない. 0%と10%だと0と1になるため違いがある. ↩︎

  2. このあたりも型かトレイトで制限をかけて, コンパイルが通らないようにしたほうがいいんだろうか……? [Lights]: https://docs.rs/joycon-rs/0.3.1/joycon_rs/joycon/lights/trait.Lights.html [LightsStatus]: https://docs.rs/joycon-rs/0.3.1/joycon_rs/joycon/lights/struct.LightsStatus.html [LightEmittingPattern]: https://docs.rs/joycon-rs/0.3.1/joycon_rs/joycon/lights/home_button/struct.LightEmittingPattern.html ↩︎