SSブログ

OLED 0.91インチディスプレイを買ってみた [DIY電気]

電子工作で小型の表示器が必要になりAmazonでOLED表示器を買ってみました。
「DSD TECH 2 PCS Arduino ARM用IIC OLEDの0.91インチディスプレイ」という商品で表示面積がかなり小さなものとなっています。届いた商品を開けると本体と接続ケーブルが2セット、広告っぽいチラシ一枚です。
DSC_0980.jpg

ひとつ手にとってます。
赤いのは保護シートを剥がす端っこです。
DSC_0981.jpg

それぞれの表裏です。
DSC_0982.jpg

Arduinoのu8glibライブラリを使えと書いてあるだけです。私は、PICマイコンで使用するつもりなのでArduinoと言われてもピンと来ないのです。勉強不足でついて行けません。
もう少し調べると、一番重要なキャラクターROMが入ってないということが判明したのであります。やられました!
まあ、購入前からキャラクターROMが入ってないというのは薄々わかっていましたが、案の定そうだったわけです。
文字フォントはマイコン側に持たせてI2C通信によりビット情報を流し込んでドットで書け!というものです。
今回の工作では主に時刻情報を表示させたいので、一歩譲って最悪数字とコロンと+αがあればいいということにします。
チラシにはメインチップがSSD1306だと書かれていますので、早速ネットで仕様書をダウンロードして入手。
コントローラであるSSD1306は128*64の解像度のOLEDを制御するとのこと。縦の64ドットは8ブロックに分かれ、ページと呼んでいます。1ページの縦は8ドットです。全面を全て書くには、8ビットを128回書くのを8回繰り返すということです。
それは理解できたんですけど、今回購入した表示器は128*32なので仕様書に書かれている縦のドット数が半分なのです。
あたって砕けろ!ということでブレッドボードでテストしてみました。
PICマイコンは16F88です。
DSC_0985.jpg

回路図です。
OLED TEST.gif

データを流し込んだら、わ~綺麗な水色表示!
でも、なんか変んな表示!どういうこと?砕けかけそうです。
それからそれから、あれこれ遊んでいるうちに発見しました。
奇数ビットだけ表示しているようなんです。
おいおい、偶数ビットは無視かよ。
仕様書に舞い戻り、「Set COM Pins Hardware Configuration (DAh)」という項目に目が止まりました。
0xDAコマンドの次の1バイトデータで設定できるようです。
今回初期値でテストしていましたので、0xDAに続いて0x02を設定することにより表示に成功しました。
左は猫のシルエットを4文字分で表示されています。
数字は、自作の7セグメント風フォントです。
DSC_0998.jpg

ビットマップフォントは1文字12*16にしています。横12ドットだと10文字で120ドットなので水平方向は8ドット余る計算。
縦はフルで32ドットなので、その半分の16ドットにしました。表示できる文字数は10*2ということになります。
DSC_1001.jpg

その後、テストを繰り返しているうちに別の場所のACコンセントにさすと、OLED画面の初期化に失敗しているようで、画面が反転モードだったり、砂の嵐だったり、一部が横線だったり、勝手にスクロールしたりなんです。
数分完全放電させると正常になったりするので、動作モードが予期せぬモードにラッチしているような感じです。ラッチが抜けにくいというか。
SSD1306仕様書の最後にApp Noteというのがあり、P5/6に「Software Configuration」の項目があり初期化のフローが書いてありました。12ステップですが、仕様書どおりに初期化ルーチンを書いて様子見しましたが改善せず。
結果的には商品が不良っぽいです。
2つのうちもうひとつは安定動作することがわかりました。

ここからCCSC用のテストプログラム(C言語ソースコード)です
/**********************************************
  OLED TEST PROGRAM
  DSD TECH OLED 0.91inch Display
  CCSC PIC COMPILER
  DATE 2019 JULY
***********************************************/

#include <16f88.h>
#use delay(clock=20000000)
#FUSES  HS,NOWDT,NOPROTECT,PUT,MCLR,NOBROWNOUT,NOLVP
#ignore_warnings 203
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>

#use i2c(master,sda=PIN_B1,scl=PIN_B4,FAST)

// Bitmap Font Data
//
// [14][24]で一つの配列にしたかったがコンパイラエラーとなるため分けた
// font1[14][12], font2[14][12]の2つにした
byte const font1[14][12] =
{
{0x00,0xFC,0x7A,0x06,0x06,0x06,0x06,0x06,0x06,0x7A,0xFC,0x00},//0
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xFE,0x00},//1
{0x00,0x00,0x82,0x86,0x86,0x86,0x86,0x86,0x86,0x7A,0xFC,0x00},//2
{0x00,0x02,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x7A,0xFC,0x00},//3
{0x00,0xFE,0x7C,0x80,0x80,0x80,0x80,0x80,0x80,0x7C,0xFE,0x00},//4
{0x00,0xFC,0x7A,0x86,0x86,0x86,0x86,0x86,0x86,0x02,0x00,0x00},//5
{0x00,0xFC,0x7A,0x86,0x86,0x86,0x86,0x86,0x86,0x82,0x00,0x00},//6
{0x00,0xFC,0x7A,0x06,0x06,0x06,0x06,0x06,0x06,0x7A,0xFC,0x00},//7
{0x00,0xFC,0x7A,0x86,0x86,0x86,0x86,0x86,0x86,0x7A,0xFC,0x00},//8
{0x00,0xFC,0x7A,0x86,0x86,0x86,0x86,0x86,0x86,0x7A,0xFC,0x00},//9
{0xFF,0xFC,0xB8,0xF8,0xF8,0xB8,0xFE,0x00,0x00,0x00,0x00,0x00},//CAT LTOP
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//CAT RTOP
{0x00,0x01,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//CAT LBTM
{0xFF,0xFF,0xFF,0xFF,0xFC,0xC0,0x00,0x07,0x1F,0xF8,0xE0,0x00},//CAT RBTM
};

byte const font2[14][12] =
{
{0x00,0x3F,0x5E,0x60,0x60,0x60,0x60,0x60,0x60,0x5E,0x3F,0x00},//0
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x7F,0x00},//1
{0x00,0x3F,0x5E,0x61,0x61,0x61,0x61,0x61,0x61,0x41,0x00,0x00},//2
{0x00,0x40,0x60,0x61,0x61,0x61,0x61,0x61,0x61,0x5E,0x3F,0x00},//3
{0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x3E,0x7F,0x00},//4
{0x00,0x00,0x41,0x61,0x61,0x61,0x61,0x61,0x61,0x5E,0x3F,0x00},//5
{0x00,0x3F,0x5E,0x61,0x61,0x61,0x61,0x61,0x61,0x5E,0x3F,0x00},//6
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x7F,0x00},//7
{0x00,0x3F,0x5E,0x61,0x61,0x61,0x61,0x61,0x61,0x5E,0x3F,0x00},//8
{0x00,0x00,0x40,0x61,0x61,0x61,0x61,0x61,0x61,0x5E,0x3F,0x00},//9
{0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xF8,0xF0,0xF0,0xE0},//CAT LTOP
{0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0xE0,0xF0,0x38,0x38,0x18},//CAT RTOP
{0x20,0x60,0x78,0xFF,0xFF,0x7F,0x1F,0x7F,0x7F,0xFF,0xFF,0xFF},//CAT LBTM
{0x7F,0x7F,0x7F,0x7F,0x3F,0x3F,0x38,0x38,0x1C,0x0F,0x03,0x00},//CAT RBTM
};

// AポートのI/Oビット配置
struct porta_pin_map {      // This structure is overlayed
    BOOLEAN reserved1;
    BOOLEAN reserved2;
    BOOLEAN reserved3;
    BOOLEAN reserved4;
    BOOLEAN pl;      //pilot lamp
} PORTA;
#byte PORTA = 0x05
#byte PORTB = 0x06

void oled_init(void);
void oled_clr(int);
void char1216( int font_code, int cx, int cy );
/*---------------------------------------------
   main module
---------------------------------------------*/
void main( void ){
    setup_adc_ports(NO_ANALOGS);
    setup_ccp1(CCP_OFF);
    set_tris_a( 0x00 );     // ALL OUT
    set_tris_b( 0x12 );     // SDA, SCL is INPUT
    PORTA.pl = 0;           //PL OFF
    delay_ms(100);
    oled_init();
    delay_ms(100);
    oled_clr(0x00);


    char1216(10,0,0);  //猫シルエット左上
    char1216(11,1,0);  //右上
    char1216(12,0,1);  //左下
    char1216(13,1,1);  //右下

    char1216(0,2,0);  // Font0 を x=2 y=0に出力
    char1216(1,3,0);
    char1216(2,4,0);
    char1216(3,5,0);
    char1216(4,6,0);
    char1216(5,7,0);
    char1216(6,8,0);
    char1216(7,9,0);

    char1216(8,2,1);
    char1216(9,3,1);
    char1216(0,4,1);
    char1216(1,5,1);
    char1216(2,6,1);
    char1216(3,7,1);
    char1216(4,8,1);
    char1216(5,9,1);
    while(1);
}

/* ----------------------------------------------------------------
    OLEDの初期化
---------------------------------------------------------------- */
void oled_init(void)
{
   i2c_start();
   i2c_write(0x78); // OLED slave address
   i2c_write(0x00); // Control byte Co=0, D/C#=0
   i2c_write(0xa8); //SET MUX RATIO
   i2c_write(0x3f);
   i2c_write(0xd3); //SET DISPLAY OFFSET
   i2c_write(0x00);
   i2c_write(0x40); //SET DISPLAY START LINE
#if 0 //画面上下設定
   i2c_write(0xa0); //SET SEGMENT RE-MAP
   i2c_write(0xc0); //SET COM OUTPUT SCAN DIRECTION
   i2c_write(0xda); //SET COM PINS HARDWARE CONFIGURATION
   i2c_write(0x02);
#else //画面上下逆
   i2c_write(0xa1); //SET SEGMENT RE-MAP
   i2c_write(0xc8); //SET COM OUTPUT SCAN DIRECTION
   i2c_write(0xda); //SET COM PINS HARDWARE CONFIGURATION
   i2c_write(0x22);
#endif
   i2c_write(0x81); //SET CONTRAST CONTROL
   i2c_write(0x7f);
   i2c_write(0xa4); //DISABLE ENTRE DISPLAY ON
   i2c_write(0xa6); //SET NORMAL DISPLAY
   i2c_write(0xd5); //SET OSC FREQUENCY
   i2c_write(0x80);
   i2c_write(0x8d); //ENSBLE CHSRGE PUMP REGULATOR
   i2c_write(0x14);
   i2c_write(0xaf); //DISPLAY ON
   i2c_stop();
}
/* ----------------------------------------------------------------
    OLEDの画面クリア

      data : 埋めるデータ
---------------------------------------------------------------- */
void oled_clr(int data) // OLED 画面消去
{
   int32 i;
   i2c_start();
   i2c_write(0x78); // OLED slave address
   i2c_write(0x00); // Control byte Co=0, D/C#=0
   i2c_write(0x20); // Set memory addressing mode
   i2c_write(0x00); // Horizontal addressing mode
   i2c_write(0x21); // Set column address
   i2c_write(0x00); // Column start address 0
   i2c_write(0x7F); // Column end address 127d
   i2c_write(0x22); // Set page address
   i2c_write(0x00); // Page start address 0
   i2c_write(0x03); // Page end address 7d ->3d
   i2c_stop();
   i2c_start();
   i2c_write(0x78); // OLED slave address
   i2c_write(0x40);
   for(i=0; i<512; i++){ // 128COL * 4page
     i2c_write(data); // Out data
   }
   i2c_stop();
}

/* ----------------------------------------------------------------
     OLEDに一文字出力
       font_code:
          配列を指定(0~)
       cx:
          出力水平位置(0~9)
       cy:
          出力垂直位置(0~1)
---------------------------------------------------------------- */
void char1216( int font_code, int cx, int cy ) // 12x16dot FONT
{
    int x;
    i2c_start();
    i2c_write(0x78); // OLED slave address
    i2c_write(0x00); // Control byte Co=0, D/C#=0
    i2c_write(0x20); // Set memory addressing mode
    i2c_write(0x00); // Horizontal addressing mode
    i2c_write(0x22); // Set Page Address
    i2c_write(cy*2); // Page Start
    i2c_write(cy*2+1); // Page End
    i2c_write(0x21);  // Set Column Address
    i2c_write(cx*12);  // Start Address(0-9)
    i2c_write(cx*12+11);  // End Address
    i2c_stop();
    i2c_start();
    i2c_write(0x78); // OLED slave address
    i2c_write(0x40);
    for( x=0 ; x<12 ; ++x ){
      i2c_write(font1[font_code][x]);
    }
    for( x=0 ; x<12 ; ++x ){
      i2c_write(font2[font_code][x]);
    }
   i2c_stop();
}


このデバイスを使った電子工作が完成したら記事にしたいと思います。


DSD TECH 2 PCS Arduino ARM用IIC OLEDの0.91インチディスプレイ

DSD TECH 2 PCS Arduino ARM用IIC OLEDの0.91インチディスプレイ

  • 出版社/メーカー: DSD TECH
  • メディア: エレクトロニクス




人気ブログランキング
nice!(0)  コメント(0) 
共通テーマ:日記・雑感