技術記事の一覧
Article / 名刺基板(2)

電池なしで光る名刺基板を作る(2)届いた基板に書き込んで光らせるまで

電池を持たず、スマホをかざすと LED が光る名刺を、電子回路の板(基板)で作っています。今回は、工場から届いた基板に小さなコンピュータ(マイコン)のプログラムと、スマホで開くページの URL を書き込みました。Android ではかざしている間光り続けましたが、iPhone では何も光りませんでした。その原因を探して iPhone でも一瞬光るように直し、光り方を 9 種類に増やすまでの記録です。

読む時間 12 分山本 雄斗
この記事の要点

企画から発注までは (1)企画から発注まで に書きました。今回はその続きです。

届いた名刺基板の表面。外周に金色のアンテナと 20 個の LED、中央にロゴ・URL・名前・キャラクター・QR コード、左側にマイコンや NFC チップなどの部品

表

届いた名刺基板の裏面。ロゴ、キャッチコピー、URL、出典表記と、右上に書き込み用の 3 つのパッド

裏

届いた実物です。(1)の図は、設計データから描いた絵でした。

01届いた基板

2026 年 9 月 18 日に発注した 30 枚が、10 月 1 日に届きました。

(1)で「刷った実物で読めるかは(2)で確かめます」と書いた QR コードは、実物でもスマホで読めました。工場の審査で指摘を受けたアンテナ微調整用のコンデンサ(C1)は、0402 サイズ(1.0×0.5 mm)の部品(C1552)への変更が反映されたと、9 月 21 日に JLCPCB(基板を作った中国のメーカー)から回答をもらっていました。実物でも、すぐ下にある同じ 0402 サイズのコンデンサ(C2)と同じ大きさの部品が載っていました。30 枚のうち、届いた時点で見た目でわかる不良はなく、書き込みでつまずいた基板もありませんでした。

ただ、届いたあとの 10 月 5 日に、片付けの途中で束を落とし、何枚かの LED を割ってしまいました。紙の名刺と違って表面がつるつる滑るので、重ねて手で持つのには向きません。

届いた基板には、電源の LED の横にあった稲妻マークが入っていません。シルク(表面の印刷)を差し替えたときに、意図せず消していました。残す範囲の境目を、図形の中心がわずか 0.05 mm 越えていたためです。気づいたのは発注のあと、9 月 30 日に設計データを公開する前の見直しのときでした。

技術メモ:消えた稲妻マーク
表面の左上の拡大。上下に LED、中央に黒い NFC チップ、その上と下に小さなコンデンサ
表面の左上の拡大。中央の黒い部品が NFC チップで、その上が C1、下が C2 です(どちらも 0402 サイズ、1.0×0.5 mm)。上下の LED は 1.6×0.8 mm です。

02マイコンへの書き込み:3 つのパッドと 3.3V

書き込み:プログラム(ファームウェア)をマイコンに入れる作業。UPDI:このマイコンに書き込むための、線 1 本の入口。裏面に GND・VCC・UPDI の 3 つの金属の点(パッド)がある。アダプタ:パソコンの USB と UPDI をつなぐ小さな変換器。

マイコンは、裏面の 3 つのパッドをクリップではさんで、アダプタとつなぎます。マイコンは電気を節約するため 1 MHz という低めの速さで動かしていて、書き込むプログラムもその速さを前提にしています。

大事なのは、アダプタの電源を 3.3V にすることです。同じ基板に載っている NFC のチップ(スマホと通信する部品)は、電源の上限が 3.6V です。アダプタによくある 5V のまま当てると、このチップの上限を超えるので、基板でいちばん弱い部品に合わせました。

30 枚に同じ作業をくり返すので、手順は「基板をクリップではさむ → Enter キーを押す → 成功か失敗かを色で見る」だけで済むようにしました。書き込みのあとには、書いた中身を読み出して照合(ベリファイ)します。製造の現場でいう、治具(作業を正確にくり返すための専用の道具)と作業手順書を小さく作ったようなものです。パソコンの画面には次のように出ます。

基板をはさんで Enter(q で終了):
✔ 成功(この回 1 枚目) LED が回るのを確かめて外してください

基板をはさんで Enter(q で終了):
✘ 失敗 ピンの当たりを確かめて、もう一度 Enter
(中略)
成功: N 枚

成功は緑、失敗は赤で表示し、どちらのときもベルが鳴るので、画面を見ていなくても終わったことが分かります。最後に、その回に成功した枚数を表示します。

アダプタは、スイッチサイエンスの「USB シリアル UPDI 変換アダプタ(FTDI)」(税込 1,760 円)を使いました。電源の出力を 5V と 3.3V で切り替えられるので、3.3V にしています。クリップは、2.54 mm 間隔・4 ピンの、ばねで伸び縮みするピン(ポゴピン)が付いたもの(Amazon で購入時 1,054 円)で、4 本のうち 3 本を使います。洗濯ばさみのような形で上下の両方にピンが付いていますが、表側のピンは LED に当たるので外し、裏面のパッドにだけ当たるようにしました。

1 枚の書き込みは約 3 秒、照合は 0.3 秒ほどです。1 枚目で動作を確かめたあと、翌日、光り方を仕上げた版(firmware-2)を 30 枚すべてに書き込みました。途中で一度、書き込み用のスクリプト(手順を自動で進めるプログラム)が止まりましたが、立ち上げ直して最後まで終えています。書き込みを成功させるには、基板をクリップでしっかり固定することが大事だと分かりました。

技術メモ:書き込みの道具と設定
裏返した名刺基板の右上をオレンジ色のクリップではさみ、ジャンパー線で赤いアダプタにつないで、USB でパソコンに接続している
裏面の右上の 3 つのパッドをクリップではさみ、奥の赤いアダプタ(USB でパソコンにつながる)から書き込みます。

03かざしてみる:iPhone は光らず、Android は光った

NFC:Suica やスマホ決済と同じ、かざして通信する仕組み。NFC チップ:かざしたスマホに渡す URL などを覚えておく部品。

10 月 1 日の夜、プログラムを書き込んだ 1 枚目に、まず iPhone 17 をかざしました。何も光りません。NXP(NFC チップのメーカー)の書き込みアプリ「NFC TagWriter」で読み取ると、「No NDEF records available」(読み取れるデータがない)と出ました。NFC チップの中は、まだ空のままでした。

次に、手元の古い Android で NFC をオンにしてかざしました。すると、かざしている間、外周の赤い LED が光り続けました。電池を持たない基板が、スマホの電波だけで光った瞬間です。このとき書き込んでいたのは、元の作者のプログラムをほぼそのまま使った版(違いは、黄色の LED で光らせるモールス信号の文字列だけ。06 章で書きます)で、赤の光り方は、尾を引いた光が外周を回る元の「彗星」1 種類でした。

(1)で「この基板でうまく動くかは(2)で確かめる」と書いた電源まわりの工夫も、元の設計のままで動きました。LED を光らせるための電気をためる部品(10µF のコンデンサ)を、最初は抵抗を通してゆっくりため、約 0.3 秒後に電子スイッチで抵抗を迂回する仕組みです。今回確かめたのは「光り続けた」ところまでで、電流は測っていません。

Android で光ったので、基板と電源まわりは動いています。iPhone で光らない理由は、別にありそうです。チップへの URL の書き込みは、次の章で書きます。

Android スマホの背面に名刺基板を重ねると、外周の赤い LED が光っている
Android の背面に重ねると、外周の赤い LED が光ります(写真は、06 章の firmware-2 を書いたあとに撮ったものです)。

04NFC への書き込み:工場出荷のままでは書けなかった

初期化:使い始める前に、チップの中を決まった形に整えること。

かざしたスマホに開いてもらうページの URL を、NFC チップに書き込みます。最初は、同じ NFC TagWriter で書こうとしました。

ところが、iPhone からは書き込めず、Android の同じアプリでもうまく書けないことがありました。調べると、このチップは工場から出荷された時点で初期化されておらず、データを書く場所の「目次」にあたる部分が空のままでした。

そこで、Android で動く NXP の「NTAG I2C Demoboard」というアプリを使い、Config の「Reset tag」で初期化してから書きました。初期化したあとは、iPhone の NFC TagWriter でも書けました。リポジトリの書き込み手順も、この形に書き換えています。

教訓:部品の「出荷時の状態」を、使う前に確かめる。新品のチップがそのまま使えるとは限りません。今回は初期化の手順を 1 つ足すだけで書けるようになりました。
技術メモ:NFC チップの初期化

NFC には、かざした人だけが開く名刺ページの URL だけを書きました。このページは検索には出さず、HP からもリンクしていません。「名刺にスマホをかざしてくださって、ありがとうございます。」で始まり、「連絡先に追加」と「フォームで相談する」の 2 つのボタンを置きました。「連絡先に追加」から、名前・肩書・サイトと SNS の URL などを、スマホの連絡先に登録できます。URL と連絡先(vCard)の両方を NFC に入れる案も試しましたが、アプリでうまくいかなかったので、連絡先はこのページから渡す形にしました。

(1)の 09 章で、名刺を配る前に、かざして開くページに公開場所へのリンクを置くと書いた件も、このページで済ませました。書き込んだプログラムのソースの置き場所(github.com/chofu-lab/nfc-card)へのリンクと、名刺をお渡ししてから少なくとも 3 年間はどなたでも無料で入手できるようにしておくこと、ライセンス表示のページへのリンクを載せています。配る基板に入っているのは、firmware-2 という版のプログラムです。

iPhone で開いた名刺ページ。「名刺にスマホをかざしてくださって、ありがとうございます。」の見出し、名前と肩書、「連絡先に追加」と「フォームで相談する」のボタン
かざすと開く名刺ページ(iPhone)。

050.1 秒のうちに光らせる

URL を書いたあと、iPhone をホーム画面のまま(アプリを使わずに)かざすと、URL を開く通知は出るようになりました。ところが、LED は相変わらず何も光りません。

試した iPhone 17 では、ホーム画面での読み取りのとき、電波が約 0.1 秒で切れました。一方、元のプログラムは、起動してから 0.3 秒待ち、そこから 0.3 秒かけて LED を明るくする作りでした。光り始める前に、電気が来なくなっていたのです。

確かめるため、iPhone のアプリ「NFC Tools」で、チップからの読み出し(READ)を 2,500 回続けて送りました。すると約 14 秒の間、iPhone でも光り続けました。光らない原因は、電波が出ている時間の短さだと分かりました。

技術メモ:iPhone で読み出しを続ける

そこで、マイコンが起動した直後に、黄色の LED を半分の明るさで点けるようにしました。これで iPhone でも、ホーム画面のままかざすと、黄色の LED が一瞬光ります。

代わりに、最初の 0.3 秒にも黄色の LED に電流が流れるようになりました。赤の演出と、突入電流(電源を入れた瞬間に流れ込む大きな電流)の対策は元のままです。この直しは、次の章以降の変更と一緒に firmware-2 に入っています。

教訓:電池のない機器は、相手がいちばん短く電気をくれる時間のうちに、最初の反応を返す。データシートだけでは、スマホごとの読み取り方の違いは分かりません。今回は 0.3 秒と 0.1 秒の差でした。
0.1 秒の内側 iPhone の電波 黄 LED(元の版) 黄 LED(新しい版) コンデンサに電気をためる 電子スイッチ オン 赤のフェードイン 0.3 秒からフェードイン 0 秒から半分の明るさ 0 0.1 0.2 0.3 0.4 0.5 0.6 秒
起動から 0.6 秒までの流れ。元の版(薄い黄色)では、iPhone の電波が出ている 0.1 秒の内側に、光るものが何もありませんでした。
技術メモ:起動の流れ(firmware-2)
時刻起きること
t=0analogWrite(powerLedPin, 127)(PWM 約 50%)で黄 LED を点ける
0〜0.3 秒delay(300)。C3(10µF)を R3(2.2kΩ)経由で充電する
0.3 秒P-ch MOSFET の Q1 をオンにして R3 を迂回する(元と同じ)
0.3〜0.6 秒1 フレームを 13.5 ms から 6 ms へ縮めて、赤をフェードインする
約 0.6 秒〜黄 LED を 0.5 秒で消し、彗星が回り始める

出典:software/nfc_card.ino(firmware-2 の 93〜147 行)、docs/CHANGES.md(2026-10-01)。元の版は 0.3 秒の待ちのあと、黄 LED を 0.3 秒かけてフェードインしていた。

直したあと(firmware-2)の、スマホによる反応の違いをまとめます。試したのは iPhone 17 と古い Android の 2 台です。

AndroidiPhone 17(ホーム画面のまま)
電波が出ている時間かざしている間約 0.1 秒
かざしたとき外周の赤い LED が 9 種類のパターンで光り続ける黄色の LED が一瞬光り、名刺ページを開く通知が出る
iPhone のホーム画面の上に出た通知。「Web サイト NFC タグ」「chofu-lab.com を Safari で開く」
iPhone 17 をホーム画面のままかざしたときの通知。タップすると名刺ページが開きます。

06光り方を 9 種類に

元のプログラムの光り方は、03 章で書いた「彗星」1 種類でした。これを 9 種類に増やしました。1 種類を 6 秒ずつ、1 巡 54 秒でくり返します。

名前見え方
彗星尾を引いた光が 2 周する
双子の彗星反対側にもう 1 つの彗星
スピナー4 つの点が回る
すれ違い2 つの点が逆向きに回り、4 回すれ違う
交互点灯300 ms ごとに半分ずつ入れ替わる
満ちて引く3 秒で全部点き、同じ順に消える
積み上げ速い点が終点に積もっていく
きらめきばらばらに明滅する
チャージ5.2 秒かけて明るくなり、最後に 2 回点滅する

赤の光り方として、ほかに心拍・呼吸・ルーレット・衝突・流れ星なども試しましたが、残したのは上の 9 種類です。心拍は、全部の LED を点けて明るさを変えると、なめらかに変わらず、段差のようにカクカクと変わって見えたので外しました。

黄色の LED の役割も変えました。元のプログラムには、黄色の LED で作者のサイト名をモールス信号で光らせる、小さな遊びが入っていました。03 章で触れたとおり、10 月 1 日に一度、その文字列を当社の CHOFU-LAB.COM に変えましたが、翌日の firmware-2 では、このモールス信号と、起動時の演出のあとに 10 秒間ゆっくり明るくなったり暗くなったりする動きを、両方やめました。

今の黄色の LED は「パターンが変わる合図」です。パターンが切り替わるたびに光り、0.5 秒で消えます。チャージの最後の点滅では、赤と一緒に光ります。

9 種類の光り方(約 60 秒、音なし)。1 種類 6 秒で、1 巡は 54 秒です。
技術メモ:9 パターンの数値

07速くしたら明るくなりすぎる:6 ms の決まりを守る

チャーリープレクス:5 本のピンで 20 個の LED を光らせる配線の工夫。ある瞬間に光っているのは 1 個だけ。フレーム:20 個を 1 巡して描く 1 回分。スリープ:マイコンが計算を止めて休み、電気を節約する状態。

その 1:1 個ずつ順に光らせている

外周の 20 個の LED は、同時には光っていません。1 個ずつ、ごく短い時間だけ順に光らせ、それを速くくり返すことで、目には全部が光っているように見せています。そのため、LED の明るさは「1 フレームのうち、点いている時間の割合」で決まります。点いている時間が同じなら、フレームが短いほど明るくなります。

その 2:元の 1 フレームが約 6 ms だった理由

元のプログラムでは、1 フレームが約 6 ms でした。中身を見ると、LED ごとに割り算(20 で割った余り)を計算していて、これに時間がかかっていました。このマイコンには割り算の命令がなく、割り算をするたびに、たくさんの手順を踏む必要があるからです。1 フレームの大半は、光らせることではなく計算に使われていました。

その 3:割り算をなくすと 3 倍明るい → 6 ms に固定して休ませる

パターンを増やすにあたって、割り算を比較と引き算に置き換え、パターンの計算も 25 ms ごとにまとめました。すると 1 フレームが約 3 分の 1 に縮みます。点いている時間は同じなので、点灯の割合が約 3 倍になり、LED の明るさも、赤い LED に流れる平均の電流も約 3 倍になってしまいます(計算上の見込み)。

そこで、タイマーで 6 ms ごとに 1 回だけ描くことにしました。彗星を描くのにかかるのは約 1.3 ms で、残りの時間は、次の 6 ms の区切りまでマイコンをスリープさせます(20 個全部が点くパターンでは描く時間が延び、休む時間はそのぶん短くなります)。これで、LED 1 個あたりの明るさと電流は、元とほぼ同じになりました。実物でも、20 個全部が点くパターンの 1 個あたりの明るさは、ほかのパターンと同じに見えます。

元 割り算なし firmware-2 計算(割り算など) スリープ(残り) 描画(彗星で約 1.3 ms) 036 ms LED が点いている時間
1 フレームの中身の模式図(長さは目安)。赤が LED の点いている時間です。割り算をなくすと同じ 6 ms の中で約 3 回描くことになり、点灯の割合が約 3 倍になります。2 段目の 1 回分の長さは模式的です(描く時間はパターンによって変わります)。firmware-2 は 6 ms に 1 回だけ描き、残りを休みます(3 段目は彗星の場合)。

その 4:電流はどうなったか

基板全体の平均電流は、約 0.69 mA から約 0.52 mA に下がる見込みです(細かい動作を計算でなぞったシミュレーションによる推定)。理由は 2 つで、マイコンがフレームの残りの時間を休むようになったことと、黄色の LED がふだん消えていることです。

一方、赤の LED は点いている数が増えるパターンがあるので、赤の合計電流は平均で元の約 1.2 倍、20 個全部が点くパターンの間は平均で約 3 倍になります(どちらも推定)。

教訓:処理を速くしたら、副作用として何が増えるかを先に数える。明るさや電流のように「時間の割合」で決まる量も変わります。今回は描く間隔を元と同じ 6 ms に固定し、増えた時間を休む時間に回しました。

ついでに見つけた、元からの小さな不具合

プログラムを読んでいて、起動時のフェードの最後に、まれに約 65 ms、外周の赤い LED が消えたままになる箇所を見つけました。時計を 2 回読んでいて、その間に時刻がちょうど 0.3 秒の区切りをまたぐと、マイナスになるはずの待ち時間が、とても大きな数として扱われる作りでした。時計を 1 回だけ読むように直しています。コードを読んで見つけたもので、実機でどのくらいの頻度で起きるかは確かめていません。

技術メモ:割り算をなくした 1 行と、6 ms ごとに眠る仕組み

LED ごとの % 20 を、比較と引き算に置き換えた(元の 173 行 → firmware-2 の 270 行)。

// 元: LED ごとに割り算(AVR には割り算命令がない)
uint8_t dist = (headIdx - i + 20) % 20;
// 新: 比較と引き算だけ
uint8_t d1 = head >= i ? head - i : head + 20 - i;

6 ms ごとに起きて描画し、あとは眠る(firmware-2 の 196〜207 行)。

void waitFrame() {
  cli();
  while (!frameDue) {
    sleep_enable();
    sei();
    sleep_cpu();
    sleep_disable();
    cli();
  }
  frameDue = false;
  sei();
}

1.3 ms は起動時の彗星 1 回分の描画時間(firmware-2 のコードのコメントの値)、「約 3 倍」「約 1.2 倍」「約 0.69 mA → 約 0.52 mA」は docs/CHANGES.md にあるサイクル単位のシミュレーションによる推定値です。電流の値はシミュレーションによる推定です。

技術メモ:65 ms 消灯の原因

元のコード(元の 98〜105 行の一部)。

while (millis() - startupStart < 300) {
  uint32_t elapsed = millis() - startupStart;
  uint16_t blankingDelay = (300 - elapsed) * 25;
  ...
  if (blankingDelay > 0) delayMicroseconds(blankingDelay);

08確定した費用

(1)では、届いたときに消費税と通関の手数料がかかるので、確定額は(2)で書くとしていました。

内訳(30 枚)金額
基板58.06 ドル
部品の実装(部品代を含む)104.86 ドル
送料9.82 ドル
追加(治具費など)25.63 ドル
小計(JLCPCB への支払い。カード明細で 32,143 円)198.37 ドル
関税0 円
輸入消費税(地方消費税を含む)2,900 円
通関手数料0 円
合計(小計+関税+輸入消費税+通関手数料)35,043 円

上の 5 行(小計まで)は(1)の表と同じです。届いたときにかかったのは輸入消費税の 2,900 円だけで、関税と通関手数料はかかりませんでした。小計の円額は、9 月 18 日と 21 日の 2 回に分けて払った分(27,952 円と 4,191 円)の、カード明細の合計です。

このほかに、書き込みの道具として、アダプタ 1,760 円とクリップ 1,054 円の合わせて 2,814 円がかかりました(どちらも購入時の税込価格で、送料は別)。何度でも使える道具なので、名刺 1 枚あたりの費用には入れていません。

1 枚あたりは約 1,168 円になりました((1)の時点の見込みは約 1,050 円)。見込みより高くなった分の大半は、輸入消費税(1 枚あたり約 97 円)です。

09届いた基板を配る前のチェックリスト

今回の経験から、電池のない NFC の基板を書き込んで配るまでに確かめることをまとめました。

10この経験が役立つご相談

今回やったことは、仕事の場面に置き換えると、次のようなご相談に役立ちます。

電子機器の試作や、ファームウェアの読み解き・改良のご相談は、お問い合わせからどうぞ。

← 技術記事の一覧へ

この基板は WiHarper/nfc_card(CERN-OHL-S v2 / GPL-3.0)をもとにしています。名刺に書き込んだファームウェア(firmware-2)は GPL-3.0-or-later で、megaTinyCore(LGPL 2.1)と AVR-LibC(修正 BSD)の一部を含みます(表示は THIRD_PARTY_NOTICES.md)。変更後の設計データとソースは github.com/chofu-lab/nfc-card にあります。作業には arduino-cli と、AI の Claude Code を使いました。前回は (1)。