Voron0.2用のアクリルバックパネルを遊舎工房でカットしてもらった

はじめに

この記事は 3Dプリンター Advent Calendar 2023 21日目の記事です。

Voron0.2用の8010FANを取り付けるためのアクリルバックパネルを遊舎工房のレーザー加工サービスを利用してカットしてもらったので、記録しておく。

キーボード用では無いのだが、レーザー加工のレギュレーション内であればカットしてもらえるらしい。

yushakobo.jp

動機

Voron0.2には制御ボード類の冷却用に3010FANがついているのだが、これが少し心もとないのと、取り付け位置もよくなさそうだったので、代わりのものが欲しかった

見つけたモデル

  • Voron V0.2 Lower Rear Panel with 8010 MCU fan
  • 8010FANを使うモデル
  • バックパネルは3パターン
    • 一枚板を印刷する(212mm x 185mm)
    • 分割して印刷する(106mm x 95mm程度 x4)
    • アクリルをレーザーカット

発注から受け取りまで

今回はAffinityDesigner2を使って加工データを入稿した。

  1. 遊舎工房のレーザー加工サービスページからテンプレートをダウンロードする
  2. printablesのVoron V0.2 Lower Rear Panel with 8010 MCU fanからレーザーカット用データ「lower rear panel 02.dxf」をダウンロードする。
  3. 加工データの作成
    1. AffinityDesignerでテンプレートを開いて、アクリルA4のレイヤー(アートボード)だけ残して他のレイヤーを削除する。
    2. AffinityDesignerから「lower rear panel 02.dxf」を開いてインポートする。
    3. 別ファイルとして開かれるので、CRTL-Aでパーツをすべて選択して、CTRL-Cでコピーする。
    4. アクリルA4のレイヤーを展開して、レイヤー:カット1(R255/G0/B0)を選択する。
    5. CTRL-Vでコピーしたパーツを貼り付ける
    6. 回転と移動でパーツの位置を調整する。
    7. 最外周の枠「LWPOLYLINE - 0x133」だけ選択して、CTRL-Xでカットする
    8. レイヤー:カット2(R0/G0/B255)を選択する
    9. カットしたパーツをペースト
    10. レイヤー1を選択して、境界線の色をスウォッチの赤、幅を0.3ptに変更する。
    11. レイヤー2を選択して、境界線の色をスウォッチの青、幅を0.3ptに変更する。
    12. 保存して完了
  4. 遊舎工房のレーザー加工サービスで以下の商品を選択して注文
    • 材料カテゴリ:アクリル マット
    • 厚さ: 3mm
    • サイズ: A4
    • D:マットブラック
  5. 遊舎工房から「【遊舎工房】加工データ送付のお願い」というメールが届くので、加工データを添付して返信。
  6. 遊舎工房の担当者が加工データを確認して、問題がなければ加工に進みますという連絡が来る。
  7. 加工が終わったら遊舎工房から発送メールが届く
  8. 受け取り

完成品

ネジ穴の大きさや位置に問題はなく、8010FANをネジ止めできた。 まだ本体側の電装後のチェックが終わってないので、取り付けはまだちょっと先。

RaspberryPIにI2C接続した2004液晶をKlipperから使う

はじめに

Raspberry PIにI2C接続した2004液晶をklipperのディスプレイとして使う方法について書く。

動機

Klipperで3Dプリンタを運用していると、3Dプリンタについてる液晶ディスプレイに温度などの情報が表示されなくなったので、その代わりに表示したかった。

RaspberryPiにOLEDディスプレイを接続してKliiperのディスプレイとして扱う例をみて、もう少しサイズの大きいディスプレイで表示したいと思った。

ブロック図

ブロック図

  • 3Dプリンタの制御にKlipperをインストールしたRaspberryPiを使う
  • RaspberryPIのGPIOに2004液晶を接続して利用する
  • KlipperをインストールしたRaspberryPiを3DプリンタのセカンドMCUとして利用する。

目次

必要なハードウェア

ハードウェア 用途 仕様とか
3Dプリンタ Klipperに対応しているやつなら何でもOK
RaspberryPI Klipper,moonraker,mainsailを動かす
3DプリンタのセカンドMCUとして使う
2004液晶ディスプレイを駆動する
Raspbian bullseye
i2c接続の2004液晶ディスプレイ Klipperのディスプレイとして情報を表示する I2C接続
LCDディスプレイのコントローラがHD44780で、
PCF8574TがI/Oエキスパンダとしてついてるタイプ
I2Cロジックレベル変換ボード LCD用の5V電源からraspberry piのGPIOに電流が流れ込んで壊れるのを防ぐためにいれる PCA9306

I2C接続の2004液晶ディスプレイ

Amazon: Longruner Display R3 Mega2560 2004 LCD Display Module IIC/I2C/TWI Blue Screen Panel Extension Board with 4-Pin Jumper Wire LK51

  • Amazonで売ってるarduino用のよくあるやつ
  • LCD側のコントローラがHD44780
  • PCF8574がi2cのI/Oエキスパンダとしてついてるタイプ
  • 5V駆動なのでI2Cのロジックレベル変換モジュール経由でRaspberry PIに接続

ロジックレベル変換ボード

switch-science: PCA9306搭載 ロジックレベル変換ボード スイッチサイエンス版

ediy-fan.com

配線

Raspberry PIのGPIO端子 ロジックレベル変換ボード 3.3V側 ロジックレベル変換ボード 5V側 2004液晶ディスプレイ(PCF8574T)
1: 3.3V— —VREF1
2: 5V— —VREF2
3: SDA— —SDA1 SDA2— —SDA
4: 5V— —VCC
5: SCL— —SCL1 SCL2— —SCL
9: GND— —GND GND— —GND

pinout.xyz

raspberry piをセカンドMCUとして設定する

Klipperの公式ドキュメントに従って、raspberry pi3DプリンタのセカンドMCUとして設定する。 I2C接続の液晶ディスプレイを使うので、「Optional: Enabling I2C」の部分も実行する。

www.klipper3d.org

klipper-mcuサービスの確認

systemctlを使って確認する

systemctl status klipper-mcu.service
● klipper-mcu.service - Starts the MCU Linux firmware for klipper on startup
     Loaded: loaded (/etc/systemd/system/klipper-mcu.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2023-07-12 21:46:43 JST; 1h 5min ago
       Docs: https://www.klipper3d.org/RPi_microcontroller.html
   Main PID: 396 (klipper_mcu)
      Tasks: 1 (limit: 1595)
        CPU: 2.906s
     CGroup: /system.slice/klipper-mcu.service
             └─396 /usr/local/bin/klipper_mcu -r -I /tmp/klipper_host_mcu

Jul 12 21:46:43 klipper systemd[1]: Started Starts the MCU Linux firmware for klipper on startup.

液晶ディスプレイの動作確認

raspberry piに接続した液晶ディスプレイがちゃんと動くか確認する。

i2cdetectの確認

sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

circuitpythonのhd44780ライブラリを使った確認

github.com

こいつはPCF8574Tにも対応しているらしい circuit python用なのでadafruitのblinkaをraspberry piにインストールする。

blinkaのインストール

learn.adafruit.com

blog.goediy.com

circuitpython-hd44780のサンプルを使った確認

exampleフォルダにlibフォルダに入ってるhd44780.pyへのシンボリックリンクを作成する

ln -s ../lib/hd44780.py hd44780.py
  • main.py
    • Hello CircuitPythonと表示したり、バックライトをON/OFFする。
  • show_charset.py
    • 文字セットを表示する
    • 半角カナが入ってた。

Klipperの改造

klipperのLCDコントロール部分の改造

spi接続のLCDコントローラhd44780用のソースコードがある。

klippy/extras/display/hd44780_spi.py

これを改造してi2c接続用にする

--- hd44780_spi.py   2022-12-16 02:02:27.605696269 +0900
+++ hd44780_i2c.py    2023-07-15 01:01:17.445932287 +0900
@@ -1,5 +1,5 @@
 # Support for HD44780 (20x4 text) LCD displays
-#
+# with PCF8574 I/O Expander
 # Copyright (C) 2018  Kevin O'Connor <kevin@koconnor.net>
 # Copyright (C) 2018  Eric Callahan <arksine.code@gmail.com>
 # Copyright (C) 2021  Marc-Andre Denis <marcadenis@msn.com>
@@ -15,19 +15,21 @@

-class hd44780_spi:
+class hd44780_i2c:
     def __init__(self, config):
         self.printer = config.get_printer()
         self.hd44780_protocol_init = config.getboolean('hd44780_protocol_init',
                                                        True)
-        # spi config
-        self.spi = bus.MCU_SPI_from_config(
-            config, 0x00, pin_option="latch_pin")
-        self.mcu = self.spi.get_mcu()
-        #self.spi.spi_send([0x01,0xa0])
-        self.data_mask = (1<<1)
-        self.command_mask = 0
-        self.enable_mask = (1<<3)
+        # i2c config
+        self.i2c = bus.MCU_I2C_from_config(config, default_addr=0x27,
+                                           default_speed=400000)
+        self.mcu = self.i2c.get_mcu()
+        self.command_mask = 0b0000
+        self.data_mask = 0b0001
+        self.enable_mask = 0b0100
+        self.backlight_mask = 0b1000
+
+

         self.icons = {}
         self.line_length = config.getchoice('line_length', LINE_LENGTH_OPTIONS,
@@ -47,12 +49,14 @@
             (self.glyph_framebuffer, bytearray(b'~'*64), 0x40) ]
     def send_4_bits(self, cmd, is_data, minclock):
         if is_data:
-            mask = self.data_mask
+            mask = self.data_mask | self.backlight_mask
         else:
-            mask = self.command_mask
-        self.spi.spi_send([(cmd & 0xF0) | mask], minclock)
-        self.spi.spi_send([(cmd & 0xF0) | mask | self.enable_mask], minclock)
-        self.spi.spi_send([(cmd & 0xF0) | mask], minclock)
+            mask = self.command_mask | self.backlight_mask
+
+        self.i2c.i2c_write([(cmd & 0xF0) | mask], minclock)
+        self.i2c.i2c_write([(cmd & 0xF0) | mask | self.enable_mask], minclock)
+        self.i2c.i2c_write([(cmd & 0xF0) | mask], minclock)
+
     def send(self, cmds, is_data=False, minclock=0):
         for data in cmds:
             self.send_4_bits(data,is_data,minclock)

hd44780_i2c.pyを使えるようにする

klippy/extras/display/display.pyを修正して、hd44780_i2cを使えるようにする

--- a/klippy/extras/display/display.py
+++ b/klippy/extras/display/display.py
@@ -6,7 +6,7 @@
 #
 # This file may be distributed under the terms of the GNU GPLv3 license.
 import logging, os, ast
-from . import hd44780, hd44780_spi, st7920, uc1701, menu
+from . import hd44780, hd44780_spi, hd44780_i2c, st7920, uc1701, menu

 # Normal time between each screen redraw
 REDRAW_TIME = 0.500
@@ -17,7 +17,8 @@ LCD_chips = {
     'st7920': st7920.ST7920, 'emulated_st7920': st7920.EmulatedST7920,
     'hd44780': hd44780.HD44780, 'uc1701': uc1701.UC1701,
     'ssd1306': uc1701.SSD1306, 'sh1106': uc1701.SH1106,
-    'hd44780_spi': hd44780_spi.hd44780_spi
+    'hd44780_spi': hd44780_spi.hd44780_spi,
+    'hd44780_i2c': hd44780_i2c.hd44780_i2c,
 }

klipperのconfigファイル(printer.cfg)にdisplayの設定を追加する

[mcu rpi]
serial: /tmp/klipper_host_mcu

[display]
lcd_type: hd44780_i2c
i2c_mcu: rpi
i2c_bus: i2c.1
i2c_address: 39 #(0x27)

Klipperからの制御の確認

ファイルを修正して、Klipperを再起動する。 2004液晶ディスプレイにこの記事の冒頭のような表示がでたらOK

mainsailのG-codeコンソールから以下のコマンドを送って、2004液晶にメッセージが反映されるかテストする。

M117 TEST Message

参考にさせて頂いたもの

Klipper OLED接続 - HackMD

LCD1602をRaspberry PiとPCF8574を使って制御する方法

PicBasic ProでI2Cアダプター「PCF8574」を使ってLCD(液晶表示器)に表示

LCD1602Aや2004AをI2C接続で使いこなす【ハード編】 | M5Stack沼人の日記

DE0でFPGAマスターをめざせ! - 20x4 LCD/OLED

LCD Interface

TC2004A-01.pdf

RK-10290_410.pdf

なぜウォーターフォール型の受託開発では終盤に問題が起きがちなのか

結論から言うと

「システムの発注者が受注者に対して設計段階で適切なフィードバックをできていない」

から。

はじめに

これは個人的な経験に基づく意見であり、観測範囲はすごく狭く、広範囲の調査を行ったものではありません。あくまで個人的にはこうだったから、こうなんじゃないかなという仮説とポジショントークてんこもりの話です。

前提とか背景とか

私の経験では受託開発の受託側で仕様の検討から実装・テストまで担当することが比較的多く、また、システム開発にあまり詳しくない発注者が、実際にシステムの開発を行う受注者に発注する開発スタイルが多かったです。

また、開発体制などの都合からまっとうなアジャイル開発やスクラムテスト駆動開発をやったことがありません。

また、この記事での機能仕様書とは、システムの振る舞い=どういう入力があって、どのように処理されて、どのように出力されるかを定義したものであり、Joel on softwareで述べられているところの機能仕様書を想定しています。

場所によっては外部設計などとよばれているかもしれません。

影響を受けているもの

リーンソフトウェア開発の作りすぎの無駄を極力避けるという考え方に、Joel on Softwareの機能仕様書の考え方を混ぜた感じと言ったらいいんでしょうか。

ろくに仕様の検討や設計もせずに先に実装を進めてしまうと、間違って作ってしまった実装やテストの修正コストが無駄になり、何より貴重な時間というリソースを浪費してしまうので、分かる範囲で仕様の検討や設計を行ってから実装しよう。 仕様書の修正コストは実装の修正コストよりも低いからなるべくそこで問題を見つけよう。 仕様書にはシステムがどのように振る舞うか、入力に対してシステムがどのような反応をするか、具体的に、詳細に、網羅的に記述しよう。

そんな考えです。

これまでの経験をふりかえる

私がやってきた仕事の範囲でいうと、発注者側からまともな機能仕様書をもらったことも、発注者の代わりに機能仕様書を作成してその仕様に対して文言・フォーマット・体裁以外で設計に関わる重要なフィードバックをもらった事も、残念ながらほとんどなかった。

これは別に「私の機能仕様書作成能力が高いからフィードバックが無かった」とかそんな理由ではない。 他人が書いた機能仕様書であれば、多かれ少なかれ考えが違う部分はあるはずで、ここはこうしてほしいとか、そういうフィードバックは少なからずあったはずだ。

私の機能仕様書作成能力が低くて、発注者が読んでも分からなかったからフィードバックが無かった? 別に分からないなら分からないでそのことをフィードバックすればいい話だ。

だが、そういったシステム開発を行う上で重要なフィードバックはほとんどもらったことがなかった。 20年ほど前にウォーターフォール型の開発をした時もそうだったし、最近ウォーターフォール型の開発をしたお客さんもそうだった。

ウォーターフォールと修正コスト

一般的なウォーターフォール

一般的なウォーターフォール型の開発はこんな感じ。

一般的なウォーターフォール

バグの修正コスト

で、設計時の問題が後工程になるほど修正コストは指数関数的に跳ね上がる。

バグの修正コスト

http://www.jaspic.org/event/2009/SPIJapan/keynote/SJ9keynote.pdf

*1

図は2009年のもので、オンラインでアップデートが当たり前になった現在の状況はどうなっているか不明だけど、それでも稼働中のシステムの修正には注意と慎重さが必要なので、そのまま利用できると思っている。

この修正コストをウォーターフォールの図に反映するとこうなる。

受け入れになってから問題発覚

本来のウォーターフォール

本来のウォーターフォールでは、開発の各工程で見つけた問題を前の段階にフィードバックする前提があったとか無かったとか。

本来のウォーターフォール

うん、適切にフィードバックがあれば、バグの修正コストの問題が解決できそうですね。 適切にフィードバックがあれば。

でも、なんで今になってもいつもシステム開発の終盤になってから重大な問題が見つかっているのか? バグの原因をたどっていくと、仕様の検討不足や考慮漏れが多いのはなぜなのか? 仕様書のレビューで平仄やフォーマットの指摘が多めになり、設計に関わる部分でのまともなフィードバックが少ないのはなぜなのか?

ウォーターフォールの工程が会社をまたがって分断されている

分断されたウォーターフォール

まず、ウォーターフォールの工程が会社をまたがっており、分断されていることが原因の1つに挙げられる。 契約や納品が絡んでくると、前工程の成果物が間違っていたから修正するというのは難しくなる。 問題がみつかっても、「すでに納品しちゃってるし」「修正するとやり直しが手間だし」「原因究明の報告書を書かないとならんし」みたいな感じで適切なフィードバックがしにくくなる。

本来のウォーターフォール開発では各工程を会社をまたいで行う前提はなかったんじゃないか?

システムの発注者が機能仕様書を読めないのではないか?

会社間をまたぐのが多少手間でも、納品前であればフィードバックはできるはず。 しかしそれすらできていないのはなぜか? もしかして、発注者が書いてもらった機能仕様書を読めていないのではないか?

本来のウォーターフォール開発が提案された時期、大昔のシステム開発は組織内で行うものであり、システム開発に詳しい発注者が仕様を決めるものであり、その前提だったのではないか?

一方で、現代の日本においてはシステムに詳しくない発注者がシステムの開発を依頼するパターンが多いのではないか?

だとすると、システムの発注者がシステムの受注者に機能仕様書を作成してもらったところで、機能仕様書の内容を読み込めず、そのためレビューでは設計に関わる指摘よりもドキュメントの平仄やフォーマットの指摘が多くなり、問題が後工程まで残存し、実際に受け入れ段階になって動かしてみて初めて問題に気づくのではないか?

ではどうするか?

システムの発注者が機能仕様書を読めない、仕様のレビューでフィードバックもできないのだとしたら、根本的に開発プロセスを変える必要がある。

いくらちゃんとした機能仕様書を書いても受け入れテストのときに「思ってたんと違う」をやられて無駄だから、先に動くものを作って確認してもらおうぜっていうアジャイル的開発スタイルにするしかないし、そのスタイルが流行るのもわかる。

しかし、発注側にシステム開発の経験が少ない場合、こういったアジャイル的開発スタイルを利用しても開発コストは減らないし、システム全体の完成時期も早くならない。逆に前工程での無駄を削減できない分開発コストは増えるし、システム全体の完成時期も伸びる。 とりあえず動いているシステムだけは手に入ることだけが救いだ。

結局、先に動くものを作って確認してもらおうぜっていうスタイルであっても発注者側の力量を上げないと解決しない問題なのではないか?

理想的には

  • 実際に作って動かして確認する部分と、機能仕様書を先に作成して開発の無駄を削減する部分を分けること
    • webサービスの詳細な画面設計書をWordに図を貼り付けて作ってたりするけど、HTMLでそのままモックアップ作ればいいんじゃねとか思ってる。
      • そのモックアップの上っ面だけ見てシステムは完成しているじゃないかという客もいるけど。
    • 未検証の技術とか、新しい設計とかは実際に動かしてみて、問題点を見つけて、それを設計に反映するとか。
    • API仕様とかは、どういうパラメタが入力された時に、何がおこって、どういうレスポンスが返されるかとか、エラーパターンとかはちゃんとまとめたい。
  • システム発注者が機能仕様書をレビューできること
  • システム発注者が機能仕様書をレビューできないのであれば、その分増える開発コストを負担すること。

システム発注者に言いたいこと

いくらシステム開発を依頼して作ってもらっているとはいえ、どういうシステムを作って欲しいかは依頼者が決めなければなりません。仕様を提案してもらったり、他人に書いてもらってもいいですが、その仕様をレビューしてフィードバックを行う責任は発注者側にあります。

この世の中にまだ存在していないものを作ろうとしているのですから、「全部おまかせしますからいい感じで」では本当にほしいシステム、役に立つシステムは手に入らないでしょう。

具体的には

  • あなたがほしいと思っているシステムは、まだこの世には存在しておらず、実現可能な仕様として文書化され、網羅されていなければ作ることができません。まずそのような仕様書があれば出してください。
  • そのような仕様書がなく他人に書いてもらうのなら、仕様書を書いてもらうために必要な打ち合わせの分のお金もちゃんと払ってください。
    • 他人の時間と頭脳は無償のリソースではありません。
  • また書いてもらった仕様書のレビューを行い、自分がほしいと思っているシステムと一致しているかの判断と、設計への具体的なフィードバックが必要です。
  • 以上の全てができないのであれば、実際に動くものを作ってもらって、それからフィードバックをかけるしかありません。そのせいでよけいにかかる実装やテストなどの時間的、金銭的コストはあなたが負担してください。

最後に

こういう事を書いてますが、 「仕様を誰かに決めてもらって、決まったモノをそのまま作りたい」 という考えではなく、

  • 自分で良い仕様や適切な仕様を考えたり、提案したりしたいけど、それを無償でやらせられると商売あがったりなので、他人の時間と頭脳に金をちゃんと払え。
  • 設計でなるべく品質を向上させて、バグが後工程に流れることで発生する無駄なコストを削減したい。
  • いちいち作ったあとで間違いだったと気づくのは無駄なので、問題になりそうなところは先に文書という形で明確化し同意をとっておく。

やってみなければ分からない部分はもちろんあるけど、実際に作る前に机上で検討することで削減できるコストもある。 ならば、それぞれを区別して無駄を少なく開発できればいいな。 そういう感じ。

*1:JASPIC SPIJapan2009 ソフトウェア品質保証の方法論、技法、その変遷~先達の知恵に学ぶ~ 2009年10月5日 NARAコンサルティング奈良 隆正

Ergo42(Towel)をLEDテープでアンダーグロウ化した

はじめに

LEDテープを使ってErgo42Towelのアンダーグロウ化に成功したので、記録を残しておきます。

SK6812miniを搭載したLEDテープを利用したので、Ergo42本体に付属しているスペーサーを交換せずにアンダーグロウ化できました。

※この改造は自己の責任で行ってください。

f:id:cnaos:20191230174347j:plain

参考にさせて頂いたもの

目次

必要な材料

  1. 超極細 NeoPixel MiniテープLED(テープ幅4mm SK6812)
    • LEDパラダイスで購入(https://www.led-paradise.com/product/2277)
    • よくあるLEDテープはテープ幅が10mmですが、キースイッチの端子の間を通すために超極細 NeoPixel MiniテープLEDを選択
    • 小さくなればなるほどLEDテープのはんだ付け用のランドも小さくなるので注意。
  2. AWG24相当の配線
    • 今回つかったのは住友電工製のイラックスA
  3. カプトンテープ
    • 基板のスイッチをはんだ付けした部分とのLEDテープ絶縁のため。
    • 6mmと10mmを使った。
  4. フラックス
    • LEDテープのはんだ付け用のパッドおよび導線に塗ってはんだ付けしやすくする。

必要な工具

  1. ワイヤストリッパ
  2. 曲尺(かねじゃく)
    • LEDテープをコの字型に配置したので直角を作るのと、縦と横のLEDテープの相対位置を決めるのに利用した。
  3. ピンセット
    • 配線を持ってはんだ付けするために必要。

作業手順

LEDテープを接続する端子の特定

  1. Ergo42のKiCadデータを見てVCC, GND, TX0, TRRSジャックのXTRA DATAを見つけておく。
  2. Ergo42左手側のTX0から左手側LEDテープのData-INへ、
  3. 左手側LEDテープのData-OUTからErgo42左手側のTRRSジャックのXTRA DATAへ
  4. Ergo42右手側のTRRSジャックのXTRA DATAから右手側LEDテープのData-INへ
左手側

f:id:cnaos:20191231151139p:plain
Ergo42Kicad左手
f:id:cnaos:20191231151224p:plain
Ergo42Kicad左手拡大
f:id:cnaos:20191231151400j:plain
Ergo42実基板左手

右手側

f:id:cnaos:20191231151531p:plain
Ergo42Kicad右手
f:id:cnaos:20191231151641j:plain
Ergo42実基板右手

LEDテープ配置の検討と切り出し

  1. Ergo42の基板に切り出す前のLEDテープを重ねて、どのように配置するか検討する。
  2. LEDテープから利用する分のLEDテープを切り出す
    • 今回は片手分を 縦LED3個x2, 横LED6個 x1にした。
    • 今回は4mmのLEDテープを利用したので、スイッチの端子の間に通すことができた。

※LEDテープの側面がキースイッチの足に触れないように注意する。

f:id:cnaos:20191229192042j:plain
LEDテープの幅の比較
f:id:cnaos:20191231152356j:plain
極細NeoPixel RGBテープLED
f:id:cnaos:20191231152507j:plain
超極細 NeoPixel Mini テープLED
f:id:cnaos:20191231152647j:plain
LEDテープの配置の検討

LEDテープ同士のはんだ付け

LEDテープ同士をはんだ付けしたらErgo42の基板上においてみて問題ないかチェックしつつやると良い。

  1. 切り出したLEDテープを実際に配置する場所において、曲尺(かねじゃく)で縦のLEDテープと横のLEDテープの相対位置を調べる。
  2. はんだ付けマットの上にLEDテープを移して、調べたLEDテープ同士の相対位置を再現して、マスキングテープで固定する。
  3. 配線材を切り出す。
    • 今回利用した配線材はあまり柔軟性が無いものだったので、事前にちょうどよい長さになるように切り出した。
  4. 配線材をはんだ付けする。
    • LEDテープ側にはんだを盛っておく。
    • 剥いた配線材にもフラックスを塗っておく。
    • はんだがブリッジしやすいので注意。
  5. はんだ付けした部分がブリッジしていないかテスターの導通モードを使って確認する。
    • 真ん中のData-IN/Data-OUTとVCCは導通していないこと。
    • 真ん中のData-IN/Data-OUTとGNDは導通していないこと。
    • 接続したLEDテープ同士のVCCとVCCは導通していること。
    • 接続したLEDテープ同士のGNDとGNDは導通していること。
    • 接続したLEDテープの末端同士のData-INとData-OUTは導通していないこと。

f:id:cnaos:20191231153021j:plain
LEDテープ同士のはんだ付け

Ergo42とLEDテープのはんだ付け

TX0へのはんだ付けはProMicroを外して、他の端子にはんだが付着しないようにカプトンテープなどで保護しておく。 また短い導線からはんだ付けすると良い。

  1. Ergo42の基板上にLEDテープを仮止めする。
  2. 配線材をちょうどよい長さになるように切り出す。
  3. 配線材をLEDテープにはんだ付けする。
  4. LEDテープから出ている配線をErgo42の基板にはんだ付けする。

Ergo42の端子とLEDテープが正しくはんだ付けされているかテスターで導通チェック

  • 左手側
    • Ergo42のVCCとLEDテープのVCC
    • Ergo42のGNDとLEDテープのGND
    • Ergo42のTX0とLEDテープのData-IN
    • LEDテープのData-OUTとErgo42のXTRA_DATA
  • 右手側
    • Ergo42のVCCとLEDテープのVCC
    • Ergo42のGNDとLEDテープのGND
    • Ergo42のXTRA_DATAとLEDテープのDATA-IN

Ergo42のアンダーグロウLED対応ファームウェアを書き込む

RGBLIGHT_LIMIT_VALがデフォルト値のままだと電力不足で不安定になるため、最大輝度に制限を入れる。

デフォルト値のままRGBLED_NUMを14から24に増やしたところ、 一瞬だけテープLEDが光って消えるようになり、リセットスイッチを押してもファームウェアの書き込みすらできなくなってしまった。 ProMicroを取り外して、RST端子とGND端子をピンセットで短絡させ、ファームを書き込んで戻したところ問題なく動作するようになった。

※TRRSケーブルを外してファームウェアを書き込む

※左手、右手とも同じファームウェアを書き込む。

  1. qmk_firmwareのkeyboards/ergo42/keymaps/default-underglow以下のconfig.hに以下の変更を入れる
    • RGBLED_NUMを14から24に変更する。
    • 「#undef RGBLIGHT_LIMIT_VAL」を追加する
    • 「#define RGBLIGHT_LIMIT_VAL 128」を追加する。
  2. コマンドラインから「make ergo42:default-underglow:flash」を実行してファームウェアを書き込む。

テープLEDを仮止めして動作チェック

テープLEDのはんだ付け部分がErgo42のはんだ付け部分に接触しないように、マスキングテープなどで覆ってから動作チェックを行う。

まずは左手側のみで動作チェックを行う。

f:id:cnaos:20191230140001j:plain
左手側のみで動作チェック

問題なければ右手側もTRRSケーブルで接続して動作チェックを行う。 右手側だけではテープLEDの動作チェックはできない。

f:id:cnaos:20191231154141j:plain
右手側も接続して動作チェック

Ergo42の基板にカプトンテープを貼ってパターンとスイッチのはんだ付け部分を絶縁

f:id:cnaos:20191230171731j:plain
カプトンテープで絶縁

LEDテープを貼って完成

f:id:cnaos:20191230173743j:plain

環境センサviewerというAndroidアプリを作った

どういうアプリ?

Omronの環境センサ2JCIE-BL01の測定データの読み取り、測定データのグラフ表示、測定データのエクスポートができるアプリです。

環境センサ2JCIE-BL01を使ったデータ観測の例では、環境センサの動作モードをデータ保存なしのビーコンモード(IM/EP)に変更して観測する例が多いのですが、他のアプリとの同時利用も想定してデータ保存ありのモードでの運用ができるようにしました。

play.google.com

できること

  • 環境センサの現在の測定データの読み取り
  • 環境センサ内の過去の測定データの読み出し
  • アプリ内に取り込んだ測定データのグラフ表示(最大二週間まで)
  • アプリ内に取り込んだ測定データのTSVエクスポート
  • 環境センサの測定間隔の変更&内部タイマー設定

f:id:cnaos:20191204230551p:plainf:id:cnaos:20191204230607p:plainf:id:cnaos:20191204230628p:plainf:id:cnaos:20191204230634p:plain
スクリーンショット

作った動機

  • スキルアップ
    • 仕事でAndroidアプリのメンテナンスをしてるけど、機能追加などの開発が乏しく積極的にコストをかけてJetpackの導入やKotlinへの置き換えができないため、新しい技術のスキルが積めない。
  • KotlinでAndroidアプリを1本つくってみたい。
  • 既存アプリへの不満
    • 複数の環境センサーのデータが読めない。
    • データのエクスポートができない。
    • 動作が不安定
    • わざわざアカウントつくらないと使えない
    • 日時設定にタイムゾーン周りのバグがあるらしく、時刻が9時間ずれる。

アプリを作る過程で習得したこと

  • Kotlinをそこそこ使えるようになった
    • Javaと比べていろいろと書きやすい気がする。
      • 匿名クラスまわり
      • いちいちgetter, setterを書かなくていい。
      • mapやlistをリテラルで書ける
    • Kotlinイイね。
    • Kotlin coroutine
      • なんとか使えてるという程度
  • AndroidでBLEデバイスを扱えるようになった
  • Omronの環境センサを扱えるようにった
    • 環境センサから測定データを読み出す
    • 環境センサから読みだしたデータを加工して表示する
    • 環境センサから読みだしたデータをアプリ内DB(Room)に保存する
    • アプリ内DBに保存したデータを利用して測定データの差分読み込みを行う
  • Android Jetpackを扱えるようになった
    • DataBinding
    • LiveData
    • Room
    • Navigation
  • その他
    • グラフ描画ライブラリandroidplotの利用

必要になりそうな新しい技術を、別の実験的なプロジェクトで試してみて、おおよその使い方が分かって行けそうだと思ったらアプリに組み込むという事を繰り返していました。

苦労したところ

測定データの差分取り込み

とくに何も考慮しない、アプリ内の取り込み済みのデータと、環境センサの現在の測定データまでの差分取り込みだけは割と楽に実装できましたが、 環境センサのリングバッファ構造を考慮した差分取り込みのための工夫とか、 環境センサが測定間隔の変更などを行うと最新ページが0にリセットされるので、その後どうやって差分取り込みを行うかとかで2,3回くらい内部の方式を変更しました。

グラフ表示に使ったAndroidplot

サンプルは豊富にあったんですが、日時でグラフを表示する例がなくて試行錯誤が必要でした。 まだ表示に改良の余地があるかなと思います。

Android BLEの133エラー

やっぱりよくわからん。 端末のbluetoothのON/OFF切り替えで直るときもあるし、だめなときはだめだし。

アプリに組み込んだ便利だったライブラリ

  • peko
    • https://github.com/deva666/Peko
    • AndroidPermission用のライブラリ
    • Perrmission関係のコールバックをcoroutineやLiveDataなどに置き換えられる。神
    • 特にViewModel側でPermissionが必要な処理を一旦Activityに戻して処理する必要がある場合に便利。
  • able
  • androidpolot
    • http://androidplot.com/
    • グラフの表示用
    • MPAndroidChartでは精度がfloatしか使えず、今回の用途には不十分だったので。
  • databinding-ktx

つくってみて

ちょっとずつですが、機能が増えていくのが楽しかったです。

XD75Reを組み立てた

f:id:cnaos:20191016213535j:plain
XD75Re

今回のキーボードの構成

組み立て

はんだ付け箇所はなし、スイッチはめてネジ止めするだけのハズだったんですが、ポリカーボネートケースの加工が必要だったのと、使用したステンレスプレートの制限から、PCBをケースにネジ止めした後にスイッチを固定する必要があるなどハマりポイントがありました。

ポリカーボネートケースの加工

XD75Reにはケース側の面にキースイッチ用のソケットとダイオードがついているため、 そのままだと60%のポリカーボネートケースについているネジ止め用の突起が邪魔になって組付けできませんでした。

どこかで買ってきた3本組(平、丸、半丸)で売ってるヤスリを使って、ネジ止め用の突起を削って対応しました。

※PCBのリビジョンや、ケースのモノによっては加工方法が変わるかもしれないので、現物に合わせてください。

加工箇所

  • ネジ止め用の突起を削る 3箇所
  • USBケーブル接続用の口の拡張

f:id:cnaos:20191016213750j:plain
ケースの加工箇所

左上のネジ止め用の突起を削る

赤がMXソケット用に削った部分で、 緑がダイオード用に削った部分です。

f:id:cnaos:20191016214054j:plain

f:id:cnaos:20191016214120j:plain

f:id:cnaos:20191016214134j:plain

真ん中のネジ止め用の突起を削る

ガタつかないようにするには、 ここが一番重要かも。

MXソケットに対応するためにかなり深くまで削ります。

f:id:cnaos:20191016214256j:plainf:id:cnaos:20191016214318j:plainf:id:cnaos:20191016214330j:plainf:id:cnaos:20191016214356j:plain

右上のネジ止め用の突起を削る

ここもMXソケットに対応するために、かなり深くまで削ります。 f:id:cnaos:20191016214507j:plainf:id:cnaos:20191016214520j:plain

USBケーブル接続用の口の拡張

手持ちのケーブルだと根本までちゃんと刺さらなかったので、ヤスリで削って穴を拡張しました。

f:id:cnaos:20190907183836j:plain
削って開口部を大きくしたUSBケーブル接続用の穴

ポリカーボネートケースへの組付け

XD75Re用のステンレスプレートですが、空いているネジ穴が小さすぎて、PCBとポリカーボネートケースを止めるためのネジをステンレスプレートの上から通すことができません。

また、ステンレスプレートに空いている穴を通るような ドライバーも手持ちではありませんでした。

つまり、PCBとステンレスプレート、キースイッチを組み付けた後ではポリカーボネートケースに固定することができません。

先にPCBをポリカーボネートケースにネジで固定したあとで、キースイッチを組み付ける必要がありました。

はんだ付けが必要なタイプのXD75Amだったら詰んでたかも。

f:id:cnaos:20190907184324j:plain
ステンレスプレート

PCとの接続

macとXD75ReをType-C to Type-Cのケーブルで接続しても、電源が入らないみたいでキーボードを認識しませんでした。

Type−C to Type−Aメスの変換ケーブルをかまして Type−C to Type−Aメスの変換ケーブル --> Type-Aオス to Type-Cケーブルという形だと電源が入りました。

kbdfansのkbd75v2では同じType-C to Type-Cケーブルで認識しているので、XD75Reの方の問題だと思います。

解体して確認するのが手間なので確認してないんですが、どうもXD75ReのType-Cコネクタ側にUSBデバイス(Upstream facing port (UFP))として認識させるために必要なプルダウン抵抗が入っていないらしい。

community.cypress.com

キーボードブリッジを作った

Amazonに売ってるクリアーのやつはやたら高いし、 アクリル板1枚だしレーザー加工機で作れそうだなって思ったので作ってみた。

f:id:cnaos:20190915214234j:plain
キーボードブリッジ
f:id:cnaos:20190915175236j:plain
13インチ mac book proに載せたところ

設計

mac book pro 13インチのおおよその寸法を採取

  • 本体の横幅が300mm
  • 本体の上端からキーボードの下端までの縦幅が120mm
  • トラックパッドの横幅が135mm

PFUのを参考にトラックパッドにかからないように適当に下に20mm伸ばして、凹みを作る。

できたデータ

github.com

※見やすいように線幅を広めにしてあります。 レーザー加工機の仕様に合わせて線幅や線の色を調整してください。

切り出しデータの作成ソフトと出力形式

切り出しデータは利用するレーザー加工機に合わせて作る必要があります。

私がよく利用しているFabLab世田谷のレーザー加工機では、Adobe Illustratorで切り出しデータを読み込める形式になっていないといけないため、Adobe Illustratorを使うのがまっとうな方法なのですが、 年に数回程度のちょっとしたレーザー加工のデータを作るのに使うには値段が高すぎるため、Affinity Designerを使って以下のようなフローで加工しています。

  1. Affinity Designerを使ってデータを作成
  2. データをPDFで出力してUSBメモリに保存
  3. FabLabのAdobe IllustratorUSBメモリに保存されたPDFを読み込み
  4. Adobe Illustratorで最終的な調整を行って加工データを保存

これまでの経験から言うと、なんだかんだでPDFが一番安定して読み込めるみたいです。

Inkscapeから出力したPDFでも加工できなくは無いんですが、Inkscape自体の操作がいろいろとつらいのでAffinity Designerを使っています。

テスト印刷

紙に印刷してmac bookの実物に合うか試してみようとして、セブンイレブンネットプリントで出力してみたところ、微妙に縮尺がずれていたり、端っこがかけていたりとあんまり参考にはなりませんでした。

A4ギリギリサイズのデータだったので、余白のあるB4の紙の中央に印刷したらなんとかなったのかも。

素材

  • アクリル板(270x320×3mm ガラスカラー)
  • ゴム足

東急ハンズでアクリル板を買ってきました。

東急ハンズには135x320x3mmの板があったようなので、 トラックパッド用の凹みとか角の加工とか気にしなければこれで間に合うかも。

はざいやさんだと 220x300x3mmのサイズのアクリル板があるけど、 余白がまったくなく加工が難しそうだったので、 今回は使いませんでした。

切り出し

FabLab 世田谷のレーザー加工機を借りて切り出しました。

※機器を利用するには事前に講習を受ける必要があります。

予約を入れて1枠45分 2000円で借りる事ができます。

結果

目論見どおりという感じです。

PFUのヤツとそんなに値段が変わらないけど、 まあガラス色がキレイなので良しとしよう。