Arduino~Basis of Design Recap
前回はArduinoの入出力に関する基礎編でしたが、今回は空燃比、回転数、および負圧を同時に計測・記録するプログラムを実際に組んでみて気づいたこと、注意点等の実用編をお届けします。備忘録になりますがよろしくお願いします。
ポートレジスタ
冒頭から難しい話題になりますが、回転数を計測するには避けて通れない要件です。
”レジスタ”とはマイコン内部の記憶装置のことで、一般のメモリに比べて記憶領域は小さいが、データにアクセスするスピードは格段に早い。そのため、回転数の計測など1μs単位のとても短い時間を扱う必要がある場合や複数のピンを同時にセットしたい場合などには直接レジスタへのアクセスする方が処理上優位となる。
こちらからの引用です。
Arduinoの入出力に関わるI/Oレジスタには3つの入出力ポートが用意されている。
-
ポートB
-
ポートC
-
ポートD
其々のポートは3つのレジスタによって制御される。DDRレジスタはピンが”INPUT”なのか、”OUTPUT”なのかを決定する。PORTレジスタはピンが”HIGH”なのか、”LOW”なのかを制御する。PINレジスタはpinMode()により入力に設定された入力ピンの状態を読み取る。DDRレジスタとPORTレジスタは双方とも読み書き可能である。一方、PINレジスタは読み取り専用の入力レジスタで、全てのピンのデジタル入力を同時に読み取ることができる点で秀でている。なお、各レジスタはArduino言語の変数としても定義されている。
PORTB | ||||||||
ビット | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
ピン | – | – | D13 | D12 | D11 | D10 | D9 | D8 |
PORTC | ||||||||
ビット | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
ピン | – | – | A5 | A4 | A3 | A2 | A1 | A0 |
PORTD | ||||||||
ビット | 7 | 6 | 5 | 2 | 4 | 3 | 1 | 0 |
ピン | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
ポート並びに各々のレジスタのルールと役割は以下のようになっている。
-
PORTDはArduinoのデジタルピンの0番から7番に対応している。
-
DDRD:ポートDデータ転送方向レジスタ。各ビットはポートDの各ピンが入力と出力のどちらに使用されるかを決定する。
-
PORTD:ポートDデータレジスタ。読み込み/書き出し
-
PIND:ポートD入力ピンレジスタ。読み込み専用
-
PORTBはArduinoのデジタルピンの8番から13番に対応している。2つの上位ビット(6と7)は水晶ピンに対応しているので利用できない。
-
DDRB:ポートBデータ転送方向レジスタ。各ビットはポートBの各ピンが入力と出力のどちらに使用されるかを決定する。
-
PORTB:ポートBデータレジスタ。読み込み/書き出し
-
PINB:ポートB入力ピンレジスタ。読み込み専用
-
PORTCはArduinoのアナログピンの0番から5番に対応している。
-
DDRC:ポートCデータ転送方向レジスタ。読み込み/書き出し
-
PORTC:ポートCデータレジスタ。各ビットはポートCの各ピンが入力と出力のどちらに使用されるかを決定する。
-
PINC:ポートC入力ピンレジスタ。読み込み専用
上記のように、PORTDレジスタはArduinoのデジタルピンの0番から7番と広範囲に制御していることがわかる。ただ、注意が必要なのは、Arduinoの0番ピンと1番ピンはシリアル通信にも使用されているため受信や送信の機能が無効になることである。
実際、LCDへの表示とSD Cardへの書き換えを同時に行う時に0番と1番を使った為、LCDに表示できず大分悩んだ苦い経験があるので、RXとTX(ピン0番と1番)は触らずにピン2~7番を使用しています。また、あくまでもスピードを重視する処理をプログラミングではデジタルピンを幅広く扱えるポートDを利用する予定です。
ビットチェック
直接レジスタの値を読み取ることができる為、高速化手法の一つです。
- bit_is_set():第1引数の第2引数ビット目が1かどうかチェックします。
- bit_is_clear():第1引数の第2引数ビット目が0(1でない)かどうかチェックします。
(顛末)回転数のプログラミングでは精々1万回転以下で低回転数の計測を目的としている為、結局これら高速手法は必要ありませんでした。
外部入力による割り込み
割り込み((interruption)とは、例えば外部のスイッチが押される度に予め設定しておいた関数を呼び出すための仕組みです。Arduino言語ではsetup()で初期値を設定したら、loop()に実行したいプログラムを書きます。そのプログラムによってArduinoボードの動きをコントロールします。loopという名前の通り、この部分は繰り返し実行されます。 これが「本業」の処理フローとなります。割り込み処理を設定しておくと、スイッチやタイマからのキッカケによって、「本業」の処理フローを一時中断して、予め設定しておいた「副業」関数を呼び出し、それが終了すると「本業」の処理フロー(一時中断した箇所)に戻ります。
割り込みのトリガーとしては入力モードに設定した 2番ピンあるいは 3番ピンの電圧変化を使います。2番ピンは割り込み番号0、3番ピンは割り込み番号1に対応し、其々の独立した割り込み処理に利用できます。
-
void attachInterrupt (intId, func, cond);
-
intId:割り込み番号0(2番ピン使用)、1(3番ピン使用)
-
func:呼び出される関数名
-
cond:割り込み条件LOW、CHANGE、RISING、FALLINGの何れ
-
返値:なし
-
機能:割り込みを有効にする。
入力ピンの電圧がLOW(オフのあいだ)、CHANGE(変化したとき)、RISING(オフからオンに上がったとき)、FALLING(オンからオフに下がったとき)にfuncを名前とする関数が呼び出される。割り込み入力ピンはあらかじめ入力モードに設定しておく。
-
void detachInterrupt (intId);
-
intId:割り込み番号0(2番ピン使用)、1(3番ピン使用)
-
返値:なし
-
機能:割り込み番号intIdの割り込みを無効にします。
使用上の注意事項として、一部繰り返しとなりますが、
- 2番ピンは割り込み番号0、3番ピンは割り込み番号1を使う。
- 割り込み関数の内部から書き換える大域変数にはvolatile というキーワードをつけるように心がける。参照するとき割り当てられた RAM の内容を確実に読み出す事が出来る。
- int型データは16bit(−32768~32767)、long(= long int)型データは32bit (−2147483648~2147483647)で表現される。プログラム中の定数は基本的に int 型として扱われるが,例えば“600000UL”のように”L”を加えることでlong 型の定数とすることができる。
回転数計測アルゴリズムでは本手法を利用しました。
入出力
一部前回の繰り返しになります事、ご了承ください。
Arduino Unoのアナログ出力はPWMによる疑似的なアナログ出力です。このため、アナログ出力(PWM出力)はデジタル入出力ピンを利用します。Unoのデジタル入出力ピンは14本(PWM出力できるのはこのうち6本)、アナログ入力ピンは6本付いている。因みに、Dueではアナログ出力ピンが2本付いており物のアナログ出力を行うことができます。
また、Unoにはシリアル通信が1チャンネルしか無い為(Dueは3チャンネル)、ソフトウエアによってI/Oポートを動かしてシリアル通信するライブラリも存在します。これをソフトウエアシリアルと呼びます。
arduinoの0番~13番ピンの14本のピンはデジタル入出力端子として割り当てられていますが、デジタル0番~13番はデフォルトでデジタル入力ピンに設定されています。アナログ入力ピンとして割り当てられているアナログ0番~5番も其々デジタル14番~19番として使用することが可能です。14番~19番はデフォルトでアナログ入力ピンに設定されているので、アナログ入力端子をデジタルモードで使う場合や、先のデジタル入力ピンを出力ピンに切り替えて使う場合、下記のようにピンモードを切り替えることで行います。
-
void pinMode (pin, mode);
-
pin:ピン番号 2~13(0~13)、A0~A5。PC と通信しないスタンドアロン動作時は0〜13 に広げることができる。また、アナログ入力ピン A0~A5 についてもこの関数で動作モードを設定することでデジタル入出力ピンとして利用できる。
-
mode:入力モード”INPUT”か、出力モード”OUTPUT”のどちらかを指定。
その他の留意事項
-
アナログ入力analogRead()
アナログ信号をデジタル値に変換するには凡そ0.1ms掛る。
-
デジタル入出力端子の電気特性
入力端子に掛けられる電圧は、(GND-0.5v)~(Vcc+0.5v)の範囲内に入っている必要がある。この範囲を外れるとラッチアップを起こし破損してしまう恐れがある。
以上を心すれば回転数、負圧、空燃比計測プログラムは作成できると思います!?。
今回は写真もなく寂しい内容となりましたが、こちらのサイトに大変参考になりました。改めてこの場を借りて厚くお礼申し上げます。