質問: Arduinoはプログラムにて、1ピンごとに どのようなピンにするかあらかじめ決めますが、プログラの状況によりプログラムにて入力、出力を決め、切り替えをすることはできないのでしょうか? 例えば、LEDが接続されている時に、 点灯/消灯させる事と点灯しているかどうかを チェックできないか 1ピンで切り替えてできれば少ないピンで対応できます。 よろしくお願いします。
回答: Arduino UNO のマイコンは ATmega328 で、有志によるマニュアルの オレオレ翻訳 中の 18.2 ポート構成図を見るに、また 18.2.4 の解説によると * DD レジスタの設定値によらず PIN レジスタを読むことができて * PIN レジスタはピンの信号をラッチした値を得る ので `pinMode()` で出力にしたピンを `digitalRead()` すると、事前に `digitalWrite()` で出力した値がそのまま読めます(外部回路が電流を取りすぎているなどの回路不良があると異なる値になる可能性は否定できないが、まあレアケースなので無視してよさそう) 入力回路上「ラッチ」が入っているので1クロックの遅延があることに注意とあります。 API 関数呼び出しを経由すれば1クロック以上は必ず経過するので `digitalWrite()` と `digitalRead()` を使っているぶんには気にする必要はありませんが、ポートレジスタの直接アクセスを行う際にはマニュアルにあるサンプル通り `NOP` 等による待ちが必要です。 この手の「ハードウエアによる制約」はどのマイコンでも必ずあるので、いわゆるデバイスドライバを書くプログラマはハードウエアマニュアルの精読が必要です。手を抜くとあとでトラブります。 もうちょっと大規模・高速マイコンとなると (Renesas RX など) 周辺回路レジスタの動作速度は CPU の計算回路の動作速度に対して遅いので「自分が出力した値」を得たいのなら周辺回路から読まずに出力時に RAM 上に記憶しておいてそれを読むほうが高速です。