この記事は、組込みエンジニアを目指してArduinoを学ぶ人のための練習問題シリーズ(全7テーマ+総合演習)の目次です。

ゴールは、温湿度を測って実際のエアコンを赤外線で操作する装置を、自分の手で作り切ることです。要件定義から試験まで通しで進めるので、完成したものはそのまま転職活動で見せられます。

そのために、digitalWrite()で動かして終わりにせず、レジスタ操作までを学習範囲とします。ハードウェアを直接制御することは組込みの中心的な仕事ですが、未経験者向けの学習リストにはまず入っていません。そこが、他の未経験者と差がつく場所です(根拠はなぜレジスタから教えるのか)。

<自己紹介>
筆者は現役の車載組込みソフトエンジニアです。転職前にUno R3と温湿度センサ、赤外線を使った熱中症リスク監視システムを約1か月かけて作り、面接で説明しました。このシリーズは、そのとき必要だった考え方を、未経験者が順番に追える形へ整理したものです。

このシリーズで何が作れるようになるか

このあと出てくる7テーマは、それぞれ単体の練習ではありません。1つの製品を組み上げるための部品として選んでいます。その行き先がArduino総合演習|自動温湿度調整システムです。

何を作るか温湿度を読んで熱中症のリスクを判定し、赤外線で実際のエアコンを操作する装置。人がリモコンを触ったときは人の操作を優先し、室温を設定温度へ寄せていきます。

どう進めるか要件定義書 → 設計書 → 実装 → 試験の順。発注者から渡された要件(R1〜R7)を読むところから始め、要求ごとの試験項目で確かめて終わります。作例を真似る形ではありません。

何に使えるか完成したものは、そのまま転職活動で見せられる成果物になります。私が転職前に作り、面接で説明したのと同じ題材です。

先に総合演習を開いて「何を作るのか」を見てから、この記事へ戻ってくるのも良い進め方です。行き先が分かっていると、各テーマで何を持ち帰ればいいかが決まります。

なぜレジスタから教えるのか

ArduinoのAPIは学び始めるうえで便利です。まずはpinMode()digitalWrite()でLEDを動かし、配線とコードの関係をつかみます。

APIとレジスタは、別々の2つではない

先に誤解を1つ外しておきます。「Arduinoの書き方」と「レジスタの書き方」は、覚えることが2つあるわけではありません。digitalWrite()はC言語の関数で、その中でレジスタに値を書いています。APIを使うことは、誰かが書いたレジスタ操作を呼んでいるのと同じです。

#1で扱うLED(D13)で並べると、対応はこうなります。

Arduinoの書き方 レジスタの書き方 やっていること
pinMode(13, OUTPUT) DDRB |= _BV(DDB5); PB5を出力に切り替える
digitalWrite(13, HIGH) PORTB |= _BV(PORTB5); PB5を1にする(点灯)
digitalWrite(13, LOW) PORTB &= ~_BV(PORTB5); PB5を0にする(消灯)

右の列が読めれば、左の列が何をしていたのかが分かります。逆に右が読めないままだと、思ったとおりに動かないときに確認できる場所がコードの外にありません。本シリーズがAPI版で動きを見る → レジスタ版で中身を確認するという順番にしているのは、この1対1の対応を毎回自分の手で確かめるためです。

レジスタ操作は、組込みの必須スキルなのか

ハードウェアを直接制御することは、組込みエンジニアの中心的な仕事です。ここは求人や企業の説明で確認できます。

  • 組込み開発を手がけるNTTデータMSEは、必要なスキルの筆頭にC/C++を挙げ、その理由を「メモリ効率に優れ、ハードウェアを直接制御できる特性」と説明しています。ハードウェアの基礎知識としてCPUアーキテクチャやメモリマップ、リアルタイムOSの理解として割り込み処理も挙げています。
  • 転職メディアのKOTORA JOURNALも、押さえるべきスキルにマイコンの基本設計と動作原理データシートの活用を挙げています。
  • 実際の求人票を見ると、たとえば業務用インクジェット・3Dプリンタの組込みソフト開発の募集は、必須要件が「組込みソフト(マイコン制御)開発経験」です。

一方で、未経験者向けの学習アドバイスは様子が違います。書かれているのはC言語・C++の基礎、資格、ラズベリーパイでのポートフォリオまでです(マイナビ転職エージェントレバテックキャリアパーソルクロステクノロジーほか)。レジスタ操作やデータシートの読み方は、この一覧に入っていません。

ここに落差がある企業が必要としているのはマイコン制御そのもの。一方、未経験者にすすめられる学習範囲はその手前で止まっている。必須スキルなのに、学習リストに入っていないという状態です。

未経験の側に開発経験が無いのは当たり前で、それは入社しないと手に入りません。代わりに示せるのは「実務でやることを、自分の手でやった」という事実だけです。そのためこのシリーズは、digitalWrite()で動かして終わりにせず、レジスタ操作までを学習範囲とします

同じアドバイスを受けた人の中で、データシートを開いてレジスタを書いた人は多くないはずだ——私はそう考えて、転職前にレジスタ操作までを学習範囲としました。実際に手を動かしたのはArduinoでのレジスタ設定とBoot下回りで、そこで身についた見方が、入社後にマイコンの設定を理解する助けになっています。総合演習で作る成果物は、そのとき面接で説明したものと同じ題材です。

毎日レジスタを書くわけではない。それでも差がつく理由

正直に書くと、実務でゼロからレジスタを書き起こす場面ばかりではありません。ドライバや自動生成されたコードが用意されていることも多く、その上で作る仕事のほうが量としては多くなります。

差が出るのは、思ったとおりに動かないときです。自分のプログラムしか見られない人は、コードを何度も読み返すところで止まります。レジスタが読める人は、「そもそも、このビットは1になっているのか」を実際に確かめられます組込みの技術コラムが、レジスタを「設定を変更したり、状態を確認したりする」ものだと説明しているとおりで、状態を確認する手段を持っているかどうかの違いです。

特にタイマは、この差が出やすい場所です。delay()は待っているあいだ他の処理を止めるため、複数の仕事を同時に進める必要がある組込みソフトでは使いどころを選びます。車載でも10msや100msといった周期で処理を回すことが多く、時間をどう作っているかを説明できることが求められます。

全7テーマと、進む順番

ここからが本編の入口です。7テーマの中身と、進む順番をまとめます。

以下の7テーマは、総合課題を作るために必要なものだけを選びました。番号順に進めると、最後の総合課題がそのまま組み上がります。

# テーマ 学べること/総合課題での役割 記事
1 Lチカとデジタル出力 digitalWrite()で動かしたあと、DDRBPORTBでLEDを操作する。総合では状態や異常を知らせるLEDになる 記事を読む
2 シリアルで見る シリアルモニタで値と状態を確認する。発展ではUARTのボーレート分周も見る。総合では温湿度・制御状態のデバッグに使う 記事を読む
3 タイマと実行周期 プリスケーラ、カウンタ、比較一致、タイマ割り込みで周期タスクを作る。総合では測定と制御の周期そのものになる 記事を読む
4 DHT11をライブラリなしで読む パルス幅を測り、40ビットをパースしてチェックサムを確認する。総合では温湿度の入力を担う 記事を読む
5 赤外線リモコンを解析して送る パルス幅から信号を読み、タイマで38kHzキャリアを作って送信する。総合ではエアコンの操作を担う 記事を読む
6 電源が切れても状態を失わない設計 EEPROMへ状態や異常の記録を残し、あとから原因を解析できるようにする。総合では設定値の保存と異常記録になる 記事を読む
7 低消費電力で動かす設計 スリープと割り込みで、必要なときだけマイコンを起こす。総合では電池での長時間動作を意識した周期設計につながる 記事を読む

迷ったら1から7へ順番に

迷ったら、1から7まで順番に進めてください。特に#3のタイマと実行周期は、あとの4テーマすべてで使います。DHT11のタイミング測定も、赤外線の送受信も、低消費電力での定期的な起床も、#3で作る仕組みの上に乗ります。

  1. #1 Lチカで、出力ポートとビット操作に慣れる
  2. #2 シリアルで、動いている中身を確認する手段を持つ
  3. #3 タイマと実行周期で、delay()に頼らない時間管理を作る
  4. #4 DHT11で、データシートを読みながらセンサの信号を解釈する
  5. #5 赤外線で、家電の信号を解析し、外部へ出力する
  6. #6 EEPROM保存#7 低消費電力で、止まり方・電源断まで考える
  7. 総合課題で、要件定義、設計、実装、試験を1つにつなげる

総合課題は、C言語 総合実力テストのエアコン模擬プログラムを実機にする位置付けです。紙の上で考えた条件分岐、配列、関数、ビット演算を、温湿度センサと赤外線LEDを使って本物の入出力へつなぎます。

各記事の進め方

このシリーズは、各テーマを講義形式の解説+練習問題7問+回答例で進めます。コードを読むだけでなく、まず自分で書き、実行結果を確かめてから回答を開いてください。

  • 番号順に進める。後のテーマでは、前のテーマで扱ったビット演算やタイマを使います。
  • まずArduino APIで最短の動きを作り、次に同じ動作をレジスタで書き直す
  • 各記事の「データシートのこの部分を読む」を開き、設定値の根拠を一次資料で確認する。
  • 問題を解いたあとに、完成品のどの部品になるかを確認する。

前提として、C言語 基礎ドリル変数if文ループ関数ポインタビット演算を終えていることをおすすめします。特にビット演算は、レジスタの一部だけを変更するときにそのまま使います。

始める前にそろえるもの

やることが決まったら、部材をそろえます。7テーマ全部を通しても、追加で買うものは多くありません。

本シリーズはArduino Uno R3(ATmega328P搭載)を前提にします。Uno R3はATmega328Pを搭載したボードで、内蔵EEPROM、タイマ、GPIOを使って学習できます。Uno R4など別のマイコンを搭載したボードでは、レジスタ名も設定方法も変わるため、このシリーズのコードをそのまま使うことはできません。Arduino公式のUno R3仕様も、最初に確認してください。まだボードを持っていない方は、Arduinoは結局どれを買う?初心者へのおすすめと主要ボード比較で、なぜR3系が学習に向くか・どのスターターキットを選べばいいかを確認してからそろえると失敗しません。

用途 必要なもの 使うテーマ
最初の出力確認 Uno R3系、LED、抵抗、USBケーブル #1
温湿度の入力 DHT11、ジャンパ線 #4、総合
赤外線の解析・送信 IR受信モジュール、赤外線LED、抵抗、ジャンパ線 #5、総合
保存・省電力 追加部材は原則不要。内蔵EEPROMとスリープだけで完結する #6、#7、総合

開発環境は、初心者ならArduino IDE、実務に近い環境へ進みたいならVS Code+PlatformIOを選べます。どちらから始めるか迷う場合は、先にArduino開発環境の選び方を読んでください。

導入手順はそれぞれ別の記事にまとめています。Arduino IDEはダウンロード〜インストール完全ガイド、PlatformIOはVS Code+PlatformIOで作るArduino開発環境です。

データシートは全部読まない|必要な章だけを見つける

レジスタを扱うときに最初につまずくのが、データシートです。私も、分周の計算方法、割り込みハンドラの設定、そもそもの割り込みの概念で手が止まりました。ページ数が多い資料を最初から読む必要はありません。今やりたい動作に必要な章だけを、決まった順番で読むようにします。

先に「やりたい動作」を1文で決める

データシートを開く前に、「LEDを13番ピンで点灯したい」「1msごとに処理を呼びたい」のように、やりたい動作を1文で決めます。その動作が決まると、調べる対象はポート、タイマ、割り込みなどに絞れます。

Uno R3で使うATmega328Pの一次資料は、MicrochipのATmega328Pデータシートです。記事ごとに、読む章と表を抜粋して示します。

レジスタ設定は、この5つの順で追う

  1. ブロック図と端子機能を見て、目的の機能がどのポート・周辺回路につながるかを確認する
  2. レジスタの概要で、設定に必要なレジスタ名を拾う
  3. 各ビットの説明で、0と1が何を意味するかを確認する
  4. 初期化手順と注意事項を読み、設定する順番や禁止条件を確認する
  5. タイミング図・電気的特性で、センサ信号や時間の条件を確認する

例えばタイマなら、「どのタイマを使うか」→「クロック源とプリスケーラ」→「比較値」→「割り込み許可」→「割り込み関数」の順です。分周比や比較値を暗記するのではなく、どのビットがその設定を持っているかをデータシートでたどります。

#6では、Uno R3のATmega328Pで電源断後に残せる内蔵領域であるEEPROMを扱います。このシリーズでは、当時「DF保存」と呼んでいた要件を、Uno R3ではEEPROMへ状態を保存する設計として扱います。保存する内容、書き込むタイミング、書込み回数の抑え方まで考えます。

よくある質問(FAQ)

C言語を全部終えてから始めるべきですか?

最低限、変数、if文、ループ、関数、ポインタ、ビット演算は確認してから始めることをおすすめします。とくにビット演算は、レジスタの特定のビットだけを変更する場面で使います。C言語に不安がある場合は、C言語 基礎ドリルから進めてください。

Uno R4でも学べますか?

このシリーズはUno R3(ATmega328P)専用です。R4ではマイコンとレジスタ体系が異なるため、同じコードを写してもレジスタ操作の学習にはなりません。Uno R3またはATmega328P搭載のR3互換ボードを用意してください。

ライブラリを使わないと、初心者には難しすぎませんか?

最初から全部を自力で書くのではなく、まずArduino APIで動きを確認します。その後で、どの設定をAPIが肩代わりしているのかをレジスタで確かめます。シリアル出力はデバッグの道具として使い、発展では#2 シリアルのドリルでUARTレジスタ(ボーレートの分周)まで確認します。

まとめ|動いた理由まで説明できるようにする

  • Arduinoドリルは、レジスタ、タイマ、実行周期を扱う全7テーマ+総合課題で進める
  • 最初はAPIで動かし、その後に同じ動作をレジスタで書き直す
  • #3のタイマと実行周期を最初に作り、その上にセンサ、赤外線、保存、省電力を乗せる
  • データシートは最初から読破せず、目的の機能に必要な章を順番に確認する

このシリーズでは、単にLEDを光らせるところで終わらず、温湿度を読み、家電を動かし、電源断まで考えた成果物を作ります。まずは#1のLチカから、実機で1ビットを動かすところを確認してください。

次に読む