SONY LinkBudsが1歳児の育児に最高だった話

SONY LinkBudsが1歳児の育児に最高だった話

子育てをするようになってから、まとまった娯楽やインプットの時間を取ることが難しくなってきたので、最近はよく家事の最中や子供の寝かしつけでPodcastを聴いています。

そんな日々に最近購入したSONYのLinkBudsが最高でした。というお話。

www.sony.jp

購入

ソニーストアにて購入。ソニーストアだと片方紛失した際の保険に入れたりするのが良いですね。 他ECサイトより少し高価ですが、クーポンを大量に持っていたので相殺他ECサイトより安く購入できました。

感想

数か月使った感想を。

良い

  • 完全ワイヤレス
    • 抱っこしててもケーブルを掴まれることがない
      • 最初は有線イヤホンだったが、ケーブルを掴んで引っ張るので諦めた
  • 外の音が聴こえる
    • 家事をしていても子供の様子が聞こえるので安心
      • 子供は突拍子もなく転んだりするので、音は聞こえる状態にしておきたい
  • 騒音にあわせて音量が調整される
    • 食洗器の音とか周辺の音量にあわせて自動的に音量が変わるので、洗い物してて両手がふさがってても大丈夫。

悪い

  • 誤飲できちゃうサイズ
    • TWSイヤホンは子供が飲み込めるサイズなので危険。ケースに収めるか、耳に付ける。外して置くことは絶対にしない。ケースは手の届かないところに置く。
  • ギャン泣きされると何も聴こえない
    • 耳をふさがないから仕方がないね。。。

耳に装着してるLinkBudsに子供が気づくようになったら(危険なので)この手段も使えなくなるんでしょうねぇ。

オチは?

ごめんなさい。ないんです。 この便利さを書き残しておきたかった。そのくらい最高なのです。

OpenWRTとシングルボードコンピュータでIPv6 IPoE対応ルーターをつくる

一般家庭用のBUFFALOのルーターを使っていたのですが、ファームウェアのアップデートを機に不安定になってしまい、古いバージョンに戻しても不安定なままになってしまいました。

自動でアップデートしておいて不安定になるというのが気に食わないので、OpenWRTでルーターをつくることにしました。 既存のルーターには無線LANのAPとして余生を過ごしてもらいましょう。

PINE A64?なにそれ?

今回はシングルボードコンピュータのPINE A64を使用します。

Raspberry Piが値上がり&在庫なしの時代に、秋月電子で2,980円でいつでも在庫があるシングルボードコンピュータです。

2022年となっては型落ち感がありますが、Raspberry Pi使う大抵の用途ってこのスペックで十分なのでは?と思ってたりします。電源が2Aでいいのも調達がラク

PINE A64+1GB BOARD (PINE64): マイコン関連 秋月電子通商-電子部品・ネット通販

NICはひとつしかないため、手元に余っていた100BASE-TXのUSB-LANアダプタ、USB無線LANドングルを追加しました。

流れ

さて、こんな流れでつくります。

  1. OpenWRTの用意
  2. 設定
  3. ニチバンベンチ対策
  4. ケースを作る

OpenWRTの用意

OpenWRT公式サイトからイメージをダウンロードするのですが、今回は事前にイメージをカスタマイズします。

バージョンはあえて最新の22ではなく21を使用します。

22はファイアウォールiptablesじゃなくてnftablesになっていて、iptables前提の後述のニチバンベンチ対策ができないので見送りました。

https://firmware-selector.openwrt.org/?version=21.02.5&target=sunxi%2Fcortexa53&id=pine64_pine64-plus

今回はいくつかパッケージを追加する必要があったので、事前にカスタマイズしておくことにしました。

以下、カスタマイズで入れたパッケージ一覧。

base-files
brcmfmac-firmware-usb
busybox
ca-bundle
cgi-io
dnsmasq
dropbear
e2fsprogs
firewall
fstools
fwtool
getrandom
hostapd-common
ip6tables
iptables
iptables-mod-conntrack-extra
iptables-mod-ipopt
iw
iwinfo
jshn
jsonfilter
kernel
kmod-brcmfmac
kmod-brcmutil
kmod-cfg80211
kmod-fs-vfat
kmod-hid
kmod-hid-generic
kmod-rt2800-usb
kmod-input-core
kmod-input-evdev
kmod-ip6-tunnel
kmod-ip6tables
kmod-ipt-conntrack
kmod-ipt-conntrack-extra
kmod-ipt-core
kmod-ipt-ipopt
kmod-ipt-nat
kmod-ipt-offload
kmod-ipt-raw
kmod-iptunnel6
kmod-lib-crc-ccitt
kmod-libphy
kmod-mii
kmod-mmc
kmod-nat46
kmod-nf-conntrack
kmod-nf-conntrack6
kmod-nf-flow
kmod-nf-ipt
kmod-nf-ipt6
kmod-nf-nat
kmod-nf-reject
kmod-nf-reject6
kmod-nls-base
kmod-nls-cp437
kmod-nls-iso8859-1
kmod-nls-utf8
kmod-ppp
kmod-pppoe
kmod-pppox
kmod-slhc
kmod-sound-core
kmod-usb-core
kmod-usb-hid
kmod-usb-net
kmod-usb-net-asix
libblkid1
libblobmsg-json20210516
libc
libcomerr0
libext2fs2
libf2fs6
libgcc
libgcc1
libip4tc2
libip6tc2
libiwinfo-data
libiwinfo-lua
libiwinfo20210430
libjson-c5
libjson-script20210516
liblua5.1.5
liblucihttp-lua
liblucihttp0
libnl-tiny1
libpthread
librt
libsmartcols1
libss2
libubox20210516
libubus-lua
libubus20210630
libuci20130104
libuclient20201210
libustream-wolfssl
libustream-wolfssl20201210
libuuid1
libwolfssl5.2.0.99a5b54a
libxtables12
logd
lua
luci
luci-app-firewall
luci-app-opkg
luci-base
luci-lib-base
luci-lib-ip
luci-lib-jsonc
luci-lib-nixio
luci-mod-admin-full
luci-mod-network
luci-mod-status
luci-mod-system
luci-proto-ipv6
luci-proto-ppp
luci-ssl
luci-theme-bootstrap
map
mkf2fs
mtd
netifd
odhcp6c
odhcpd-ipv6only
openwrt-keyring
opkg
partx-utils
ppp
ppp-mod-pppoe
procd
px5g-wolfssl
rpcd
rpcd-mod-file
rpcd-mod-iwinfo
rpcd-mod-luci
rpcd-mod-rrdns
uboot-envtools
ubox
ubus
ubusd
uci
uclient-fetch
uhttpd
uhttpd-mod-ubus
urandom-seed
urngd
usign
wireless-regdb
wpad-basic-wolfssl

USB-LANアダプタ、USB無線LANドングルを使うので、そのドライバを追加しています。

  • kmod-rt2800-usb
  • kmod-usb-net-asix

あとは、MAP-E関連で必要なパッケージを追加しました。

生成されたイメージはext4ではなくsquashfsの方をダウンロードし、sdカードに書き込みました。

設定

以下、自分用めも。

  1. PCとPINE A64のLANポートを接続し、電源ON
  2. WiFi設定。アクセスポイントとして動くようにする
  3. アクセスポイントに接続し、以後そこから設定する
  4. OpenWRT – OSAKANA TAROのメモ帳 ここを参考に設定
  5. WAN6 -> WAN -> LAN(ここで既存のブリッジは削除した) -> MAP-E
  6. DNS設定
  7. Network > DHCP and DNS
    • General Settings
    • Resolv and Host Files
      • Ignore resolve file のチェックをいれる

ニチバンベンチ対策

Network > Firewall > Custom Rules に以下スクリプトを設定します。

# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.

# Internal uci firewall chains are flushed and recreated on reload, so
# put custom rules into the root chains e.g. INPUT or FORWARD or into the
# special user chains, e.g. input_wan_rule or postrouting_lan_rule.

units1=15 #V6plus:15 OCN:63
units2=4096 #V6plus 4096 OCN:1024
IP4='YOUR_IP'
PSID='YOUR_PSID'
TUNDEV='map-WAN_MAP'


iptables -t nat -F PREROUTING
iptables -t nat -F OUTPUT
iptables -t nat -F POSTROUTING

rule=1
while [ $rule -le $units1  ] ; do
  mark=`expr $rule + 16`
  pn=`expr $rule - 1`
  portl=`expr $rule \* $units2 + $PSID \* 16`
  portr=`expr $portl + 15`

  iptables -t nat -A PREROUTING -m statistic --mode nth --every $units1 --packet $pn -j MARK --set-mark $mark
  iptables -t nat -A OUTPUT -m statistic --mode nth --every $units1 --packet $pn -j MARK --set-mark $mark

  iptables -t nat -A POSTROUTING -p icmp -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
  iptables -t nat -A POSTROUTING -p tcp -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
  iptables -t nat -A POSTROUTING -p udp -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
  rule=`expr $rule + 1`
done

System > Startup > Local Startup に以下を追記します。

sleep 30
sh /etc/firewall.user

ケースを作る

あとはいい感じにケースを作ります。

fusion360モデリングして、Prusa i3 MK3S+で出力しました。

PNE A64はRaspberry Pi互換のピンヘッダが備わっているので、3.3VとGNDを使ってファンを動かしています。

ということで!

十分なスループットが出せるルーターができました。

我が家は回線が速くないからね。。。

セットアップしたり、ケース設計したり、そんな手間がなくても10,000円あれば購入できる普通のルーター、優秀ですねぇ。

余談

余ってたLED付ファンにしたので、主張が激しい。

AVMK-5(deej)のubuntu環境設定

普段AVMK-5はUbuntuのインストールされたPCで使っています。

Linux用のdeejアプリケーションはビルド済のものが公開されていないため、自分でビルド、設定する必要があります。

今回はビルド~設定方法までをまとめました。

ビルド

ビルド用のスクリプトも用意されています。 https://github.com/omriharel/deej/blob/master/pkg/deej/scripts/README.md

git clone https://github.com/omriharel/deej
./pkg/deej/scripts/linux/build-release.sh

ビルドできました。

ls -lh deej-release
-rwxrwxr-x 1 aose aose 5.1M  5月 14 14:13 deej-release*

config.ymlの作成

同じディレクトリにある config.yml を修正します。

com_port にはAVMK-5を接続した際に出てきた /dev/ttyUSB0 を設定します。(PCによって異なる)

私のアプリ設定はこんな感じ。

  • マイク音量
  • deejで指定していないアプリの音量
  • Discord
  • Spotify
  • システム音量
slider_mapping:
  0: mic
  1: deej.unmapped
  2: discord
  3: spotify
  4: master

invert_sliders: false

com_port: /dev/ttyUSB0
baud_rate: 9600

noise_reduction: default

udev設定

そのままだと一般ユーザーで/dev/ttyUSB0を参照する権限がありません。

udevの設定を変更し、AVMK-5を接続した時に読み取りの権限を得られるようにします。

sudo vim /lib/udev/rules.d/50-udev-default.rules

, MODE="0666" を追記

KERNEL=="tty[A-Z]*[0-9]|ttymxc[0-9]*|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout", MODE="0666"

あとはdeejを起動して動作を確認します。

./deej-release

スタートアップ登録

起動時にdeejのアプリケーションが起動するよう設定します。

deejは実行時のカレントディレクトリにある config.yml を参照するので、直接パスを指定して起動ができません。 起動用のスクリプト run-deej を作成します。

#!/bin/bash

cd /PATH/TO/deej

./deej-release

~/.config/autostart/deej.desktop を追加。

[Desktop Entry]
Type=Application
Exec=/PATH/TO/deej/run-deej
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name[ja_JP]=Deej
Name=Deej

ということで

Ubuntu環境でAVMK-5を使えるようになりました!

AVMK-5 はキットとして頒布しています。

aose.booth.pm

ビルドガイドはこちら。

AVMK-5 ビルドガイド - あおせのにっき

↑ これはWindows PCで動作確認したとき

AVMK-5 ビルドガイド

目次

  • AVMK-5とは?
  • キットの中身について
  • 別途購入が必要なもの
  • 必要な工具
  • 組み立て

AVMK-5とは

AVMK-5(Arduino Volume Mixer Kit 5)はArduinodeejを使ったボリュームミキサーのキットです。

Arduinoを使い安価な部品でミキサーを作成することができます。

deejとは

deejはオープンソースのハードウェアボリュームミキサーです。

各ボリュームにマスターボリューム、マイク、任意のアプリケーションなどを割り当てて音量を調節することができます。

参考:


www.youtube.com

AVMK-5について

本キットは、deejを製作するためのケースとなります。

ケースとして以下の特徴があります。

  • 内部パーツがすべて日本国内で入手可能
    • 国内で入手できるパーツに合わせた寸法
    • パーツはすべて秋月電子で安価に購入することが可能
  • デザイン性
    • 完成後はネジ、USB端子部などデザイン上のノイズになるものを隠すデザイン
    • ボリュームノブは汎用品ではなく専用の3Dプリント品にして一体感をプラス
  • 組み立てやすさ
    • 組み立て治具を添付、日本語マニュアルあり(本ガイドです!)

キットの中身について

キットの内容部が揃っているか確認してください。

※内部フレームなど外側から見えないパーツについては外装と異なる色の場合があります。

部品 数量
ケース天板 1
ケース底板 1
内部フレーム 1
ボリュームノブ 5
Arduino Nano Every用コネクタパネル 1
Arduino Nano Every用固定パーツ 1
コネクタパネル(フリー) 1
タッピングネジ(予備1本含) 12
スライドボリューム位置合わせ治具 1
ゴム足 4

別途購入が必要なもの

次の部品は別途購入が必要です。

秋月電子、AliExpressなどで適宜調達してください。

deejの製作にはArduinoが必要となります。

本キットはArduino Nano Everyが固定できるよう設計されていますが、ケース内に収めることができれば別のArduinoやNANO 互換品を使用することも可能です。

部品 数量
【P-16266】赤色LED付スライドボリューム 10kΩB 60mm 5
【P-07618】片面ガラス・ユニバーサル基板 Aタイプ 2.54mm 155×115mm 1
Arduino Nano Every(※1) 1
1kΩ抵抗(※2) 5
銅線 適量

※1 Arduino Nano Every はピンヘッダの付いていないものを用意してください。

※2 スライドボリュームのLEDを点灯させたい場合のみ必要です。

必要な工具

  • はんだごて
  • はんだ
  • ニッパー
  • プラスドライバー
  • マスキングテープ(仮固定できればその他テープでも可)

組み立て

スライドボリュームの取付位置の確認

スライドボリュームはユニバーサル基板にとりつけるので、ケース天板の穴と一致する場所に取り付ける必要があります。

いきなりはんだ付けするのではなく、ケースにあてがって位置を確認してください。

  1. ユニバーサル基板に治具を固定する

    ユニバーサル基板のランドのない面に治具をかぶせるように固定します。

  2. スライドボリュームを設置する

    治具で位置を確認しながら、スライドボリュームを基板に差し込みます。

    スライドボリュームは上下でピン数が異なりますので、治具に記載されているピンマークと向きを揃えてください。

    ※取り付けにはピンを少し曲げる必要があります。

  3. スライドボリュームを仮固定する

    基板から治具を取り外し、スライドボリュームをマスキングテープで仮固定します。

  4. ケース(天板)をかぶせる

    基板の上にケース(天板)をかぶせ、スライドボリュームのノブが5本ともケースの穴から出せるか確認します。

はんだ付け

Arduino、ユニバーサル基板にスライドボリュームをはんだ付けします。

配線が内部フレームと干渉しないか確認してからはんだ付けするようにしてください。

スライドボリュームのLEDを点灯させる場合は1kΩ抵抗を追加します。

Arduinoファームウェア書き込み

Arduinoへのファームウェア書き込みについてはdeejの解説を参照してください。

※LED点灯用ファームウェアについて こちらからダウンロードしてください。

動作確認

ケースに組み込む前にPCに接続して動作を確認してください。

PCの設定

Windows PC用ソフトウェアのインストール方法はdeejの解説を参照してください。

ケース組み立て

  1. 基板の取付

    1. ケース(天板)、内部フレーム、タッピングネジ4本を用意します。
    2. ケース(天板)を裏返して、基板を載せます。
      • ※向きを確認しましょう。反対の場合はネジ穴が合いません。
    3. 内部フレームを基板の上に載せ、ケース(天板)にネジ止めします。
      • ※向きを確認しましょう。反対の場合はケース(天板)に干渉して取付できないようになっています。
  2. Arduinoの固定

    • Arduino Nano Everyの場合

      1. Arduino Nano Every用固定パーツをケース(底面)に取り付けます。
      2. Arduino Nano Every用コネクタパネルをケース(底面)に取り付けます。
        • Arduino Nano Everyを挟みこむようにコネクタパネルを取り付け、ケース底面からネジ止めします。

    • その他のArduinoを固定する場合

      1. コネクタパネル(フリー)の穴にArduinoに接続するUSBケーブルを通します。
      2. コネクタパネル(フリー)をケース(底面)に取り付けます。
      3. コネクタパネル(フリー)にケーブルを通して、結束バンド(付属しない)で固定します。
      4. ケース(底面)に両面テープ、ホットボンドなどを使用してArduino基板を固定します。
        • ※ケース(天板)が閉じられるか、基板や内部フレームとの干渉を確認してから固定してください。
  3. ケースを閉じる ケース(天板)とケース(底面)を合わせて底面からネジ止めします。

  4. ノブをとりつける スライドボリュームにノブを差し込みます。

  5. ケース(底面)にゴム足を貼り付ける ケース(底面)に貼り付け位置を示すマークがありますので参考にしてください。

  6. おつかれさまでした! 🎉

Fusion360用デバイスを作る(ORBION v2.2)めも

f:id:polaroidoon:20220320171213j:plain

実はずっと欲しかった3Dマウス

2月頃、Twitter3Dプリンタ関連でフォローしている方が何人か同じデバイスを作られていました。

ORBION。

3Dマウスと呼ばれる3DモデリングやCAD用のデバイスですね。

私が知っているのだとこんなのとか。Amazon.co.jpで20,000円近い価格で販売されています。

www.amazon.co.jp

さて、このORBION、GitHubでモデルやソースコードが公開されており、安価な部品を組み合わせて作られています。

必要な部品はArduinoに、ゲームコントローラー用のジョイスティック、ロータリーエンコーダー… 3,000円いかないのでは?という価格。

一度使ってみたかったんですよね、3Dマウス。

この価格なら試してみたい!ということで、私も作ってみることにしました。

製作過程

逐次Twitterにあげてたのでまとめて貼ってお茶を濁します。

AliExpressで部品を発注しました。全部で2,000円しないくらい。悲しいかな、半分は送料です。

しかも同じセラーからふたつにわけて発送するということで、それぞれ送料取られたうえに、まとめて1パックで届けられました。...さすがにズルくない?

手持ちの熱圧入ナットは寸法が一致しませんでしたし、圧入が得意ではないので普通のM3ナットに変更しました。 使ったM3ナットは14個。手持ちのナットも使ったので、不足分だけ購入しました。20円。やっすい。

TPUフィラメントに初挑戦。

なんの苦労もなくTPUが出力できました。Prusa優秀。

部品が届き始めましたが、品質に難あり。まず直すところから始めました。

細いケーブルが必要だったので、捨てるつもりだったケーブルを解体して取りました。

Arduino IDEでファームを焼いて…

Type-C のPro Micro互換機のサイズが違ったので結局モデルを修正したりして

1カ月待ったボタン、本体より送料のほうが高かったボタン、届いて数回で壊れまして。。。

はんだ付けして、組み立てます。

組み立て順序を守らないと組めないなど、ちょっと面倒です。

手先の器用さが足りない…

はい。できあがりました。

使い方は雰囲気とソースから読み解きます。

バグ?

バグなのか変な挙動をするので、ソースを直しました。

ソースコードを修正してArduino IDEで書き込もうとしたのですが、エラーになりました。

リセットして、空のスケッチを書き込むと直るらしい。ということで、RESETスイッチを付けました。

RESETスイッチを押してすぐ書き込み・・・RESETは数秒しか効かないので、何度かやり直しました。

感想

まだ慣れていないので、左手はキーボードに置いてる方が操作しやすいのですが、しばらく使ってみようと思います。

AliExpressで購入したボタンが壊れたので代わりに取り付けたOMRONスイッチですが、

よく使うキーを割り当てたこともあり非常に操作感が良くなりました。もうこれが標準でいいんじゃないでしょうか。

開発コミュニティについて

GitHubに公開されているけれど、独特な運営方法ですね。

  • PullRequestは受け付けていない
  • 改善点があれば、Discord上で作者に伝える(反映されるとは言ってない)
  • GitHubにモデルやファームウェアが公開されているが、Gitでバージョン管理されていない

なにより、ライセンスが厳しくてForkして公開することすら許されていません。

私は安価なところに惹かれてv2.2を作りましたが、新しいバージョンでは部品点数が増え、組み立て難易度が上がっていくようですので、私のORBION製作はv2.2までになりそうです。

Raspberry Piを使ってUSBキーボードの配列をremapするめも

Capslock?そいつなら1x年前にCtrlに置き換えたよ

私は日頃、キーボードのCapslockキーをCtrlキーにremapして使用しています。

最近はUSB切り替え器を使っていて、一組のマウスとキーボードをPCやRaspberry Piなど複数の機材で使用する機会も増えました。

機材ごとに都度キー設定するのは面倒だし、やんごとない理由でキー設定できない機材もあるし できればキーボード側でremapさせたいと思っていました。

ここで「自作キーボードつくるよ!」となるのが現在は主流でしょうが、私の場合は10年以上使い続けている今のキーボードに満足しているのでそのまま使用したいところです。

ということで、今回は既存キーボードをremapできるように手を加える方向で考えてみました。

紆余曲折(+オチ)があったのですが、結論だけまとめずに失敗含めてここに残しておこうと思います。

f:id:polaroidoon:20220304185154j:plain

キーボードとPCの間にremapするなにかを挟む

キーボードで押されたキーをremapしたキーに置き換えてPCに伝えることが目標となります。

今回はRaspberry Piを使って、remapさせることにしました。

イメージ
Keyboard --> Raspberry Pi ---(USB OTG)--> USBハブ --> USB切り替え器 --> PCやRaspberry Pi
                       ↑ココ

Raspberry Piに接続したキーボードをremapする…ちょうどピッタリのものを見つけました。

https://github.com/viggofalster/kiri

そこらへんに転がってるRaspberry Piに導入すれば簡単にできそうですね!さくっと作ってみましょう(フラグ)

失敗1 Raspberry Pi Zero Wで作るremapデバイス

自宅に転がっていたRaspberry Pi Zero Wを使って試してみることにしました。

で、さっそくキーボードを接続して…動かない。

そう、Raspberry Pi ZeroのUSBポートは以下の2つなのです。

  • 電源供給専用
  • USBデバイスを接続 / USB OTG(排他)

排他!

USBキーボード繋げたらPCにつなげるポートがありません。

おとなしくRaspberry Pi 4Bを購入することにしました。

失敗2 Raspberry Pi 4B で作ったが、効かないキーがある

Raspberry Pi 4Bが届いたところで作業再開です。

microSDカードはZero Wで設定したものをそのまま使用します。

ケースはThingiverseに公開されていたモデルを3Dプリントしました。 www.thingiverse.com

USBハブの電力ではRaspberry Piが動いてくれないので、信号と電源でケーブルを分けます。

USB-C Data/Power Splitterthepihut.com

Splitterのケースはいい感じに3Dプリントします。

基盤自体のデータはGrabCADで公開されていました。

grabcad.com

f:id:polaroidoon:20220311181059g:plain

あとはconfig.pyを設定して… 動きました。

満足感に浸りながらキーボードを使います。

そして気づきます。

「無変換」「変換」「¥」「\」キーが効かない!

失敗3 キーが効くぞ!(Windowsのみ)

動作確認に使っていたWindows PCで効かないキーのキーコードを確認しました。

www2d.biglobe.ne.jp

たとえば「¥」キーはキーコードが 89

次は kiri.py がキーボードとしてどのキーコードを出してるか確認してみましょう。

aキー

[2022-03-04 14:44:00,247|root|INFO] Writing report to output: 00:00:04:00:00:00:00:00

キー

[2022-03-04 14:44:03,320|root|INFO] Writing report to output: 00:00:c2:8b:00:00:00:00:00

…桁、長くね?

知らないキーコード c2 があるし、桁数変わってますね。

89UTF-8にすると 0xC2 0x89 になる。これが原因ですね。

コード全体を直す気がないので、 応急処置しました。

# git diff kiri.py
diff --git a/kiri.py b/kiri.py
index 9106237..629fb3d 100644
--- a/kiri.py
+++ b/kiri.py
@@ -131,9 +131,9 @@ class Kiri:
             self.update_state()

     def write_report(self, report: str):
-        self.log.debug('Writing report to output: %s', ":".join("{:02x}".format(c) for c in report.encode('utf-8')))
+        self.log.info('Writing report to output: %s', ":".join("{:02x}".format(c) for c in report.encode('latin-1')))
         with open('/dev/hidg0', 'rb+') as fd:
-            fd.write(report.encode())
+            fd.write(report.encode('latin-1'))

     @staticmethod
     def set_bit(value, bit):

無事Windowsで「無変換」「変換」「¥」「\」キーが効くようになりました!

さっそく普段使っているUbuntuのデスクトップマシンに接続してみましょう。

…やっぱり効かない。

解決編 キーが効くぞ!(WindowsUbuntuもOK)

コードの問題は解決したはずなのに効かない。

さきほどはコード kiri.py を疑いましたが、コードが悪いのか切り分けが必要ですね。

コードやキーボードを使わず、Raspberry Pi上で直接 /dev/hidg0 に流し込んでみます。

a

echo -ne "\0\0\x4\0\0\0\0\0" > /dev/hidg0
echo -ne "\0\0\0\0\0\0\0\0" > /dev/hidg0

\

echo -ne "\0\0\x89\0\0\0\0\0" > /dev/hidg0
echo -ne "\0\0\0\0\0\0\0\0" > /dev/hidg0

a しか効きませんね。

疑うべきはコードではなく…キーボードとして正しく認識されていない?という点です。

こんな例もあります。HIDクラスのディスクリプタの内容は正しいのでしょうか?

jtakao.web.fc2.com

キーボードを直接つないだときと、Raspberry Piをつないだときで比較してみました。

まず、直接キーボードを接続した場合。

$ lsusb
Bus 003 Device 006: ID 04d9:2011 Holtek Semiconductor, Inc. Keyboard [Diatec Filco Majestouch 1]

$ sudo usbhid-dump -e descriptor -a 003:006
003:006:000:DESCRIPTOR         1646550972.361890
 05 01 09 06 A1 01 05 07 19 E0 29 E7 15 00 25 01
 75 01 95 08 81 02 95 01 75 08 81 01 95 03 75 01
 05 08 19 01 29 03 91 02 95 05 75 01 91 01 95 06
 75 08 26 FF 00 05 07 19 00 29 91 81 00 C0

内容を見やすくしてくれるサービスがありました。

eleccelerator.com

0x03, 0x06, 0x00, 0x05, 0x01,  // Unknown (bTag: 0x00, bType: 0x00)
0x09, 0x06,        // Usage (0x06)
0xA1, 0x01,        // Collection (Application)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0xE0,        //   Usage Minimum (0xE0)
0x29, 0xE7,        //   Usage Maximum (0xE7)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x08,        //   Report Count (8)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01,        //   Report Count (1)
0x75, 0x08,        //   Report Size (8)
0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x03,        //   Report Count (3)
0x75, 0x01,        //   Report Size (1)
0x05, 0x08,        //   Usage Page (LEDs)
0x19, 0x01,        //   Usage Minimum (Num Lock)
0x29, 0x03,        //   Usage Maximum (Scroll Lock)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x05,        //   Report Count (5)
0x75, 0x01,        //   Report Size (1)
0x91, 0x01,        //   Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x06,        //   Report Count (6)
0x75, 0x08,        //   Report Size (8)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0x00,        //   Usage Minimum (0x00)
0x29, 0x91,        //   Usage Maximum (0x91)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

// 65 bytes

次にRaspberry Piです。

$ lsusb
Bus 003 Device 005: ID 1d6b:0104 Linux Foundation Multifunction Composite Gadget

$ sudo usbhid-dump -e descriptor -a 003:005
003:005:000:DESCRIPTOR         1646550112.843986
 05 01 09 06 A1 01 05 07 19 E0 29 E7 15 00 25 01
 75 01 95 08 81 02 95 01 75 08 81 03 95 05 75 01
 05 08 19 01 29 05 91 02 95 01 75 03 91 03 95 06
 75 08 15 00 25 65 05 07 19 00 29 E7 81 00 C0
0x03, 0x05, 0x00, 0x05, 0x01,  // Unknown (bTag: 0x00, bType: 0x00)
0x09, 0x06,        // Usage (0x06)
0xA1, 0x01,        // Collection (Application)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0xE0,        //   Usage Minimum (0xE0)
0x29, 0xE7,        //   Usage Maximum (0xE7)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x08,        //   Report Count (8)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01,        //   Report Count (1)
0x75, 0x08,        //   Report Size (8)
0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x05,        //   Report Count (5)
0x75, 0x01,        //   Report Size (1)
0x05, 0x08,        //   Usage Page (LEDs)
0x19, 0x01,        //   Usage Minimum (Num Lock)
0x29, 0x05,        //   Usage Maximum (Kana)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x01,        //   Report Count (1)
0x75, 0x03,        //   Report Size (3)
0x91, 0x03,        //   Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x06,        //   Report Count (6)
0x75, 0x08,        //   Report Size (8)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x65,        //   Logical Maximum (101)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0x00,        //   Usage Minimum (0x00)
0x29, 0xE7,        //   Usage Maximum (0xE7)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

// 66 bytes

Logical Maximum の値が違いますね。

キーボード

0x26, 0xFF, 0x00,  //   Logical Maximum (255)

Raspberry Pi

0x25, 0x65,        //   Logical Maximum (101)

細かな違いを分析するのも面倒なので キーボードと同じディスクリプタを喋らせてしまいましょう。

kiri_usb を修正します。

# git diff kiri_usb
diff --git a/kiri_usb b/kiri_usb
index 848c52b..8b2f2c8 100755
--- a/kiri_usb
+++ b/kiri_usb
@@ -22,7 +22,7 @@ echo 1 > functions/hid.usb0/subclass
 echo 8 > functions/hid.usb0/report_length

 # usb descriptor equivalent to keybrd.hid seen with https://www.usb.org/document-library/hid-descriptor-tool
-echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > functions/hid.usb0/report_desc
+echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x01\\x95\\x03\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x03\\x91\\x02\\x95\\x05\\x75\\x01\\x91\\x01\\x95\\x06\\x75\\x08\\x26\\xff\\x00\\x05\\x07\\x19\\x00\\x29\\x91\\x81\\x00\\xc0 > functions/hid.usb0/report_desc

 ln -s functions/hid.usb0 configs/c.1/
 # End functions

ついにUbuntuでもキーが使えるようになりました!

結論

これ買えばよかった…(あとから教えていただきました)

booth.pm

OctoPrintで使えるネットワークカメラを作る

失敗の原因が知りたい

3Dプリンターの出力に失敗はつきものです。

数多のもじゃもじゃ出力の末にパーツが完成します。

寝る前にプリントを始めた結果、朝には樹脂の塊と向き合う。

そんなことも少なくありません。

失敗するのはいいのですが、せめてどこで失敗したのか?が分からないと改善することができません。

タイムラプス撮影できるカメラを作り、 失敗する瞬間を見て悲鳴をあげましょう 失敗を分析してみましょう。

f:id:polaroidoon:20220223202224j:plain

OctoPrint のタイムラプス撮影を使用する

OctoPrintにはタイムラプス撮影機能があります。

印刷中に一定時間ごと、またはレイヤごとに1枚の写真を撮影し、動画を作成してくれます。

こんな感じ。

OctoPrintで使えるカメラは以下の通り。

Raspberry PiにOctoPrintをインストールしている場合、カメラモジュールを取り付けるだけで撮影できるようです。

しかし、私のOctoPrint環境はRaspberry Piではなく普通のPCなのでカメラモジュールが利用できません。

また、USB接続のWebカメラを持っていません。

今回はRaspberry Piとカメラモジュールを使ってネットワークカメラを作り、OctoPrintから使用することにしました。

Raspberry Pi が手に入らない!

昨今の半導体不足により、Raspberry Piが入手しづらい状況です。高いし売り切れてるし…

今回は使い道がなくて死蔵していた 初代 Raspberry Pi を使用します。

カメラモジュールは余っていたAliExpressで300円程度で購入したものを使用します。

ケースを作る

初代Raspberry Piを使用したいい感じのケース…というのはモデルが見つけられなかったので、適当に作成します。

  • カメラモジュールが搭載できる
  • 三脚固定用にアルカスイス互換のクイックシューが使用できる
  • 自然空冷で冷やせる通気性のよいデザイン

GrabCADで見つけた初代Raspberry Piのモデルをもとに、Fusion360でケースをモデリングします。

https://grabcad.com/library/raspberry-pi-model-b

ケースのモデルは Prusa Prints に登録しました。https://www.prusaprinters.org/prints/136584-raspberry-pi-model-bfirst-gen-casealca-swiss-style

Raspberry Piをネットワークカメラにする

OctoPrintはmjpeg配信してくれるカメラに対応しているので、今回用意したRaspberry Pi をネットワークカメラとして公開できるようにします。

  1. Raspberry OSをインストール
  2. mjpg-streamを導入
  3. Overlay FSを導入 失敗

raspberry OS

ここを参考にインストールします。

aose.hatenablog.jp

mjpeg-stream

カメラモジュールで撮影した画像をストリーミング配信します。

https://github.com/jacksonliam/mjpg-streamer/tree/master/mjpg-streamer-experimental

git clone https://github.com/jacksonliam/mjpg-streamer/tree/master/mjpg-streamer-experimental

start.shを修正して、systemdに登録しました。

start.sh

#!/bin/sh
export LD_LIBRARY_PATH="$(pwd)"
./mjpg_streamer -o "output_http.so -p 8080"  -i "input_uvc.so -r SXGA -hf true -vf true"

mjpg-streamer.service

[Unit]
Description=mjpg-streamer
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/mjpg-streamer/mjpg-streamer-experimental/
ExecStart=/bin/sh start.sh

[Install]
WantedBy=multi-user.target

これで以下URLから映像が確認できます。ブラウザーVLCで開いて確認します。

http://[IPADDRESS]:8080/?action=stream

overlayFS

電源を雑にON/OFFしてもいいように、ReadOnlyのファイルシステムにしておくとよいでしょう。

ですが、今回は初代RaspberryPiだったのでメモリが足りず起動できなくなったので断念しました。

壊れたら次のSDカードを用意しましょう…

OctoPrintに設定する

こんな感じ f:id:polaroidoon:20220222175236p:plain

完成

おめでとうございます。もじゃもじゃが生まれる瞬間を目にすることができましたね!

タイムラプス撮影できる環境ができあがりました。

ホントは成功する動画が撮れたほうがうれしいんだけど…