elc: LEDチェーンをバリアントごとに分けないことを確定する
QMKの rgb_matrix はボードに1つで、レイアウトごとに分かれない。 バリアント固有の位置にLEDが載る基板も載らない基板も実在するが、どちらもチェーンは1本で、 選択によって並びが変わらない。載らないキーはPHYのper-key LEDの有無でそのまま表せる。 Journal: journal/2026-09-21-led-chain-variant.md Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01246a5KFLmwcRXriZvX8fdJ
This commit is contained in:
+4
-8
@@ -70,6 +70,10 @@ PHYがレイアウトバリアントを持つ場合も、ELCは選択に関係
|
||||
設計エラーとする。接点マトリクスなら、どちらが押されたかを区別できないため。
|
||||
排他かどうかはPHYの木から判る。
|
||||
|
||||
LEDチェーンもバリアントごとに分けない。排他なキー位置の両方にLEDが載る基板も、
|
||||
バリアント固有のキーにLEDが載らない基板もあるが、どちらもチェーンは1本で、選択によって並びが変わらない。
|
||||
載らないキーは、PHYがキーごとに持つper-key LEDの有無でそのまま表せる。
|
||||
|
||||
### 他レイヤーへの参照
|
||||
|
||||
キーとLEDの参照には、PHYのノードIDをそのまま使う。ELCはIDXを参照しない。
|
||||
@@ -153,11 +157,3 @@ type ELC = {
|
||||
- 現状の認識: 接点マトリクスではダイオードの向きから、directでは電源レールの参照から、
|
||||
どちらを駆動しどちらを検出するかが決まりそうに見えるが、全方式で導出できるか確かめていない
|
||||
- 格上げ条件: 各方式について、端子の接続先とダイオードの向きだけから走査手順が一意に決まるかを確認する
|
||||
|
||||
### P-4 LEDチェーンがレイアウトバリアントをまたぐ場合
|
||||
|
||||
- 位置づけ: 本文「LEDの識別番号」がレイアウトバリアントを考慮していない
|
||||
- 現状の認識: 選ばれなかったバリアントのキーにper-key LEDが載らないと、チェーンがそこで切れる。
|
||||
基板側でバイパスする話であればBeyond KLEの範囲外だが、チェーンの並びをバリアントごとに分ける必要が
|
||||
あるかもしれない
|
||||
- 格上げ条件: レイアウトバリアントとper-key LEDを両方持つ実在のPCBで、チェーンがどう配線されているかを確認する
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
# LEDチェーンとレイアウトバリアント
|
||||
|
||||
ELC P-4 の検証。
|
||||
|
||||
## 結論
|
||||
|
||||
チェーンはレイアウトの選択と無関係に固定されている。バリアントごとにチェーンの並びを分ける必要はない。
|
||||
|
||||
理由は、per-key LEDがスイッチとは独立に基板へ実装されるため。排他な2つのキー位置の両方にLEDが載る。
|
||||
QMKの `rgb_matrix.layout` はボードに1つしかなく、レイアウトごとに分かれていない。
|
||||
|
||||
| ボード | レイアウト数 | LED数 | バリアント固有のマトリクス位置 | そこへのLED割り当て |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| dp60 | 7 | 72 | 8 | 8個すべてにあり |
|
||||
| cherrybstudio/cb87rgb | 9 | 92 | 6 | 6個すべてにあり |
|
||||
| crkbd/r2g | 2 | 54 | 6 (外側の列) | 6個すべてにあり |
|
||||
| annepro2/c18 | 2 | 61 | 1 (ISOの追加キー) | なし |
|
||||
| boardsource/sessanta | 2 | 72 | 4 (分割スペース) | なし |
|
||||
|
||||
annepro2/c18 と boardsource/sessanta は、バリアント固有のキーにLEDが無い。
|
||||
チェーンが切れるのではなく、そのキーにper-key LEDが載っていないだけである。
|
||||
PHYがper-key LEDの有無をキーごとに持つ形でそのまま表せる。
|
||||
|
||||
どちらの型でも、LEDの番号はレイアウトの選択で動かない。
|
||||
|
||||
## 調べ方
|
||||
|
||||
QMKのinfo.json 400件から、レイアウトを2つ以上持ち `rgb_matrix.layout` を持つ19件を抽出。
|
||||
全レイアウトのマトリクス位置の和集合から共通部分を引いた「バリアント固有の位置」に、
|
||||
LEDが割り当てられているかを見た。11件は割り当てあり、12件は一部に無し(両方に該当する板がある)。
|
||||
|
||||
## 限界
|
||||
|
||||
回路図そのものではなく、ファームウェアが持つLED配列を見ている。
|
||||
LEDが基板に実装されているかどうかまでは確認できない。ただしQMKの `rgb_matrix.layout` は
|
||||
レイアウトごとに分けられない構造なので、「選択によってチェーンの並びが変わる基板」は
|
||||
少なくともQMKでは成立しない。
|
||||
|
||||
## 検証スクリプト
|
||||
|
||||
```py
|
||||
# QMKのinfo.jsonを無作為抽出で取得する。qmk_list.json は
|
||||
# curl -o qmk_list.json https://keyboards.qmk.fm/v1/keyboard_list.json
|
||||
import json, random, urllib.request, concurrent.futures, os
|
||||
kbs=json.load(open('qmk_list.json'))['keyboards']
|
||||
random.seed(42)
|
||||
os.makedirs('qmk', exist_ok=True)
|
||||
def fetch(kb):
|
||||
p='qmk/'+kb.replace('/','__')+'.json'
|
||||
if os.path.exists(p): return True
|
||||
try:
|
||||
with urllib.request.urlopen(f'https://keyboards.qmk.fm/v1/keyboards/{kb}/info.json', timeout=30) as r:
|
||||
open(p,'wb').write(r.read())
|
||||
return True
|
||||
except Exception as e:
|
||||
return str(e)[:60]
|
||||
with concurrent.futures.ThreadPoolExecutor(8) as ex:
|
||||
res=list(ex.map(fetch, random.sample(kbs, 400)))
|
||||
print('fetched', sum(1 for r in res if r is True), 'failed', sum(1 for r in res if r is not True))
|
||||
```
|
||||
|
||||
```py
|
||||
# レイアウトバリアントとper-key LEDの関係。rgb_matrix.layout はボードに1つしかない
|
||||
import json, glob, collections
|
||||
st=collections.Counter()
|
||||
for f in glob.glob('qmk/*.json'):
|
||||
d=json.load(open(f,encoding='utf-8'))
|
||||
for kb,v in (d.get('keyboards') or {}).items():
|
||||
lays=v.get('layouts') or {}; rm=(v.get('rgb_matrix') or {}).get('layout')
|
||||
if not rm or len(lays)<2: continue
|
||||
st['対象ボード']+=1
|
||||
used=[set(tuple(k['matrix']) for k in l['layout']) for l in lays.values()]
|
||||
variant_only=set().union(*used)-set.intersection(*used) # バリアント固有の位置
|
||||
led=set(tuple(l['matrix']) for l in rm if 'matrix' in l)
|
||||
if not variant_only: continue
|
||||
if variant_only & led: st['固有位置にLEDあり']+=1
|
||||
if variant_only - led: st['固有位置にLEDなし']+=1
|
||||
print(kb, 'レイアウト', len(lays), 'LED', len(rm),
|
||||
'固有位置', len(variant_only), 'うちLEDあり', len(variant_only & led))
|
||||
print(st)
|
||||
```
|
||||
Reference in New Issue
Block a user