google-site-verification: google3bd66dd162ef54c7.html
FC2ブログ

ブレッドボード上の Arduino NANO に0.96インチ OLED を簡単に接続するためのアダプタ

最近 Arduino にI2Cインターフェイスの 0.96インチ OLED を接続したものを作ることが多いのですが、ブレッドボードの配線がコンパクトに出来なくて残念に思っていました。

Arduino NANO
ブレッドボードにArduino UNO と 0.96インチのOLEDを置いた状態です。これだけでブレッドボードのほぼ全面を使ってしまっているので、他の部品を置く場所はほとんどありません。

今回、そういう問題を解決するアダプタを作ったので紹介します。

▼OLEDのピン接続
0.96インチOLEDのピン配置
私が持っているOLEDのピン配置は全部これで、GND, VCC, SCL, SDA の順に並んでいます。なお、I2Cインターフェイスです。

これを Arduino NANO にコンパクトに接続したいのですが、なかなかうまい手がありません。

▼まずはこんな案
ダメな接続
NANOにはA6とA7ピンがあるので、これを出力にアサインしてHIGHとLOWを出力して電源供給をやってしまおうという案です。2ピン無駄になりますが、この二つはUNOには無いピンなのでほとんど使われておらず、大きな問題にはならないはずです。

これはグッドアイディアと思ってやってみたのですが、ダメでした。A6、A7ピンはアナログ入力専用でデジタル出力にはアサイン出来ないようです。つまりこの方法では電源が供給出来ませんでした。

と言うことでズルは出来なかったので、真面目に接続アダプタを作ることにしました。

追記)よく考えると、どうせ使わないアナログ入力ピンなら、ブレッドボードのジャンパーでVCCとGNDを配線しちゃう手がありました。

▼接続アダプタ
Atduino NANO と0.96インチOLED接続アダプタ
Arduino のシールドを作る場合に使うロングピンのピンソケットを加工して作りました。

8ピン用だったのを7ピンに幅を切り詰め。不要なピンを切断して除去し、電源線を配線しました。ブレッドボードには裸のリード線の部品が取り付けられるので、それらとのショートを防止するために被覆線を使った方が良いでしょう。

▼接続アダプタの回路図
アダプタの回路図
電源を本来のピンから持ってくるようにしただけだけです。

▼使っている様子
使用後
OLED を NANOの基板の上に置くことで、まとまった空き地が出来て遊び場が増えました。

別アングル
アダプタをこんなふうに挿して使います。

▼128x32画素のOLEDでも使えます
128x32画素のOLEDでも使えます
ピン配置が同じなのでこんなふうに使えます。

◆まとめ
なかなか使い易いアダプタが出来たと思います。もっと前から作っておくべきでした。唯一の難点はNANOのリセットボタンが押し難くなったことですが、全く押せないわけでは無いので妥協します。

実はもう少し大きなOLEDが使いたくて、1.3インチのOLEDを現在AliExpressに注文出しています。この1.3インチのOLEDのピン配置は0.96インチの物とは違う(電源ピンが逆)ようなのでこのアダプタは使えないようです。残念!

同じ目的で Arduino UNO 用のアダプタも作っています。こっちはもう少し複雑な仕組みになっているのですが、次回の記事で紹介予定です。

Arduino よもやま話-18(未使用ピンをまとめて設定する関数を作った)

◆未使用ピン
Arduinoでは未使用ピンは何もしないで放置しておくのが普通ですが、そうやると少し問題があることが判りました。特に気になるのが電源の消費電流の増加で、何も対策しないと約3mAも消費電流が増えてしまいます。そのあたりの話はよもやま話に書いてきましたが、重要と思われる記事へのリンクを以下に貼っていきます。
Arduino よもやま話-15 (未使用ピンの電圧変化の観察)
Arduino よもやま話-16 (未使用ピンの電圧と電源の消費電流の関係)

◆プログラムからの対策
この問題の対策は、未使用ピンを入力プルアップや出力LOWの状態に設定して電圧を確定してしまえば良く、居酒屋ガレージ日記さんのArduino やっぱり気になる放置ポートという記事で詳しく解説されています。
ここまでやれば完璧ですが、これまで pinMode( )なんちゃらとやって 1ピンずつ設定してきたので、いきなりこの書き方、つまりポート制御レジスタを直接いじる方式に変えるのは大変です。

◆未定義ピンを設定するプログラム
未定義のピンだけ空き端子処理することが出来れば良いので、そこに特化した関数を作ってみました。
// Arduino の空き端子処理関数 20200530uuPinSetup.ino
// uuPinOutputLow, uuPinOutputHigh, uupinInputPullup, uuPinInput
// 2020/05/30:割り込み対策追加 (居酒屋ガレージ日記さんご指摘)*1
// ラジオペンチ

void setup() {
// Serial.begin(115200);
// pinMode(13, OUTPUT);
uuPinOutputLow(0b01111111111100, 0b111111); // 未使用ピンをLOW出力に設定
// uuPinOutputHigh(0b01111111111100, 0b111111); // 未使用ピンをHIGH出力に設定
// uuPinInputPullup(0b01111111111100, 0b111111); // 未使用ピンを入力プルアップに設定
// uuPinInput(0b01111111111100, 0b111111); // 未使用ピンを入力に設定(デフォルトに戻す)
}

void loop() {
}

void uuPinOutputLow(unsigned int d, unsigned int a) { // 指定ピンを出力/LOWに設定(un used Pin set to Output Low)
// ビットパターンで該当ピンを指定(1で有効)。d:D13-D0, a:A5-A0
// PORTx=0, DDRx=1
unsigned int x;
uint8_t oldSREG = SREG; // ステータスレジスタ保存(割込状態保存)*1
cli(); // 割込み禁止*1
x = d & 0x00FF ; PORTD &= ~x; DDRD |= x; // D0-7
x = (d >> 8) & 0x3F; PORTB &= ~x; DDRB |= x; // D8-13
x = a & 0x003F ; PORTC &= ~x; DDRC |= x; // A0-5
SREG = oldSREG; // ステータスレジスタ復元(割込状態復元)*1
}

void uuPinOutputHigh(unsigned int d, unsigned int a) { // 未使用ピンを出力/HIGHに設定(un used Pin set to Output High)
// ビットパターンで該当ピンを指定(1で有効)。d:D13-D0, a:A5-A0
// PORTx=1, DDRx=1
unsigned int x;
uint8_t oldSREG = SREG; // ステータスレジスタ保存(割込状態保存)*1
cli(); // 割込み禁止*1
x = d & 0x00FF ; PORTD |= x; DDRD |= x; // D0-7
x = (d >> 8) & 0x3F; PORTB |= x; DDRB |= x; // D8-13
x = a & 0x003F ; PORTC |= x; DDRC |= x; // A0-5
SREG = oldSREG; // ステータスレジスタ復元(割込状態復元)*1
}

void uuPinInputPullup(unsigned int d, unsigned int a) { // 未使用ピンを入力/PULLUPに設定(un used Pin set to Input Pullup)
// ビットパターンで該当ピンを指定(1で有効)。d:D13-D0, a:A5-A0
// PORTx=1, DDRx=0
unsigned int x;
uint8_t oldSREG = SREG; // ステータスレジスタ保存(割込状態保存)*1
cli(); // 割込み禁止*1
x = d & 0x00FF ; PORTD |= x; DDRD &= ~x; // D0-7
x = (d >> 8) & 0x3F; PORTB |= x; DDRB &= ~x; // D8-13
x = a & 0x003F ; PORTC |= x; DDRC &= ~x; // A0-5
SREG = oldSREG; // ステータスレジスタ復元(割込状態復元)*1
}
void uuPinInput(unsigned int d, unsigned int a) { // 未使用ピンを入力(Hi-Z)に設定(un used Pin set to Input)
// ビットパターンで該当ピンを指定(1で有効)。d:D13-D0, a:A5-A0
// PORTx=0, DDRx=0
unsigned int x;
uint8_t oldSREG = SREG; // ステータスレジスタ保存(割込状態保存)*1
cli(); // 割込み禁止*1
x = d & 0x00FF ; PORTD &= ~x; DDRD &= ~x; // D0-7
x = (d >> 8) & 0x3F; PORTB &= ~x; DDRB &= ~x; // D8-13
x = a & 0x003F ; PORTC &= ~x; DDRC &= ~x; // A0-5
SREG = oldSREG; // ステータスレジスタ復元(割込状態復元)*1
}

居酒屋ガレージ日記さんから、「IOピンのレジスタ操作中は割り込みを禁止した方が良い」とのアドバイスを頂いたので修正しました。
なお旧版はこちら → 0528版(割り込み対策無し版)

つまり、空きピンの処理用に下記の関数を作った訳です。
・出力でLOW     uuPinOutputLow(d, a);
・出力でHIGH     uuPinOutputHigh(d, a);
・入力でプルアップ  uupinInputPullup(d, a);
・入力         uuPinInput(d, a);

空き端子を行いたいピンを引数のビットで指定する方式で、引数の d が D0~D13、引数の a が A0~A5に対応しています。 1 が指定されていればそのポートの空き端子処理を行い、0 だったら、元の設定のままで何もしないという動作を行います。

pinModeの設定が終わったあたりで未使用ピンに対してこの関数を使って空き端子処理を行えばよいと思います。あるいは最初にこの関数で全ピンの空き端子処理を行い、後でpinModeで変更するという手順でもいけると思います。どちらの場合でもグリッジが出る可能性があります。

どの空き端子処理を選択するかは好みに合わせて使えば良いと思いますが、私は居酒屋ガレージ日記さんの作法にならって、LOWを出力、つまり uuPinOutputLow を使っていこうかと思います。なお、入力 (uuPinInput) は無くても良いのですが、コードの対称性が悪くなるので作っておきました。設定を途中でにデフォルトに戻したい場合などで、あると便利かも知れません。

なお、必要なコードだけソースに書けば良く、使っていないコードは削除しても大丈夫です。(書いてあっても使っていなければコンパイラの段階で無かったことになるので悪影響はありません。)

◆効果
上記のプログラムを動かしたときのCPUの消費電流は約11mAでした。一方で、未使用ピンの処理無し、つまり uuPinOutputLow() をコメントアウトした状態の消費電流は 14mA、つまり消費電流を 3mA減らす効果が確認出来ました。
他の関数を使っても消費電流の低減効果は同じでした(デフォルト状態と同じuuPinInput() は除く)

◆電流波形
以上の確認はDMMによる測定と共に、オシロで電流波形も見たものです。オシロの波形で面白い結果が出ているので以下に示します。なお、この波形はCPUの電源ピンに入れた1Ωのシャント抵抗の電圧波形、つまり1mVは1mAに相当しています。

空き端子処理無しの状態
CPU電源電流波形の測定
約14mA流れています。

空き端子処理(OutputLow)ありの場合
出力LOWに設定
消費電流が10.5mAまで下がっています。

再び空き端子処理無しの状態
ACラインノイズの影響
I/Oコネクタに指を近付けると電源電流がACライン波形で変調されました。
空きピンがACラインの影響を受けて電位が変化し、そのために消費電流が変化しているのだと思います。空き端子処理をしていない場合の消費電流の値がフラフラするのが気になっていたのですが、どうもこういう現象が起きていて値が安定しなかったようです。

◆プログラム書き込み電流と同時観察
せっかくなのでCPUのフラッシュメモリーに書き込む様子と合わせて電流波形を観察してみました。

・空き端子処理無しの場合
プログラム書き込み、デフォルト
25mAくらいのスパイク電流がフラッシュに書き込みを行っているタイミングだと思います。その電流が6mAくらいまで減った後で、ユーザープログラムに制御が移り、消費電流14mAの状態で動き始めるのだと思います。小さな周期的な波は、AC電源からの誘導があるためだと思います。

・空き端子処理あり(OUTPUT LOW)
プログラム書き込み、OUTPUT LOW
こちらはユーザープログラムが動き出した後は消費電流が約11mAに減っています。これは前記した話と同じですが、さらにユーザープログラムが起動した後の波形は平坦になっています。これは空き端子処理を行ったためにノイズの影響を受け難くなった効果が表れているのだと思います。

◆まとめ
好みの問題はあるでしょうが、空き端子処理が必要な場合は、今回の記事の関数を使っていきたいと思います。何か問題があったらその時に修正したいと思います。

マイコンはデジタル処理の典型的なデバイスですが、そこにAC電源からの誘導、つまりハムが乗るとは油断が出来ないです。

Arduino NANO にはA6,A7ピンがありますが、この2つのピンにはデジタル入出力機能が無いので初期化は不要なはずです。
カレンダー
04 | 2020/05 | 06
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 - - - - - -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード