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

0.96インチ 128x64ドット OLEDディスプレイ

 Arduinoで使うキャラクタ表示の液晶のストックが無くなりそうなので、0.96インチで128x64ドットのOLEDディスプレイをAlEexpressから購入しました。

 注文したのが12月の初め頃だったのですが、なんと正月の年賀状と一緒に届きました。注文から受け取りまで24日掛かりましたが、送料最安コースなのでこんなもんでしょう。

▼0.96インチOLED  (左のユニットは画面保護用のシールを剥がしています)
0.96インチOLED
 1個 $1.99を2個買い、送料込みで$4.14でした。安いのでもっと多く買いたかったのですが、3個目から送料が急に上がったので2個にしておきました。ちなみに、少し送料を増やせばデリバリーが早くなるようです。なお買ったのは白色表示の物で、インナーフェイスはI2Cです。
 
 AliExpress のページはこちら→new original 4pin 0.96" White/Blue/Yellow blue 0.96 inch OLED 128X64 OLED Display Module for arduino 0.96" IIC I2C Communicate

 このモジュールで気になったのは電源電圧です。調べると3.3Vから5Vまで使えることになっていました。秋月のサイトに同じような物がありますが、そちらも電源電圧は3.3-5.0Vになっています。こういう場合、以下のようなケースが考えられます。

 1) 電源電圧は3.3Vから5VまでOK。(例えば、ATmega328)
 2) 電源電圧は3.3から5VまでOK。入力は5Vトレラントなので、電源電圧3.3Vで使っていても 5V入力が可能。
 3) 仕様上の電源電圧は3.3Vだけど、5Vでも動く。但し保証外。

 1)なら安心なのですが、コントローラーチップのSSD1306のデーターシートを読むと電源電圧は3.3Vとなっています。5Vは絶対最大定格すら超えているので、そんなに高い電圧かけてはいけません。

 まさか3)のように危ない物では無いと思いますが、中華マーケットにはこういう危ない部品を見かけることがあります。

 ともかく、このあたりの疑問をすっきりさせるために、インターフェイス基板の中身がどうなっているか調べてみました。

▼インターフェイス基板 (表示面の裏側です)
OLEDのインターフェイス基板(I2C)
 上の4ピンのピンヘッダがインターフェイスコネクタで、下側の30ピンのフレキを経由してSSD1306のチップに接続されています。

▼回路図 (図をクリックで別窓に拡大図)
0.96インチOLED基板回路図
 フレキ側のピンの信号名は、Webで調べた情報を元に記入しているので、多少間違っているところがあるかも知れません。

 この回路図で疑問点は全て解決しました。電源はU2の三端子レギュレーターを通して供給されていました。つまり、OLEDモジュールに供給される電源電圧は3.3Vで、入力に3.3V以上が供給された場合は3端子レギュレーターで降圧される仕掛けになっていました。事前に三つのケースを想定していたのですが、結果はそのどれでもなく、部品コストを掛けた真面目な対応が行われていました。

 I2Cのプルアップ抵抗はこの基板で作った3.3Vに接続されています。つまりI2Cバスの電圧は3.3Vになります。そんなことで、外部に5V電源から垂らしたプルアップ抵抗を入れてはいけません。なお、Arduino側が5V電源だったとしても、I2Cのピンはオープンドレイン出力なので、そのままて(アマチュアが使うなら)大丈夫です。

 自分用のメモを兼ねてこの回路の説明をしておきます。

 BS0-1などの制御ピンに加える電圧の組み合わせで、SPIやパラレルなどの各種インタフェイス方式の選択を行っています。C4, C3 はチャージポンプのバケツ。C2, C1 は3.3V電源のデカップリング。R10, D1, C9 はパワーオンリセット回路。R6, R7 は I2Cバスのプルアップ、R5 はセル電流設定、C6, C5 は表示セル駆動電圧のデカップリング用だと思います。

▼動作テスト
0.96インチOLEDデモ画面
 Adafruit のデモプログラムを動かしている様子です。

▼特性測定中
OLEDの特性測定
 せっかくなので波形や消費電流を見てみました。

 電源の消費電流は最大で約15mAで、表示するセルが減るとその分少なくなって、最小では1mA以下にはなるようです。なお、デモプログラムを走らせたままで測定したので、最低がどれくらいまで減るかは今回は調べていません。

▼I2Cの波形
SSD1306 I2C波形
 上がデーター(SDA)で、下がクロック(SCL)です。

 振幅は3.3Vになっていて、クロックのポジエッジでデーターを読んでいる感じの波形です。クロックレートは約400kHzです。なお、以前測定したハードウエアSPIインターフェイスの液晶は4MHzでした。

◆まとめ
 0.96インチは小さいと思ったのですが、OLEDなのでコントラストが非常に高くて見易いです。今後何か作る時にぜひ組み込んでみたいです。あと、同程度の解像度で横長の 128x32の物も売られているのでこっちも欲しくなりました。

 今回、このOLEDを表示させるためのライブラリはAdafluit のものを使いました。他にU8gのライブラリが使える、というかこっちの方が有名のようです。ただ、U8gライブラリははプログラムの書き方が独特(firstPageで開始し、whileを使ってnextPageで終了待ち)なので、出来れば使いたくないです。(私が良さに気付いていないだけかも知れません)

 あと、このドライバチップの名前はSSD1306ですが、この1306という数字を見ると2SC1306を思い出します。同じ気持ちになる人が日本中探すと僅かにいるはずなので、そのあたりの話はまた記事にしたいと思います。

LOLシールドを使った LEDアレイプロジェクターの製作

 なんだか大げさなタイトルですが、実は大したことやってません。

 以前Arduino の LOLシールドを作ったのですが、高輝度のLEDを使ったので直視できないほどの光量があります。この光をレンズで投影すれば、プロジェクターが作れそうだなーと思っていたので、やってみました。

 先に完成品の写真です。

▼LEDアレイプロジェクタ
自作のLEDプロジェクタ
 名前は立派なのに貧乏臭い外観ですみません。手っ取り早く段ボール箱で作りました。大きなレンズから緑の光が出ているのが謎めいていて、かっこいいです。

▼内部
LEDプロジェクタ内部
 ArduinoとLOLシールドが入っています。パーツの固定には緑の養生テープを使っています。

LEDプロジェクタ内部、レンズは虫メガネ
 レンズは虫メガネで、このレンズは口径62mm、倍率2倍の物。焦点距離を測ってみると約125mmでした。プロジェクターと言うからには、フォーカシング機構を付けたいところですが、面倒なので約2m先にピントが合う位置で固定しています。

▼投影している様子
投影している様子
 これは投影距離 80cmの状態で、投影サイズは40cm×21cmになりました。単色光なので一枚レンズでも比較的シャープに結像しています。

 距離を増やせば投影サイズはもっと大きくなりますが、その分暗くなります。投影距離によりますが、昼間の部屋の明るさだと苦しくて、少し暗くする必要があります。

◆動画  (?rel=0)

 マトリックスが 9x14 と粗いので表現力はイマイチですが、動画が表示出来るので面白いです。イベントなどで使うと目立つと思います。それに何しろ安く作れます。

 ここまでは小学生の工作レベルですが、実はプログラムにちょっと手を入れています。

▼文字の反転
 LOLライブラリを使って表示させているのですが、そのままでは裏文字になってしまいます。ということで、何らかの方法で表示をひっくり返さないといけません。やり方はいろいろありそうですが、判り易い方法ということで、ライブラリのcherliplexing.cpp の下記の部分を修正しました。

const LEDPosition PROGMEM ledMap[126] = {
/*
// Normal (for direct LED view)
L(13, 5), L(13, 6), L(13, 7), L(13, 8), L(13, 9), L(13,10), L(13,11), L(13,12), L(13, 4), L( 4,13), L(13, 3), L( 3,13), L(13, 2), L( 2,13),
L(12, 5), L(12, 6), L(12, 7), L(12, 8), L(12, 9), L(12,10), L(12,11), L(12,13), L(12, 4), L( 4,12), L(12, 3), L( 3,12), L(12, 2), L( 2,12),
L(11, 5), L(11, 6), L(11, 7), L(11, 8), L(11, 9), L(11,10), L(11,12), L(11,13), L(11, 4), L( 4,11), L(11, 3), L( 3,11), L(11, 2), L( 2,11),
L(10, 5), L(10, 6), L(10, 7), L(10, 8), L(10, 9), L(10,11), L(10,12), L(10,13), L(10, 4), L( 4,10), L(10, 3), L( 3,10), L(10, 2), L( 2,10),
L( 9, 5), L( 9, 6), L( 9, 7), L( 9, 8), L( 9,10), L( 9,11), L( 9,12), L( 9,13), L( 9, 4), L( 4, 9), L( 9, 3), L( 3, 9), L( 9, 2), L( 2, 9),
L( 8, 5), L( 8, 6), L( 8, 7), L( 8, 9), L( 8,10), L( 8,11), L( 8,12), L( 8,13), L( 8, 4), L( 4, 8), L( 8, 3), L( 3, 8), L( 8, 2), L( 2, 8),
L( 7, 5), L( 7, 6), L( 7, 8), L( 7, 9), L( 7,10), L( 7,11), L( 7,12), L( 7,13), L( 7, 4), L( 4, 7), L( 7, 3), L( 3, 7), L( 7, 2), L( 2, 7),
L( 6, 5), L( 6, 7), L( 6, 8), L( 6, 9), L( 6,10), L( 6,11), L( 6,12), L( 6,13), L( 6, 4), L( 4, 6), L( 6, 3), L( 3, 6), L( 6, 2), L( 2, 6),
L( 5, 6), L( 5, 7), L( 5, 8), L( 5, 9), L( 5,10), L( 5,11), L( 5,12), L( 5,13), L( 5, 4), L( 4, 5), L( 5, 3), L( 3, 5), L( 5, 2), L( 2, 5),
*/
// Swap UP Down (for Lenz projection)
L( 5, 6), L( 5, 7), L( 5, 8), L( 5, 9), L( 5,10), L( 5,11), L( 5,12), L( 5,13), L( 5, 4), L( 4, 5), L( 5, 3), L( 3, 5), L( 5, 2), L( 2, 5),
L( 6, 5), L( 6, 7), L( 6, 8), L( 6, 9), L( 6,10), L( 6,11), L( 6,12), L( 6,13), L( 6, 4), L( 4, 6), L( 6, 3), L( 3, 6), L( 6, 2), L( 2, 6),
L( 7, 5), L( 7, 6), L( 7, 8), L( 7, 9), L( 7,10), L( 7,11), L( 7,12), L( 7,13), L( 7, 4), L( 4, 7), L( 7, 3), L( 3, 7), L( 7, 2), L( 2, 7),
L( 8, 5), L( 8, 6), L( 8, 7), L( 8, 9), L( 8,10), L( 8,11), L( 8,12), L( 8,13), L( 8, 4), L( 4, 8), L( 8, 3), L( 3, 8), L( 8, 2), L( 2, 8),
L( 9, 5), L( 9, 6), L( 9, 7), L( 9, 8), L( 9,10), L( 9,11), L( 9,12), L( 9,13), L( 9, 4), L( 4, 9), L( 9, 3), L( 3, 9), L( 9, 2), L( 2, 9),
L(10, 5), L(10, 6), L(10, 7), L(10, 8), L(10, 9), L(10,11), L(10,12), L(10,13), L(10, 4), L( 4,10), L(10, 3), L( 3,10), L(10, 2), L( 2,10),
L(11, 5), L(11, 6), L(11, 7), L(11, 8), L(11, 9), L(11,10), L(11,12), L(11,13), L(11, 4), L( 4,11), L(11, 3), L( 3,11), L(11, 2), L( 2,11),
L(12, 5), L(12, 6), L(12, 7), L(12, 8), L(12, 9), L(12,10), L(12,11), L(12,13), L(12, 4), L( 4,12), L(12, 3), L( 3,12), L(12, 2), L( 2,12),
L(13, 5), L(13, 6), L(13, 7), L(13, 8), L(13, 9), L(13,10), L(13,11), L(13,12), L(13, 4), L( 4,13), L(13, 3), L( 3,13), L(13, 2), L( 2,13),

/*
// Rotate 180 degree
L( 2, 5), L( 5, 2), L( 3, 5), L( 5, 3), L( 4, 5), L( 5, 4), L( 5,13), L( 5,12), L( 5,11), L( 5,10), L( 5, 9), L( 5, 8), L( 5, 7), L( 5, 6),
L( 2, 6), L( 6, 2), L( 3, 6), L( 6, 3), L( 4, 6), L( 6, 4), L( 6,13), L( 6,12), L( 6,11), L( 6,10), L( 6, 9), L( 6, 8), L( 6, 7), L( 6, 5),
L( 2, 7), L( 7, 2), L( 3, 7), L( 7, 3), L( 4, 7), L( 7, 4), L( 7,13), L( 7,12), L( 7,11), L( 7,10), L( 7, 9), L( 7, 8), L( 7, 6), L( 7, 5),
L( 2, 8), L( 8, 2), L( 3, 8), L( 8, 3), L( 4, 8), L( 8, 4), L( 8,13), L( 8,12), L( 8,11), L( 8,10), L( 8, 9), L( 8, 7), L( 8, 6), L( 8, 5),
L( 2, 9), L( 9, 2), L( 3, 9), L( 9, 3), L( 4, 9), L( 9, 4), L( 9,13), L( 9,12), L( 9,11), L( 9,10), L( 9, 8), L( 9, 7), L( 9, 6), L( 9, 5),
L( 2,10), L(10, 2), L( 3,10), L(10, 3), L( 4,10), L(10, 4), L(10,13), L(10,12), L(10,11), L(10, 9), L(10, 8), L(10, 7), L(10, 6), L(10, 5),
L( 2,11), L(11, 2), L( 3,11), L(11, 3), L( 4,11), L(11, 4), L(11,13), L(11,12), L(11,10), L(11, 9), L(11, 8), L(11, 7), L(11, 6), L(11, 5),
L( 2,12), L(12, 2), L( 3,12), L(12, 3), L( 4,12), L(12, 4), L(12,13), L(12,11), L(12,10), L(12, 9), L(12, 8), L(12, 7), L(12, 6), L(12, 5),
L( 2,13), L(13, 2), L( 3,13), L(13, 3), L( 4,13), L(13, 4), L(13,12), L(13,11), L(13,10), L(13, 9), L(13, 8), L(13, 7), L(13, 6), L(13, 5),
*/
};

 このテーブルでLEDの1番から126番までのLEDが、ピンマトリックスのどの位置に接続されているかが定義されています。つまり、この定義を変えれば裏文字に変更することが出来ます。

 Normal (for direct LED view) がオリジナルの状態で、Swap UP Down (for Lenz projection) がプロジェクターで使う場合(この記事の状態)、Rotate 180 degree は点対称の状態で、何かの時に使えるかも知れません。簡単に変更出来るようにするために、使わない定義はコメントアウトして外しておきました。

▼ピンとLEDの関係
LOLシールドのLEDアサイン表
 LOLシールドのIOピンとLEDの接続については先人の方が書かれた記事が大変参考になります。ikkeiさんの記事にある回路図が判り易いのですが、私なりに作ってみたのが上の表です。なお、表の中の数字がLED番号を表します。

 12ピンの総当たりは12x11=132の組み合わせがあり、そこにLOLシールドの14x9=126個のLEDを置くわけですが、その対応関係は上の表のようになっています。黄色で塗った部分は綺麗な直交配置になっており、その外側の水色の部分では、対称な位置を番号が行ったり来たりするようにアサインされています。表の右下の空白は使われていない部分です。

◆まとめ
 手で持てる箱から光が出て、文字や図形が表示されるのは凄く不思議な感じがします。これ、5Vで0.12Aくらいしか電流を消費しないので、USBモバイルバッテリーで長時間動かすことが出来るはずです。

 LOLのライブラリには、この記事の動画に出て来たもの以外に、テトリスやピンポンゲームなどいろいろなものがあるので、試してみると面白いと思います。

 レンズのサイズが小さいので、現状ではLEDから出た光の一部しか使えていません。もっと口径の大きなレンズを使えば投影する画像を明るく出来るはずなので、適当なレンズを探してみたいと思います。

Arduino用LOLシールドキット、動作テスト編

 前の記事で作ったLOLシールドを動かしてみます。また、少し波形を見てどういう動作になっているか調べて見たいと思います。

 ところで、動かす前にLOLシールドについて、前の記事で書ききれなかったことを先に説明しておきます。LOLシールドは9x14のマトリックスになっていて、合計126個のLEDがあります。端子は12ピンあり、これをチャーリープレクシングで動かすと、点灯可能なLEDの数は最大で12x11=132個です。つまり6個余るのですが、これはどこかで飛ばして配線してしまえばいいので、めでたくLOLシールドの出来上がりということになります。

 なお、チャーリープレクシングの配線の基本は12x12のマトリクスなのに、LOLシールドのLEDの配置は14x9になっていて、この違いは配線方法で吸収する必要があります。ということで、LOLシールドの基板パターンはちょっとややこしいことになっています。

 さて、実際に動かしてみますが、そのためにはGitHubにあるLOLシールドのライブラリを使いました。LOLシールドのライブラリを登録すると、IDEのプログラム例に下記のような LoLshield-master という項目が出来て、そこにサンプルプログラムが沢山入っています。

▼LoLsheild-master のメニュー
LOLのEXAMPLE
 いろいろなサンプルプログラムが入っており、入力デバイスが必要な一部のプログラムを除き、ほとんどがそのまま動くので、LOLシールドの動作テストにもってこいです。

▼全点灯
全点灯デモ
 写真では一部が消灯していますが、見た目には全点灯になっています。

 左上のLED(LED1)の端子電圧を観察したのが次の波形です。

▼全点灯時のLED端子電圧波形
駆動波形、全点灯
 中央がGNDレベルで、±2.8Vくらいのパルス電圧が掛かっています。パルスのタイミングでLEDは発光していて、その時間は約1.2ms、周期は約13msというところです。なお、負側も同じ波形で駆動されています。つまり、点灯のデューティは1/12になっているようです。

 一般的なチャーリープレクシングでは、点灯のデューティーはLEDの数の逆数になります。つまりLOLシールドは126個のLEDがあるので、デューティは1/126なりそうです。しかし一本のラインに繋がっているLEDをまとめて点灯させてしまえば、駆動デューティをもっと改善出来る、つまりもっと明るく表示出来る、ということみたいです。

 なお、ちょっと判らないのは、ラインが12本あるとして、一本ずつ正負に固定して残りのピンで情報を表現すると、デューティーは1/24になりそうですが、これが1/12で済んでいるのは謎です。まあ私の頭が悪いのが原因なんですが。

 ここで注意が必要なのはこの波形はLEDを全点灯させている状態なので、複数のLEDが同時に光っています。一つのLEDだけが光っている状態を知りたいので、もう少しやってみます。

▼DNAデモの時のLED1の電圧波形
駆動波形
 複雑な波形が表示されますが、LED1だけが光っている(状態に近い)時の波形です。

 途中にいろいろな波形が入っていますが、LEDの点灯電圧は3.6Vに上がっています。これがポート間で一つのLEDを光らせている状態だと思います。

 この3.6Vという値はポートに加わっている負荷の重さを表していて、結構重要な値なのでもう少し検討してみます。

 電源電圧は5Vなのでポートの電圧降下は1.4Vということになります。ここでちょっと乱暴ですが、正負両方のポートで案分して負担していると考えると、片側のポートで0.7Vのドロップ(上昇)があることになります。Atmega328PのデーターシートのIOピンの駆動能力のグラフにはこの半分程度のドロップ電圧のデーターまでしか記載されていませんが、外挿で推定すると40mAくらいは流れていそうです。ちなみに同じLEDに安定化電源で3.6Vを加えてみると、流れた電流は42mAだったので、話はほぼ一致しています。

 なお、ATmega328Pの絶対最大定格で、IOピン毎の最大電流は40mAなので、この状態はギリギリな感じです。また、デューティが低いと言っても、同じタイムスロットで複数のLEDを点灯させることもあるので、たぶんスペック違反の状態になっている気がします。

 まあ、これが嫌なら電流制限抵抗を入れてください。でも部品が増えるし LEDの点灯数によって明るさが変わっちゃって、あまりいいことはありませんよ、ということなんでしょう。

 あと、ATmega328Pの絶対最大定格には、VCC/GNDピンの電流は200mA以内という制限がありますが、実測で消費電流は0.12A程度だったので、こちらは大丈夫そうです。なお、他に見逃しているスペック上の制限があるかも知れません。

▼動作デモ

 なかなか綺麗です。それに、LEDが猛烈な明るさで光っていることが良く判ると思います。なお、これはライブラリのLoLshield_Demo を走らしていますが、このプログラムは状態をEEPROMに保存していて、リセットボタンを押すたびに4種類のデモを順番に動かすようになっています。(そのために時々手が出てきます)

◆まとめ
 Aliexpressから買わないといけないし、別途LEDも手配しないといけませんが、これかなり楽しめると思います。あと、とても明るいので屋外でも十分使えると思います。

 この記事では別途購入した緑色のLEDを使いましたが、オリジナルの赤色LEDを使っていたらポートへの負担はもっと重くなっていたと思います。

 あと、最初のオシロの波形ですが、この時電流を供給しているポートにはピークで60mAくらいの電流が流れている可能性があります。平均電流としてはもっと小さな値になるはずですが、長時間動かし続けるような用途では危ないかも知れません。そういう場合は電源電圧を3.3Vにした方が良い気がします。

 ところで、ポートの最大許容電流の20mAは絶対最大定格なので、瞬時たりとも超えてはいけない値です。となると、この記事に出てくる話は全部規格違反の可能性があります。デューティを考慮した平均電流なら、とりあえず規格の20mA以下になっている可能性あありますが、そういう自分勝手な解釈はダメなんでしょうね。
カレンダー
12 | 2019/01 | 02
- - 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コード