Raspberry Pi zero W + IR

家で転がっていた使われないでいたRaspberry Pi zero Wを使って、家庭内のリモコン機器を自動化しようと思い立ち、秋葉原くんだりまで行って諸々部品を買ってきました。 ゴミを二つほど生成したのち、最終的に動くモノができましたので備忘録的に残しておきます。 pic.twitter.com/e55qxX5GL6 — nasa9084@某某某某(0x1a) (@nasa9084) July 29, 2019 主に「格安スマートリモコンの作り方 」を参考にしました。部品を購入した店は秋月電子で、商品ページの下の方にある「店舗情報」のリンクをクリックすると店内のどの棚に商品があるのかわかり便利です。どの部品も特に珍しい部品ではないため、商品自体がなくなっているようなことは(Pi zero用ユニバーサル基板をのぞき)まず無いように思えます。また、手持ちで0Ω抵抗が(なぜか)在庫してあったため、ジャンパ線代わりに使用しています。 一番見つけづらかったのがPi zero用ユニバーサル基板ですが、これは店の中ではなく、外のRaspberry Pi関連部品が置いてあるところにありました。 上記のQiita記事はさほど古いモノではないため、価格も変わってなかったように思えますが、動くモノができるまでにゴミを二つほど生成した都合上、三倍程度のコストがかかりました。回路周りや半田付けがあまり得意ではない人は覚悟(というほどの額ではないですが)しておいた方が(材料を余分に買っておいた方が)良いでしょう。 余談ですが部品を購入した際、近くのあきばおーでTranscendのmicro SDが安くなっていたため、大して使い道も考えずに32GBのモノを5枚ほど購入しました。 ほとんどの情報は参考にしたQiita記事にまとまっているため詳細は端折りますが、変更点として赤LEDを足してあります。ピカッと可視光が光るので、実行されたということを確認するのに便利です。 参考記事には実際の配線図だけはなかったので、紹介します。 上図が部品面、下図が半田面です。MOSFET 2N7000は平らな面が図の上側、MOSFET IRFU9024NPBFは放熱板(?)が図の下側、赤外線LEDは欠けている側(カソード?)が図の右側、赤LEDは欠けている側が図の左側、赤外線受光モジュールOSRB38C9AAは受光部が図の上側を向くように配置します。私は受光モジュールは図の下方向に向けて折り、受光部が天を向くような形にしました。 ブレッドボード上で配線してそのまま基板に移植したような形になっているため、複雑な配線もなく比較的簡単かと思います。 IRFU9024NPBFの左下はジャンパなので、半田面で配線してもかまいません(私は0Ω抵抗を使用した関係で部品面を通しています)。 実際に配線したもの。右側に温度センサを追加しています 赤外線コードの学習・実行も参考記事通りpigpioを使用しましたが、毎度SSHしてコマンドを実行するのは面倒なため、GoでAPIサーバを実装しました。Goで赤外線をGPIOでいい感じにアレするようなパッケージが見当たらなかったので、GoからPythonのスクリプトを叩くという残念なコードになっております。いいパッケージがあれば誰か教えてください。 systemdかなんかでデーモン化したりなんかして起動しておくと、例えば、 1 $ curl http://raspberrypi.local/playback?key=light:off とかすると部屋の電気が消せます。素晴らしい。 今のところ外部に公開してはいないのですが、外部に公開すると他のサービスとの連携(例えばIFTTT)ができないので、公開したい気持ちがあります。とはいえ、外からむやみに部屋の電気をあれこれされても困るし(だれもやらないとは思いますが)、そのまま公開するのも難しいな、と思っているところです。 とりあえずは扇風機とか、そのあたりをなんかいい感じにアレしたいですね。

2019-07-30 · nasa9084

NATSを触ってみた

NATS はCNCF (Cloud Native Computing Foundation)によってホスティングされているメッセージングシステムです。軽量で高パフォーマンスかつスケーラブルなのが特徴だそうです。オランダのSynadia社が中心となって開発を行っていますが、オープンソースソフトウェアなのでGitHub 上で今トリビュートすることもできます。 Go、NodeJS、Ruby、Java、C、C#、Nginx用のクライアントライブラリはSynadiaによってサポートされており、そのほかにもPythonやElixir用のクライアントなどが存在します。 NATSのサーバ自体(gnatsd)はGoで書かれている ため、バイナリ一つで起動できるほか、、公式Dockerコンテナイメージ やKubernetes用のOperator も用意されているため、簡単に構築・運用することができます。 本記事でも、Dockerで起動したサーバを使用しています。 NATSでは3種類のメッセージングモデルを利用することができます。 Publish/Subscribe Request/Reply Queueing 今回はPub/SubとRequest/Replyを試してみます。 サーバを立ち上げる 実験に先駆けて、まずはサーバを立ち上げます。今回はmacOS High Sierra環境のため、docker for macで起動してみます。 1 $ docker run --rm -d --name nats -p 4222:4222 -p 6222:6222 -p 8222:8222 nats:1.4.0-linux nats:1.4.0-linuxは執筆時点(2019-02-06)でnats:latestです。 ここで三つのポートを空けていますが、それぞれ用途は次の通りです。 :4222: client port :6222: route port :8222: http port それぞれの詳細な説明は割愛しますが、本記事ではクライアントからの接続だけを試してみますので、4222番ポートだけの開放でも問題ありません。 Publish/Subscribe まずは標準的なPub/Subモデルから試してみます。NATSのPub/SubはRedisなどと同様、Wikipedia でいうところの「トピックベース」なPub/Subです。NATSではトピックのことをSubjectとよびます。 NATSのSubjectは階層構造をとることができ、.(ドット)で区切って表現します。Subscriberはこの階層構造の一部にワイルドカードとして*(アスタリスク)を使用することができます。また、>を使用して下の階層すべて、を表現することもできます。 例えば、Subscriberがfoo.bar.*を購読している場合、foo.bar.bazやfoo.bar.quxなどのメッセージを受け取ることができますが、foo.bar.baz.quxは受け取ることができません。一方、foo.bar.>を購読している場合、foo.bar.baz.quxも受け取ることができます。 サンプルコードとして、次のようなものを書いてみました。 Publisher 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package main import ( "log" nats "github.com/nats-io/go-nats" ) func main() { nc, err := nats.Connect("localhost:4222") if err != nil { log.Fatal(err) } defer nc.Close() if err := nc.Publish("subjectFoo", []byte("bodyBar")); err != nil { log.Fatal(err) } } Subscriber 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package main import ( "log" nats "github.com/nats-io/go-nats" ) func main() { nc, err := nats.Connect("localhost:4222") if err != nil { log.Fatal(err) } defer nc.Close() sub, err := nc.Subscribe("subjectFoo", callback) if err != nil { log.Fatal(err) } log.Printf("Subject: %s", sub.Subject) log.Printf("Queue: %s", sub.Queue) ch := make(chan struct{}) <-ch } func callback(message *nats.Msg) { log.Print(string(message.Data)) } それぞれ、適当なファイルに保存し、go runで起動します。あらかじめSubscriber側を起動しておくことで、Publisherを起動した際にメッセージ(今回は"bodyBar")が(Subscriber側で)Printされるはずです。 ポイントは*nats.Conn.Subscribeが非同期な関数で、メッセージを受け取った際にcallback関数が呼ばれる、というところです。 今回のサンプル中では<-chとしてブロックしていますが、何らかの方法でブロックしないと、受け取る前にmainが終わってしまうので注意が必要です。 同期処理したい場合には、*nats.Conn.SubscribeSyncを使用することで次のように書き換えられます。 ...

2019-02-06 · nasa9084

初めての自作ケーブル

こんばんは。以前記事にした ように、現在、職場でErgodox EZ というキーボードを使用しています。これは元々は自作キーボードの一種で、左右分割型のキーボードです。 Ergodox EZでは、右のキーボードと左のキーボードはTRRSケーブル という、4極のイヤホンケーブルみたいなケーブルで接続されています。今まではとりあえず購入時に付属していたケーブルを使用していたのですが、だんだん肩が開いてきて、長さが足りないなーというお気持ちになってきました。どうせならおしゃれなケーブルがいいなぁと思いながら通販サイトで探したのですが、このTRRSケーブル、あまり需要がないのか、種類が多くありません。 じゃぁ自作キーボード勢はどうしてるのだろうか、と思って調査したところ、諦めて売っているものから選ぶか、自作するか、という選択肢のようでした。自作すれば自分好みの色や長さで作れるし、ケーブルくらいなら作れそう!ということで自作ケーブル沼に入門してみました。 今回作ったのはこちら。遊舎工房 さんで販売されている、自作ケーブルキットです。はじめは部材を個別にそろえて作ろうと思っていたのですが、自作キーボード界隈のDiscordサーバ で聞いたところ、最初はこちらのケーブルキットが個別にパーツをそろえるよりも安くておすすめ、と言うことなので早速遊舎工房さんに向かい購入してきました。 セットの内容を確認していきましょう。まずはプラグ。4極の3.5mmフォーンプラグです。Ergodox EZは向かって奥の方にジャックがあるため、L字型なのはうれしいですね。 次は熱収縮チューブ。こちらは購入時に色を選ぶことができます。今回は無難に白を選択しました。 こちらはパラコード。元々はパラシュートなどのひもに使われるらしいのですが、今回はケーブルカバー的なものとして使用します。こちらも色を選ぶことができ、黒を選択しました。 これはスリーブです。パラコードの上からかぶせておしゃれ感を演出します。これ、なんて調べたら売ってるのを見つけることができるんでしょうか。 最後にケーブル本体。50cmです。上からパラコードをかぶせるため、なんかよくわからない色です。 実際に作業していきます。まずはパラコードの中にケーブルを通していきます。パラコードの中には白いひもが入っていますが、これを抜いてあいたスペースにケーブルを通します。ちょっとずつ、パラコードを縮めてひっぱってを繰り返して、ケーブルが全部入りきるまで差し込みます。 こちらが挿入し終わったもの。パラコードはケーブルより長めに用意されているのですっぽり隠れました。 さらに上からスリーブをかぶせます。スリーブの端は非常にほどけやすく、最初入れるのが難しかったです。要注意。 片方の恥をテープで留め、ケーブルを露出させました。露出させた長さはプラグに合わせてあります。 被覆を剥いた状態。四軸のケーブルです。非常に細いため、被覆を剥く時に切ってしまわないかドキドキでした。予算に余裕があればケーブルストリッパーを用意してもいいかもしれません。 ケーブルを端子に半田付けしていきます。冒頭にも書いたように、「ケーブルくらいなら作れそう!」とか思ってましたが、これめっちゃ難しいです。3.5mmフォーンプラグなんで、端子もめっちゃ小さいです。上の方(写真中黄色の線)から付け始めてしまったので、余計難易度が増しました。 反対側の半田付け。これを始める前に端子のカバーと熱収縮チューブをケーブルに通しておきます。そして二度目はさすがに学び、きちんとケーブルの長さを端子にそろえる、下から半田付けを始める、などにより少しきれいにつけれるようになりました。 残念なことにテスターを用意していなかったのでテストしていませんが(大丈夫か?)、この時点で導通とショートしてないかをテストしておくべきでしょう。 半田付けが終わったら熱収縮チューブをネジの直前まで持ってきて温めます。最初はヒートガンを買おうと思ってたのですが、秋葉原で売っていたものはamazonで売ってる安いやつより高かったのと、思ったよりサイズがあってびびったので購入には至りませんでした。Discordで聞いたところによるとドライヤーでもいける、ということだったのでドライヤーで挑戦しましたが、十分収縮しました。 最後にケーブルの端子カバーをはめて(ぴったりのサイズなので、熱収縮チューブをつけた後は非常に通しにくい)完成です。会社に行かないとErgodoxがないので動作確認ができていませんが、無事使えることを祈っています。 このほかにも部材をいくつか購入してきてあるので、もう少しケーブル作りをやって行ってみようと思います。 追記: 使えませんでした

2019-02-04 · nasa9084

zero memory allocation slice filtering

次のように、あるスライスをフィルタリングする関数を書くことがあると思います。 1 2 3 4 5 6 7 8 9 func FilterFoo(arr []string) []string { b := []string{} for _, e := range arr { if IsFoo(e) { b = append(b, e) } } return b } 簡単なベンチマークを書くとわかるように、この関数は返値となるスライスの長さ+1回のメモリアロケーションを行います。一般に、メモリアロケーションの回数は少ない方がパフォーマンスがよく、可能ならばアロケーション回数0を目指したいものです。 今回の場合、次のように書くとメモリアロケーション回数0回の関数を書くことができます。 追記 b := arr[:0]とすると、基底配列に影響が出るので一概に比較できない、とご指摘を受けました。実際に使用する際は副作用に注意しましょう。 このやりかたって引数に副作用あるので、わかってないで使うと危ないような…https://t.co/iKXrXHUD3N https://t.co/CMrAYGJrdA — Yoichiro Shimizu (@budougumi0617) February 4, 2019 append は引数を弄ってしまうので動作が異なりますね。 / “zero memory allocation slice filtering” https://t.co/JFFDJlfIQA — mattn (@mattn_jp) February 5, 2019 追記終わり 1 2 3 4 5 6 7 8 9 func FilterFoo(arr []string) []string { b := arr[:0] for _, e := range arr { if IsFoo(e) { b = append(b, e) } } return b } 違うのは一行目だけですが、ベンチマークを取ってみると、速度面では大きな違いがあります。次のようなベンチマークを実行してみます。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 package benchmark_test import ( "strings" "testing" ) var a = []string{"Hello", "foo.go", "hoge", "bar.go", "baz.go", "fuga"} func IsGoFilename(filename string) bool { return strings.HasSuffix(filename, ".go") } func naive(arr []string) []string { var b []string for _, x := range arr { if IsGoFilename(x) { b = append(b, x) } } return b } func BenchmarkNaive(b *testing.B) { for i := 0; i < b.N; i++ { naive(a) } } func woAlloc(arr []string) []string { b := arr[:0] for _, x := range arr { if IsGoFilename(x) { b = append(b, x) } } return b } func BenchmarkWithoutAlloc(b *testing.B) { for i := 0; i < b.N; i++ { woAlloc(a) } } 結果は次のようになります。 ...

2019-02-04 · nasa9084

Majextand

ラップトップスタンド、というものをご存知でしょうか。いわゆるノートPCを傾けたり、高さを変えるために使用するアイテムです。折りたたみができるものや、PCに貼り付ける小型のものなんかもあります。 貼り付け型のものとしては、Kickflip が人気です。 今回紹介するのも貼り付け型で、その名もMajextand といいます。 特徴としてはとにかく薄い。そしてその薄さにも関わらず、6段階の高さ調整ができる、という点です。 まずはパッケージ。すっきりとしたパッケージです。商品名をggって出てくるブログに掲載された写真では何やら筆文字で書かれているようなパッケージが見られますが、現行品ではなくなったようです。 裏面はこんな感じ。スタンドを使用して画面を高くすることで猫背を防ぎ、頚椎の姿勢を正します。また、18インチ以下のラップトップであれば基本的には使用できます。非常に薄いため、インナーケースなどに入れる場合にも引っかかりません。 パッケージ自体にテープなどは使用されておらず、Majextand本体と同じように引き出す形となっています。パッケージ自体が本体と同じような構造になっているのは素敵な感じがしますね。 本体を取り出しました。非常に薄く、切れ目が入ったただの鉄板と言われても信じてしまいそうです。測ってはいないのですが、他のレビュー記事によるとだいたい10円玉と同じ厚さとのこと。薄い。 しかし、薄さに対して、若干重い気はします。スタンドという用途ですから、強度を確保するには仕方ないのかもしれませんが。 このように引き出して使います。(本当は手前をまず引き出して、奥側は高さ調整のために使う) MacBook Pro (13-inch, 2018)のスペースグレーの底面に貼り付けるとこんな感じ。両面テープは非常に強く、意図的に剥がさなければ剥がれてしまうということはなさそうです。 今回購入したMajextandはグレーで、MacBookのスペースグレーとは若干色味が違いますが、すごく目立つということはなく、安心しました。 購入したばかりでまだ活用できていないのですが、これから使っていきます。

2019-01-28 · nasa9084

年越し鴨南蛮

もう1月も半ばを過ぎ、まもなく2月が来る、というところで今更感を拭うことができない話題なのですが、2018年末(実は時間的には年が明けていたが)に年越しそばとして鴨南蛮を作りました。 さて、鴨南蛮なので鴨肉が必要です。今回はbuilderscon の肉会などでお世話になっているミートガイ さんから鴨の胸肉 を購入しました。 こちらが回答した鴨肉をAnovaでやったやつです。温度は忘れたんですが、大体1~2時間くらいやったやつです。 軽く塩をした後、熱したフライパンで焼き目をつけていきます。皮を下にして、高めの温度でさっとやります。 焼き目をつけた鴨肉です。いい色ですね。 油がたくさん出ます。 鴨から出た油でネギを焼きましょう ネギを焼いている間に鴨を切ります。幸せのため少し厚切りにしましたが、鴨はすこし薄めでもいいかもしれないです。 最後にそばの上に盛り付けて完成。うまい。

2019-01-19 · nasa9084

jessevdk/go-assetsでファイルを埋め込む

Go言語の素敵なところの一つとして、最終的な成果物を1バイナリに収めることができる、という点にあると思う。結果として、非常に簡単にコマンドラインツールなどを配布することができる。 しかし、例えばコード生成を行うようなツールでテンプレートファイルを別途持っているような場合や、アプリケーション中で使う画像などを含む場合など、Goのソースコード以外のファイルを必要とする場合、全てを1ファイルで、とはいかない。 そのような場合に便利なのがjessevdk/go-assets である。以前は多くの人がgo-bindataを使用していたと思われるが、作者がやめてしまったため、使えなくなってしまった。代替としてこれが便利。 jessevdk/go-assetsを使用するには、まずjessevdk/go-assets-builder を使用する。これは、指定したファイルをGoのソースコードに埋め込んで、それらを扱うためのAssetsというオブジェクトを作成してくれるツールである。 インストールは簡単で、go getするだけ。 1 $ go get github.com/jessevdk/go-assets-builder インストールできたら、次のように使う。 1 2 3 $ ls assets/ foo.html.tmpl bar.png $ go-assets-builder assets -o assets.go すると、assetsディレクトリの内容が埋め込まれたassets.goが生成される。今回は特にパッケージ名を指定していないのて、package mainとして作成された。必要なら-pオプションでパッケージ名を指定することもできる。 生成されたあとは、実際に使いたいソースコード内で次のように使う。 1 2 3 4 f, _ := Assets.Open("/assets/foo.html.tmpl") // in production, need to handle error defer f.Close() // Do something with f ここで作成されたfはos.Fileと同じインターフェースを備えている。要するに、os.Openを使用したときと同じように操作することができる。 また、Assetsという変数を別に使いたいときは、go-assets-builderでパッキングするときに-vオプションで変数名を指定することもできる。ディレクトリ全体ではなく、個別のファイルを指定することもできる。

2019-01-17 · nasa9084

きちんとやるnet/http

皆さん、net/httpパッケージは使っていますか? Go言語の標準パッケージであるnet/httpはPythonなどの標準HTTPパッケージに比べ、人間にとっても取り扱いがしやすいため、そのまま使用している方が多いかと思います。 しかし、このnet/httpパッケージ、簡単に使えるように見えて結構落とし穴が多いのです。 1. Response Bodyはクローズする必要がある 次のコードを見てみましょう。 1 2 3 4 5 6 7 8 9 resp, err := http.Get("https://example.com/api") if err != nil { return nil, err } var t T if err := json.NewDecoder(resp.Body).Decode(&t); err != nil { return nil, err } return &t, nil クライアントライブラリなどでよく書きそうな処理ですね。何も問題ないと思いましたか? 公式ドキュメント を見てみましょう。 It is the caller’s responsibility to close Body. Bodyをクローズするのは関数を呼んだ人の責任、とあります。そうです。Response.Bodyは Close()しなければならないのです。ちゃんとクローズされていない場合、次のリクエストでkeepaliveコネクションの再利用がされず、パフォーマンスの悪化やコネクションリークを起こす可能性があります。 2. Response Bodyを最後まで読む Response Bodyをきちんとクローズするように修正したコードが次のようなコードです。 1 2 3 4 5 6 7 8 9 10 resp, err := http.Get("https://example.com/api") if err != nil { return nil, err } defer resp.Body.Close() var t T if err := json.NewDecoder(resp.Body).Decode(&t); err != nil { return nil, err } return &t, nil deferを使うことできちんとクローズできているはずです。 さて、問題はないでしょうか?いいえ、これだけだとまだkeepaliveコネクションの再利用がされない恐れがあります。 ...

2019-01-08 · nasa9084

gitにもaliasの指定ができる件

tl;dr .gitconfigにもaliasの登録ができる [alias]ブロックにaliasを登録する tagsで単数・複数の悩みを解消する discardで変更を取り消す unstageでaddを取り消す uncommitでcommitを取り消す ignoreで.gitignoreを生成する git aliases この記事は今すぐalias登録すべきワンライナー by ゆめみ① Advent Calendar 2018 の6日目の穴埋め記事です。 こちらのアドベントカレンダーは今すぐalias登録べきワンライナーということで、みなさん.bashrcや.zshrcのaliasについて記事を書いてらっしゃいますが、実は.gitconfigという、gitコマンドの設定を書いておくファイルにもaliasの指定ができます。 誰もshellのaliasとは言ってない!(・・・はず)ので、いくつか.gitconfig用に便利なaliasを紹介していきましょう aliasの登録方法 .gitconfigは基本的にiniファイルです。そのため、次のように登録します。 1 2 3 [alias] aliasname1 = some command 1st aliasname2 = some command 2nd 簡単ですね? [alias]というブロックを作成し、alias名=コマンドの形で記述します。 このときコマンドはgit xxxの形で実行される、xxxの部分のみを指定します。 例えば、 1 2 [alias] stat = git status と指定すると実際の実行時にはgit git statusという形で実行されてしまいエラーになるので注意しましょう。 gitのつかないコマンドを実行したい場合は頭に!をつけます。 1 2 [alias] ls = !ls このように記載すると、git lsでlsが実行されます。 git tags git tagというコマンドがありまして。まぁみなさんご存知でしょうが、tagの一覧を出したり、新しいtagを作ったりするコマンドです。これ単体では特に問題がないのですが、リモートリポジトリと合わせて使うと、ちょっと悩みが発生します。 git tagコマンドでタグをつけた後、リモートリポジトリにpushするときのコマンドはgit push --tagsです。これはtagをまとめてpushするので、複数形なんでしょう。しかしです。tagの一覧を出すときに使うのもgit tagと単数形なんですね。 ついついgit tagsと打ってしまいませんか? そんなあなたはこんなaliasを登録しておきましょう 1 2 [alias] tags = tag 地味ですが、これで単数形か複数形か悩まずに済みます。 ...

2018-12-12 · nasa9084

git repositoryの初期化ルーチン

おそらくみなさんもgit repositoryを作る時、毎回だいたい同じような手順で初期化をするのではないでしょうか。 メモがてら、自分の初期化ルーチンをまとめておきます tools 使用しているツールは以下の通り: hub : .zshrc でgitコマンドにエイリアスを張ってます gitignore.io : 先日記事を書いたように 、git ignoreコマンドとして使ってます git-license : 自作のサブコマンドです routine 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # 新しいリポジトリ用のディレクトリを作成 $ mkdir new-repository $ cd new-repository $ git init # GitHub上にnasa9084/new-repositoryリポジトリを作成 # hubコマンドの機能 $ git create # まずは空の状態で初回コミット $ git commit -m 'initial commit' --allow-empty # .gitignoreを作成(今回はgo言語プロジェクト向け) $ git ignore emacs,macos,go > .gitignore $ git add .gitignore $ git commit -m 'add .gitignore for emacs,macos,go' # LICENSEを作成 $ git license -u nasa9084 mit > LICENSE $ git add LICENSE $ git commit -m 'add MIT License' $ git push -u origin master ここまでがルーチンで、ここからMakefileを作ったり開発したりします。 ...

2018-12-07 · nasa9084