#愚痴(読み飛ばして)
個人的な予想は、設定を変更すれば、前面の3点LEDの色を変更出来ると思っていた。
しかし、どうやら違うようだ。
C言語を読み解けば、それが判明するとも思ったが、そもそも10年以上C言語を仕事に使ってきたが、C言語を読み解く力が無く、断念した。
経験することこそ愚かなことはない。いかに知識が重要かが分かる。
この10年は何だったのか・・・。
経験を積むことを重要視する天才はいないだろう。しかし、ボンクラはどうしても勉強より経験を優先してしまう。
そのため・・・。
キーボードを購入するときに、光らせるつもりはなかった前提はあるが・・・。
しかし、1台購入すれば、同じキーボードを追加購入することはないであろう金額ということで、LED Lighting付きを注文した。
(前面のLEDの話どこ行った)
公式ErgoDoxEZTwitterアカウント:@ErgoDoxEZ
以下、本題...
以下、まだ前戯...
##GUIでのLED Lighting点灯方法
-
ErgoDoxEZ Try out the new configurator
公式ページだからなのか、一応出来る。
しかし、5色しか設定できず、何より左右合わせて30個ものLEDがあるのに、個別に色を設定できない。
公式なのに・・・。
最大の欠点は、設定したキー押下で、LEDが発光すると言うことだ。 -
massdrop configurator
これは、LED点灯が出来ないタイプのGUI操作 -
キーボードレイアウトエディタ
ヘルプはあるが、使い方が分からない。
しかし、LEDの説明書きがあるため、きっとできると思う。
英語で理解できないが、解説動画を見つけた。
Introduction to Creating Custom Mechanical Keyboard Keycap Sets, Cases, and PCBs -
Infinity ErgoDox
ErgoDoxEZを裏切るつもりはないが、流用できそうに思えたため、一応紹介するが・・・結局、これもLEDで設定する方法が分からない。
もしかしたらQMKで動かないかも知れない(ErgoDoxとは仕組みが違うようだ)。
##LEDの点灯は個人の趣味だ
自己満足のために、他人が関与することはなく踏み込んでくることもない。
そのため、GUI操作では、ある程度のことしか出来ず、ものによってはある程度すら出来ない。
そんな結論に達した。
ゆえに、LED Lighting変更方法は、公開されていないのかも知れない(私が知らないだけ)。
しかし、残念ながら私は頭が悪いため、誰かにやり方を教えてくれなければ、変更出来ない。
"教えてクレクレ"
#前面のLED変更
ようやく本題に挿入する。
[赤緑青]のLEDが光る。
まずは、強い光を抑えたい。
##ErgoDox EZのLEDの明るさを変更する方法
ここで紹介するやり方は、光の強さを変更するだけ。
クローンGitディレクトリ\github_repository20180604\qmk_firmware\keyboards\ergodox_ez
ergodox_ez.c
"ergodox_blink_all_leds"と言う名前の関数がある。
そこに、前面3種類のLEDの光の強さを制御する"ergodox_led_all_set"と言う関数呼び出しがあり、そこの引数に、LED_BRIGHTNESS_DEFAULT
値を渡している。
これが、強い光で点灯することを示している(標準の強さなので、強くないかも)。
そのため、弱い光としてLED_BRIGHTNESS_LO
に書き換えれば、光が抑えられる。
強い光は、LED_BRIGHTNESS_HI
を指定すれば良い。
###強弱比較
上が強い光で、下が弱い光だが、撮影技術が無いので、比較できそうにない。
光の強弱は、以下の関数を使う。
inline void ergodox_right_led_1_set(uint8_t n) { OCR1A = n; }
inline void ergodox_right_led_2_set(uint8_t n) { OCR1B = n; }
inline void ergodox_right_led_3_set(uint8_t n) { OCR1C = n; }
inline void ergodox_right_led_set(uint8_t led, uint8_t n) {
(led == 1) ? (OCR1A = n) :
(led == 2) ? (OCR1B = n) :
(OCR1C = n);
}
inline void ergodox_led_all_set(uint8_t n)
{
ergodox_right_led_1_set(n);
ergodox_right_led_2_set(n);
ergodox_right_led_3_set(n);
}
今までは、ergodox_led_all_set
を使ったが、個別に光らせるには、ergodox_right_led_[1-3]_set
を使えば良いだろう。
と言うことで、以下の画像は、LED1(赤)に1を設定し、LED2と3に0を渡した結果だ。
緑(LED2)と青(LED3)は、ゼロを渡したため、無灯だと思ったのだが、光っている。
不思議だ。
誰か、光る理由を教えてください。
(撮影技術が無いので、強く光っているように思えるが、結構弱い)
強さが分かりにくいため、以下のように変更した。
("←これ."とコメントに書いている値が以下の画像になる)
void ergodox_blink_all_leds(void)
{
ergodox_led_all_off();
// ergodox_led_all_set(LED_BRIGHTNESS_DEFAULT); // 原本20180828
// ergodox_led_all_set(LED_BRIGHTNESS_LO); // 光を抑える.
ergodox_right_led_1_set(1); // 赤 ←これ.
ergodox_right_led_2_set(0); // 緑 ←これ.
ergodox_right_led_3_set(LED_BRIGHTNESS_HI); // 青 ←これ.
ergodox_right_led_1_on();
_delay_ms(50);
ergodox_right_led_2_on();
_delay_ms(50);
ergodox_right_led_3_on();
_delay_ms(50);
#ifdef LEFT_LEDS
・
・
・
}
赤を1にしているため、弱く光るのは理解できる。
緑は0にしているのに、光があるのは何故だろうか。
どちらも青が強すぎて、視認しづらいが・・・。
青は最大にしているため、キーキャップにまで光が反射しているのが分かって頂けるだろうか。
##そもそもの光設定
前面のLEDを光らせるには、上記でergodox_right_led_1_on
が起因になって光っていることを突き止めた。
中身を確認したところ以下の2行で制御しているのが分かった(私が勝手に改行しているだけで、実際は1行)。
inline void ergodox_right_led_1_on(void)
{
// 赤
DDRB |= (1<<5);
PORTB |= (1<<5);
}
inline void ergodox_right_led_2_on(void) { DDRB |= (1<<6); PORTB |= (1<<6); } // 緑
inline void ergodox_right_led_3_on(void) { DDRB |= (1<<7); PORTB |= (1<<7); } // 青
数値の1を5つ分左にシフト(1<<5)させて、ビット制御しようとしているのが分かる。
要は、0x20(0b00100000)ってことだよね?
###ここから疑問
Rightハンドが私の彼女で、AVをおかずにしていると言えば、マイコンのAVRを想像すると思うだろうが、理解できない人もいるだろう。
私もその一人だ。
PICというマイコンもあるようだが、ErgoDoxEZにはAVRのマイコンが使われていると思って良いだろうか。
よく分からないまま0b00000001
を設定したが、まったく光らない。
inline void ergodox_right_led_1_on(void)
{
// 赤
DDRB |= (0b00000001);
PORTB |= (0b00000001);
}
要は、LEDが3つしかないため、左端のビットから順に使っていくって事でいい?
右端の5ビットは、空き?
この部分で、黄色や紫など色を変えることが出来る組合せだと思ってしまったが、そんな高度なことは出来ない?
色も固定されている?
以下の努力は無駄?
// Runs whenever there is a layer state change.
uint32_t layer_state_set_user(uint32_t state) {
・
・
・
uint8_t layer = biton32(state);
switch (layer) {
case 0:
・
・
・
case 1:
// ergodox_right_led_1_on();
DDRB |= (1<<5);
PORTB |= (1<<5);
// DDRB |= (0b00100000); 赤
// PORTB |= (0b00100000); 赤
// DDRB |= (0b01000000); 緑
// PORTB |= (0b01000000); 緑
// DDRB |= (0b10000000); 青
// PORTB |= (0b10000000); 青
// DDRB |= (0b00110000); 赤
// PORTB |= (0b00110000); 赤
// DDRB |= (0b01010000); コンパイルエラー
// PORTB |= (0b01010000); コンパイルエラー
// DDRB |= (0b10010000); 青
// PORTB |= (0b10010000); 青
// DDRB |= (0b10100000); 赤青
// PORTB |= (0b10100000); 赤青
// DDRB |= (0b11000000); 緑青
// PORTB |= (0b11000000); 緑青
// DDRB |= (0b01100000); 赤緑
// PORTB |= (0b01100000); 赤緑
// DDRB |= (0b11100000); 赤緑青
// PORTB |= (0b11100000); 赤緑青
// DDRB |= (0b00000001); 手前のLED表示されず.
// PORTB |= (0b00000001); 手前のLED表示されず.
// DDRB |= (0b00000010); 手前のLED表示されず.
// PORTB |= (0b00000010); 手前のLED表示されず.
// DDRB |= (0b00000100); 手前のLED表示されず.
// PORTB |= (0b00000100); 手前のLED表示されず.
// DDRB |= (0b00001000); 手前のLED表示されず.
// PORTB |= (0b00001000); 手前のLED表示されず.
・
・
・
#ifdef RGBLIGHT_ENABLE
・
・
・
ポートレジスタやIOポートC言語のマクロなどで、DDRB
やPORTB
の関数を調べたが、イマイチ理解できなかった。
LEDの種類によって、単色なのか、複色なのかがあるって事なのだろう。
発光用に、この2種類の関数に、同じ値を設定しなければ動かないと言うことなのかな。
エラーになっている部分も理解できないままだが・・・。
キーボードを使いたいだけなのに、ここまで時間と労力が必要な理由が理解できない。
如何に、市販品が優れているかが分かるというものだろう。
###前面LED3種類固定
もし、色を変更出来ず、固定であれば、6通りの表示・・・ではない。
レイヤー0は発光なしとして、レイヤー1〜レイヤー7までの7通りの発光になる?
中学校で、組合せや順列を習ったつもりだが、学校で習ったことを活かせない・・・。
いかに、不勉強のまま人間を捨てて生きているかが実感できて辛い。
ErgoDoxEZに、人生の甘さを自覚させる機能があるとは・・・。
残念だが、既存のソースコードが7種類としている以上、従おう。
レイヤー8以降は、無灯になる。大変残念だが、発光させたい場合は、個人で追加する必要がある。
case 7:
の次は、default:
になっているはず。
この間に、8や9など好きなだけ数字を割り当てて、3種類のLEDを好きに発光させればいいと思う。
他のレイヤーと発光が重複することになり、混乱するようにも思うが、とりあえず、レイヤーが0ではない判断が出来ると思う。
#裏面のLED変更
就職活動をそこそこに、収入もないまま高いキーボードを購入し、LED発光に時間と労力を費やしている。
先駆者が光らせていないため困っていたが、1人だけ光らせ方を公開している有志がいて、ありがたい。
ErgoDox導入記
これのLayerが切り替わったら背面LEDの色も変えるソースコードを基準に、私のErgoDoxEZもピカピカに光らせようと思った。
そもそも、前面のLEDの色を変更したかったのは、レイヤー1が赤に光らせるのは気持ち悪かったため、信号機のように青・黄・赤にしたかった。
赤は、危険信号だと思っているため、1つ目に使いたくなかった。
そして、前面LEDの色に合わせて、背面LEDも発光したかった。
反発(?)も問題ないが・・・できれば、合わせたい。
ところで、
裏面?
背面?
まっいいか。
##単純発光(同色同時発光)
上記のkeymap.cの"case 1:"に、レイヤー1のLED発光プログラムを埋め込むことを理解している前提で話を進める。
case 0:
・
・
・
#ifdef RGBLIGHT_ENABLE
rgblight_disable();
#endif
break;
case 1:
・
・
・
#ifdef RGBLIGHT_ENABLE
rgblight_enable(); // 有効
rgblight_setrgb(0xff,0x00,0x00); // ←これ.
#endif
break;
rgblight_setrgb
関数の引数に、色設定を与えれば、確かに背面LEDは変化する。
しかし、問題点が2点ある。
- その色で全てのLED30個が埋まる。
- レイヤー0からの発光にワンクッション余計な発光が入る。
この2種類は、別物なので、まずは二つ目から解決しようと思う。
###レイヤー0:無灯
発光しているレイヤーxから0レイヤーに戻る場合、0は無灯にしたかった。
無色(白では無い)で発光を抑えるのはあり得ないと思っている(通電していると思っているため)。
そのため、無効化(disable
)したのだが、有効化(enable
)した時に、その切り替え時の発光があり、一瞬だけ全色(デフォルト色?)が光ってしまう。
しかたないため、常に有効化しておくことにした(すぐに妥協するorz)。
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
rgblight_enable(); // 有効 ←これ.
#ifdef RGBLIGHT_COLOR_LAYER_0
#endif
};
既存の関数に、有効化の処理を追加した。
すでに、追加済みの処理は削除しておくこと。
uint32_t layer_state_set_user(uint32_t state) {
・
・
・
// rgblight_disable();
・
・
・
// ergodox_right_led_1_on(); ←前面のLED発光
・
・
・
// rgblight_enable();
・
・
・
このやり方があっているのか不明なので、誰か教えて欲しい。
目的は、発光していないときは通電したくない。
とりあえず、ワンクッションの余計な発光は抑えた。
###一斉発光
rgblight_setrgb
関数を使う場合、問答無用で全てのLEDの色が変わり、発光する。
ここでも新たな問題が出るものの気にしないことにする(まぶしい)。
個別に発光するには、1つずつ指定すれば解決するため、大した手間は要らない。
rgblight_setrgb_at
関数を使い、上記の色指定プラス発光したい場所を指定するだけだ。
注意しなければならないのは、C言語のため0番目から配列が始まることだ。
tmp[5]
という配列がある場合、先頭に値を設定するには、tmp[0]
を指定することだ。
最大5番目はtmp[4]
となる。
今回片方には、15個のLEDがあるため、LED[15]
という配列があった場合、端っこはLED[0]
になり、逆の端っこはLED[14]
になる。
とりあえず、指定色の一種類で全てのLED30個が埋まることは免れた。
##単色発光(LED個別発光)
何はともあれ、一応これがやりたかった。
まずは、結果から...
写真の手前側が左手部分で、奥側が右手部分の発光になる。
左手側では、裏返した状態の右端がLED[0]
になる。
右手側では、裏返した状態の左端がLED[0]
になる。
要は、置いたときの両脇がLED[0]
になり、内側になるにつれ値が大きくなるということ。
左手(LED[0][1][2]〜[12][13][14]) 右手(LED[14][13][12]〜[2][1][0])
上記で、"一応"と付けているのは、他の問題点が解決していないからだ。
-
光量を落とせない⇒RGBではなくHSVを使うことで解決
前面LEDは、冒頭通り光の強さを弱められたが、背面は方法が分からない。 -
左右分離させられない.
折角左右分離型なのに、右手側だけ光らせたり、左手だけだったりができない。
きっとやり方があるだろうが、プログラミング知識が乏しく、既存のプログラムを追いかけられない限り、解決できないだろう。
インターネットでは、解説がなかった。
出来て当たり前だから?
上記写真のプログラムを以下に置く(参考になれば幸い)。
case 1:
・
・
・
#ifdef RGBLIGHT_ENABLE
rgblight_setrgb_red_at(0);
rgblight_setrgb_at( 255, 0, 255,1);
rgblight_sethsv_turquoise_at( 2 );
rgblight_setrgb_at( 255, 255, 0, 3);
rgblight_setrgb_at( 255, 0, 255, 4);
rgblight_setrgb_at( 0, 255, 255,5);
rgblight_setrgb_at( 255, 255, 255,6);
rgblight_setrgb_at(0x00,0x00,0xff,7);
rgblight_setrgb_at(0x00,0x00,0x00,8);
rgblight_setrgb_at(0x00,0x0f,0x00,9);
rgblight_setrgb_at(0x00,0x00,0x00,10);
rgblight_setrgb_at(0x00,0x00,0x00,11);
rgblight_setrgb_at(0x00,0x00,0x00,12);
rgblight_setrgb_at(0x00,0x00,0x00,13);
rgblight_setrgb_yellow_at(14);
#endif
・
・
・
###色指定
誰もが思うであろう色指定の面倒さ。
"0x00, 0x00, 0x00"
で、いちいち色を変更するのは煩わしいと言うより、間違えやすいだろう。
ということで、用意されている色を使うのが便利だと思われる。
(微妙な色指定をしたところで、肉眼では識別できないだろうし・・・)
クローンディレクトリ\github_repository20180604\qmk_firmware\quantum
/* SET RGB List */
#define rgblight_setrgb_white() rgblight_setrgb (0xFF, 0xFF, 0xFF)
#define rgblight_setrgb_red() rgblight_setrgb (0xFF, 0x00, 0x00)
#define rgblight_setrgb_coral() rgblight_setrgb (0xFF, 0x7C, 0x4D)
#define rgblight_setrgb_orange() rgblight_setrgb (0xFF, 0x80, 0x00)
#define rgblight_setrgb_goldenrod() rgblight_setrgb (0xD9, 0xA5, 0x21)
#define rgblight_setrgb_gold() rgblight_setrgb (0xFF, 0xD9, 0x00)
#define rgblight_setrgb_yellow() rgblight_setrgb (0xFF, 0xFF, 0x00)
#define rgblight_setrgb_chartreuse() rgblight_setrgb (0x80, 0xFF, 0x00)
#define rgblight_setrgb_green() rgblight_setrgb (0x00, 0xFF, 0x00)
#define rgblight_setrgb_springgreen() rgblight_setrgb (0x00, 0xFF, 0x80)
#define rgblight_setrgb_turquoise() rgblight_setrgb (0x47, 0x6E, 0x6A)
#define rgblight_setrgb_teal() rgblight_setrgb (0x00, 0x80, 0x80)
#define rgblight_setrgb_cyan() rgblight_setrgb (0x00, 0xFF, 0xFF)
#define rgblight_setrgb_azure() rgblight_setrgb (0x99, 0xf5, 0xFF)
#define rgblight_setrgb_blue() rgblight_setrgb (0x00, 0x00, 0xFF)
#define rgblight_setrgb_purple() rgblight_setrgb (0x7A, 0x00, 0xFF)
#define rgblight_setrgb_magenta() rgblight_setrgb (0xFF, 0x00, 0xFF)
#define rgblight_setrgb_pink() rgblight_setrgb (0xFF, 0x80, 0xBF)
/* SET RGB List */
#define rgblight_setrgb_white_at(at) rgblight_setrgb_at (0xFF, 0xFF, 0xFF, at)
#define rgblight_setrgb_red_at(at) rgblight_setrgb_at (0xFF, 0x00, 0x00, at)
#define rgblight_setrgb_coral_at(at) rgblight_setrgb_at (0xFF, 0x7C, 0x4D, at)
#define rgblight_setrgb_orange_at(at) rgblight_setrgb_at (0xFF, 0x80, 0x00, at)
#define rgblight_setrgb_goldenrod_at(at) rgblight_setrgb_at (0xD9, 0xA5, 0x21, at)
#define rgblight_setrgb_gold_at(at) rgblight_setrgb_at (0xFF, 0xD9, 0x00, at)
#define rgblight_setrgb_yellow_at(at) rgblight_setrgb_at (0xFF, 0xFF, 0x00, at)
#define rgblight_setrgb_chartreuse_at(at) rgblight_setrgb_at (0x80, 0xFF, 0x00, at)
#define rgblight_setrgb_green_at(at) rgblight_setrgb_at (0x00, 0xFF, 0x00, at)
#define rgblight_setrgb_springgreen_at(at) rgblight_setrgb_at (0x00, 0xFF, 0x80, at)
#define rgblight_setrgb_turquoise_at(at) rgblight_setrgb_at (0x47, 0x6E, 0x6A, at)
#define rgblight_setrgb_teal_at(at) rgblight_setrgb_at (0x00, 0x80, 0x80, at)
#define rgblight_setrgb_cyan_at(at) rgblight_setrgb_at (0x00, 0xFF, 0xFF, at)
#define rgblight_setrgb_azure_at(at) rgblight_setrgb_at (0x99, 0xf5, 0xFF, at)
#define rgblight_setrgb_blue_at(at) rgblight_setrgb_at (0x00, 0x00, 0xFF, at)
#define rgblight_setrgb_purple_at(at) rgblight_setrgb_at (0x7A, 0x00, 0xFF, at)
#define rgblight_setrgb_magenta_at(at) rgblight_setrgb_at (0xFF, 0x00, 0xFF, at)
#define rgblight_setrgb_pink_at(at) rgblight_setrgb_at (0xFF, 0x80, 0xBF, at)
- 同色単色発光
rgblight_setrgb_〜〜〜
の場合は、上記"rgblight_setrgb"関数利用の使い方と同じ。
rgblight_setrgb(0xff,0x00,0x00);
の部分をrgblight_setrgb_red();
に置き換えればよい。
- LED個別指定発光
rgblight_setrgb_〜〜〜_at
の場合は、上記"rgblight_setrgb_at"関数利用の使い方と同じ。
rgblight_setrgb_at( 255, 255, 0, 3);
の部分をrgblight_setrgb_yellow_at(3);
に置き換えればよい。
(用語が統一されていないような気が・・・)
おまけ(発光パターン)
rgblight_mode
関数というものがあり、点灯のみの発光や強弱を付けながら発光するなどパターンがいくつかある。
最大36種類あるようだが、残念ながらErgoDoxEZでは、7種類から8種類ぐらいしか確認できなかった。
詳しく調べていないので分からないが、9番目以降は、用意された発光のみするようだった。
発光パターンは、以下のファイルにある。
クローンディレクトリ\github_repository20180604\qmk_firmware\quantum
void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
・
・
・
if (rgblight_config.mode == 1) {
#ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_disable();
#endif
} else if ((rgblight_config.mode >= 2 && rgblight_config.mode <= 24) ||
rgblight_config.mode == 35 || rgblight_config.mode == 36) {
// MODE 2-5, breathing
// MODE 6-8, rainbow mood
// MODE 9-14, rainbow swirl
// MODE 15-20, snake
// MODE 21-23, knight
// MODE 24, xmas
// MODE 35 RGB test
// MODE 36, alterating
・
・
・
}
これを見るに、"breathing"と"rainbow mood"があるようだ。
ErgoDoxEZ用に、用意されたプログラムがありそうだが、これまた見つけられなかった。
一応の使い方は、そのままなのだが・・・。
case 1:
・
・
・
#ifdef RGBLIGHT_ENABLE
rgblight_setrgb_red_at(0);
rgblight_mode(2); // ←これ.
#endif
・
・
・
case 2:
・
・
・
#ifdef RGBLIGHT_ENABLE
rgblight_setrgb_yellow_at(0);
rgblight_mode(5); // ←これ.
#endif
・
・
・
case 3:
※アニメーションの速度を変更出来るようだが、変更した状態を保存することは出来ないようだ。
個人的なアニメーション作成
Questions about RGB Matrix and creating my own animations.
カレントディレクトリにrgb_matrix_user.inc
を配置し、ヘッダーファイルをインクルードする必要があるようだ。
何を言っているのか全く分からないが、こだわりがある人には有効な情報なのだろう。
#遠い目標
前面LEDは、光量を調整できた。
そのため、今後は、背面のLEDの光量を変化させる仕組みを突き止めたい。
色を変えられるのに、光の強さを変えられないわけがない。
そして、片手だけLED[0]
からLED[14]
まで徐々に光の強さを変えながらそれぞれ色が違いつつスネークやクリスマスなどで色を動かしたい。
優先順位は低いけど。
##さらに遠い目標
今回は、レイヤー変更時に光を放つだけだった。
CapsLockキー押下時に、光らせたい。
##既存のソースコードの追いかけ
以下の3種類は何物!?
"EEPROM"って何?
#まとめ
よく分からないまま手探りでLEDを光らせてみた。
光る原理は理解できていないが、光ったのだから目的が達成できたと考えて良いだろう。
故に、今回勝ったぞぉおぉぉぉぉぉぉぉ。
今後も勉強より経験を優先させようと思う。
人間である以上、経験を積むことは不可能ではあるが、勉強嫌いなので犬畜生に成り下がり、犬や牛のようにがむしゃらに頑張ろうと思う。
##MechanicalKeyboards
HHKBが左右分離型を出すまでの繋ぎに、ErgoDoxEZを購入したのだが、自作に手を出してもいいかなと思い始めた...
The ‘Not So MiniDox’ Handwire : MechanicalKeyboards
オープンソース系自作キーボード「Iris」のビルドに挑戦
自作キーボード未経験者が左右分離型の「Orthodox」を組み立てた記録
店舗Keebio
国産キーボード?Helix キーボードキット
どこにでも売っているんだね。
ErgoDox EZ|スプリットタイプのエルゴデザインキーボード「エルゴドックスイージー」
以上。