直接USBに接続できる格安Arduino互換機をゼロから自作してみた話

# 概要
最近、秋月電子通商で面白そうな格安マイコンを探していたらWCH製のCH552が目に留まりました。1個100円くらいですが、USBを内蔵し、Arduino開発環境からも扱えるようです。興味が湧いたので試しにCH552Tを搭載した格安Arduino互換機を考えてみました。USBメモリ程度のサイズですが、そこそこピン数も多く、意外と使い勝手は悪くないように思います。結果的には1個300円くらいで作ることができました。何らかの参考になれば幸いです。
![picture.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/2aa41a5f-35e8-2cce-5103-6d9bd6c41997.jpeg)
# 開発環境
* Windows 11 Home 23H2
* KiCad 6.0.9
* Arduino IDE 1.8.19
* CH55xDuino 0.0.20
# CH552
まず、CH552に関して説明します。CH552EやCH552Gなど、数種類の中から用途に応じて選べますが、今回はピン数が20本と多く、秋月電子通商より購入できるCH552Tを選んでみました。ピン配置は以下の通りです。注意点としてはRSTピンが珍しく正論理です。そのため、プルダウン抵抗器が内蔵されています。他はプルアップ抵抗器がデフォルトで働くみたいです。
![pinout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/5f1087ca-a50a-dca0-0fb7-db695906232d.png)
特徴としてはUSBを内蔵しているため、USBシリアル変換IC等の書き込み装置を省き、部品数を減らすことができます。UART、SPI、PWM、ADCの他にタッチセンサ機能も搭載するなど、真面に使えそうです。しかし、書き換え回数が200回くらいなので使い道は限られているように感じました。

:::note info
データシートより抜粋しました。
https://akizukidenshi.com/goodsaffix/CH552.pdf
:::
# 設計
プリント基板の設計はKiCadを使用して行いました。
# 部品表
全て秋月電子通商より購入しました。チップ抵抗器は1608M、チップコンデンサは2012M、チップLEDは1005Mのサイズです。また、USB-C端子は手実装が難しそうなのでUSB-A端子を選びました。
| 参照番号 | 型番 | 販売コード | 単価 | 数量 | 合価 |
|:-:|:-:|:-:|:-:|:-:|:-:|
| U1 | CH552T | 118026 | 110円 | 5個 | 550円 |
| D1 | OSG80402C1C | 111720 | 7円 | 5個 | 35円 |
| SW1 | TVAF06-A020B-R | 114888 | 22円 | 5個 | 110円 |
| R1 | RC0603J10K | 115029 | 0.196円 | 5個 | 0.98円 |
| R2 | RC0603J1K | 114122 | 0.196円 | 5個 | 0.98円 |
| C1, C2 | GRM40-034B104K50 | 111384 | 2.5円 | 10個 | 25円 |
| J1, J2 | PHA-1x10SG | 104396 | 10円 | 10個 | 100円 |
| J3 | USB-4AM103AS | 102236 | 50円 | 5個 | 250円 |

なお、数量は5枚のプリント基板を発注する想定で決めました。
## 回路図
ほとんど外付け部品が不要なので非常にシンプルです。注意点としてはバイパスコンデンサの付け方でした。CH552の電源電圧は3.3Vから5Vなので直接USBから給電できますが、電源電圧が3.6V以上の場合、V33ピンにバイパスコンデンサを接続しないと正しく動作できないようです。もちろん、VCCピンにバイパスコンデンサを接続することは必須です。少し余談ですが、電源電圧が3.6V未満の場合、V33ピンはVCCピンに接続しておく必要があります。
![schematic.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/6f9ab7aa-899a-5cb5-ce15-f9274577356f.jpeg)
詳しい書き込み方法は後述しますが、CH552はP3.6ピンがHレベルの状態でリセットするとDFUモードで起動し、書き込み可能な状態となります。ただし、このP3.6ピンやP3.7ピンの電圧レベルは3.3Vです。ちょうどV33ピンは内臓レギュレータによって3.3Vを維持するため、ここに動作モード切り替え用スイッチを付けました。
## フットプリントの割り当て
KiCadの場合、手実装用と機械実装用で2種類のフットプリントが用意されている部品も存在します。前者は後者に比べてランドのサイズが大きく、手実装しやすいため、なるべく今回は前者を選びました。フットプリントが用意されていない部品については既存のフットプリントを編集することで対応しました。
## レイアウト
プリント基板は2層で設計しました。まずは表面です。右端がタッチセンサ用の電極、左端にUSB-A端子が載ります。また、後述するように今回はプリント基板の製造をJLCPCBに依頼しましたが、その場合は`JLCJLCJLCJLC`とシルクを入れることで製造番号が印刷される位置を自由に指定できます。今回はUSB-A端子と重なるように配置し、完成したら見えなくなるように隠してみました。
![rendering_front.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/1fb684bf-cb4c-d0e3-1510-c3e4ce725a14.png)
次に裏面です。CH552の全ピンを引き出してあります。ピン名のシルクも入れました。
![rendering_back.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/cd0521dd-db37-8944-e675-0edcd7115453.png)
ガーバーファイルは[**こちら**](https://drive.google.com/file/d/1Xf_rRVqudq_Ur75PmZN5ZBoRCsk-BabB/view?usp=sharing)からダウンロードできます。
# 製造
プリント基板の製造はJLCPCBに依頼しました。
## 発注
基本的にガーバーファイルをアップロードするだけです。レジストの色は変えてみましたが、他の項目はデフォルトのままで構いません。なお、予めKiCadに専用のプラグインを導入しておけばJLCPCBの形式に合わせたガーバーファイルを簡単に出力できるため、非常に便利です。[**こちら**](https://nararoboconproject.wordpress.com/2023/06/27/i/)が参考になりました。
## 到着
配送業者は送料が最も安い`OCS NEP`を選びました。納期は10日間くらいです。乾燥剤と共に梱包された状態で届きました。
![package.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/054e6781-592a-7004-a2ef-4d5c5c8ad3a5.jpeg)
## 修正
しかし、プリント基板にUSB-A端子が干渉し、すんなり実装できませんでした。少し削れば対応できそうでしたが、そこそこプリント基板の製造費も安いため、その外形線だけ修正し、再発注することに決めました。
# 実装
今回は費用を少しでも抑えるため、全部品を手実装します。部品数は少ないので慎重に進めていけば問題ありません。チップ抵抗器やチップLEDは拡大鏡で確認しながら実装しました。
![size.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/43fe8c5a-b377-261e-96ba-e69ccce83624.jpeg)
なお、全体的なサイズが伝わりやすいようにUSBメモリと並べて撮影してみました。
# 動作確認
最後に正しく動作することを検証します。
## Arduino開発環境
CH552をArduino開発環境で扱うため、少し準備が必要です。まずはボードを追加します。

:::note info
以下のURLを貼り付け、インストールすることで導入できます。
https://raw.githubusercontent.com/DeqingSun/ch55xduino/ch55xduino/package_ch55xduino_mcs51_index.json
:::

ボードの種類は`CH552 Board`を選択します。他の項目はデフォルトのままで構いません。普段はUSB経由でシリアル通信する場合が多いので`Default CDC`を選択しますが、CH552のHID機能を利用する場合は通信用にRAMを確保するため、この項目は`USER CODE w/ 148B USB ram`などに変更する必要があります。
![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/55d9879e-7511-cff5-f4fa-3f3cdf5e26a0.png)
## 書き込み方法
CH552は動作モード切り替え用スイッチを押しながらUSBに接続するとDFUモードで起動し、書き込み可能な状態となります。初回は必ずDFUモードで起動します。なお、COMポートは現れません。また、数秒後に解除されてしまうみたいなのでUSBに接続するタイミングも重要です。ここで`Default CDC`を選択していた場合、それ以降はCOMポートが現れて普通に書き込めます。動作モード切り替え用スイッチを操作する必要がなくなるので楽です。
## プログラム
まずはP1.5ピンに接続されたLEDの点滅から試してみました。CH552はピン名の付け方がAVRマイコン等とは異なるようで1桁目がポート番号、2桁目がピン番号です。つまり、P1.5ピンなら15と指定します。
```cpp:blink.ino
#define LED_BUILTIN 15 //P1.5


void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
}
```
このプログラムを少し変更し、タッチセンサ機能も試してみました。電極に触れている間だけLEDが点灯し、その状態がシリアルモニタに表示されます。ただし、シリアル通信には専用の関数`USBSerial_print`や`USBSerial_println`を使う必要がありました。普段の関数と使い方は同じです。
```cpp:touch_sensor.ino
#include <TouchKey.h>

#define LED_BUILTIN 15 //P1.5


void setup() {
  pinMode(LED_BUILTIN, OUTPUT);

  TouchKey_begin(1 << 2); //enable TIN2 on P1.4
}

void loop() {
  TouchKey_Process();

  uint8_t result = TouchKey_Get();
  if (result & (1 << 2)) {
    USBSerial_println("Touched");
    digitalWrite(LED_BUILTIN, HIGH);
  } else {
    USBSerial_println("Released");
    digitalWrite(LED_BUILTIN, LOW);
  }
  delay(10);
}
```
意外と感度は高いように感じました。より小さな電極でも十分に反応しそうです。
# 総括
プリント基板は送料も含めて合計460円、部品は合計1071.96円なので1個306.392円と非常に安価なArduino互換機を自作できました。個人的には大満足です。ただし、実際にはプリント基板を修正するために再発注したので最終的な費用は少し異なります。それでもプリント基板の製造費は十分に安いので助かりました。これから気楽に活用していくつもりです。また、今回は試していませんが、なんとCH552はHID機能も備えているため、USBキーボード等も機会があれば自作してみたいです。