GPIO 増設した ESP-WROOM-02 ( ESP8266 )で、8bitモードのグラフィックディスプレイ を制御してみた

ESP8266 ( ESP-WROOM-02 )

こんばんは。

前回の記事では、ESPr Developer ( ESP-WROOM-02, ESP8266 ) のGPIOを増設して、キャラクタディスプレイを8bitモードで制御してみました。

今回は、そのディスプレイを100×16ドットのグラフィックモードにして、同じく8bitモードで制御してみようと思います。

この有機EL ( OLED )グラフィックディスプレイ

ストロベリーリナックス ( Strawberry Linux )
グラフィック有機ELモジュール100x16

は、数ある電子工作用途の有機ELグラフィックディスプレイの中で、最もドットが大きいものです。
ある程度遠くからでも文字を視認できる電光掲示板を作るには、LEDマトリックスよりも簡単に実現できるものです。
今となっては極小ドットのディスプレイは沢山ありますが、大きいドット(ピクセル)というものはなかなか見当たりません。
他のメーカーさんもどんどんこういうタイプのディスプレイは取り扱っていただきたいと個人的には思いますね。

では、これのグラフィックモードの使い方について説明します。

スポンサーリンク

1.使うもの

8ビット SPI I/Oエキスパンダ MCP23S08-E/P

秋月電子通商さんで販売しています。
Microchip製です。
これは5V駆動ですのでご注意ください
SPI通信の最大速度は10MHz です。
ESPr Developer ( ESP-WROOM-02, ESP8266 )ではGPIOピンが少ないので、これを使って増設します。
これで8bitモードパラレルのディスプレイが制御できます。

グラフィック有機ELモジュール100x16

ストロベリーリナックス ( Strawberry Linux )さんで販売しています。
コントローラーは WS0010 を使ってます。
キャラクタモードとグラフィックモードを切り替えできます。

ESPr Developer ( ESP-WROOM-02 開発ボード )
スイッチサイエンス製
Amazon.co.jp

ESP-WROOM-02開発ボード
スイッチサイエンス(Switch Science)

ESPr Developer(ピンソケット実装済)
スイッチサイエンス(Switch Science)

これについては何度も当ブログで紹介しておりますが、日本の電波法をクリアした技適認証済み Wi-Fi モジュールです。ESP-WROOM-02 が安定して動作して、とても使いやすいです。
Arduino IDE で開発ができて、とてもお勧めです。
これの使い方については以下のページを参照してください。
https://www.mgo-tec.com/blog-entry-ss-wroom-howto01.html

0.1uF セラミックコンデンサー
I/Oエクスパンダの MCP23S08 チップの電源誤作動を防ぐためのパスコンです。
積層セラミックでも良いです。

サンハヤト製ニューブレッドボード 【SAD-101】
このブレッドボードがお勧めです。

サンハヤト SAD-101 ニューブレッドボード
サンハヤト
¥529(2024/04/27 13:39時点)

2.組み立て、接続、設定等

前回の記事の2~4まで予め設定を済ませておいてください。

3.Arduino IDEのスケッチ入力

では、以下のスケッチを入力してみてください。

【ソースコード】 (※無保証 ※PCの場合、ダブルクリックすればコード全体を選択できます)

/* ESPr Developer or ESP-WROOM-02 or ESP8266
 * GPIO Expander = MCP23S08 ( Microchip )
 * OLED = WS0010 ( Strawberry Linux )
 */
#include <SPI.h>

//GPIOエクスパンダ MCP23S08 のSPIインターフェースピン設定
const uint8_t sclk = 14; //SPIクロック出力ピン
const uint8_t mosi =13; //Master Output Slave Input ESP8266=Master,MCP23S08=slave 
const uint8_t MCP_CS = 0; //MCP23S08 CSピン(Chip Select)
const uint8_t MCP_RST_pin =  4; //MCP23S08 リセットピン
//OLED ピン設定 (8bitモード用)
const uint8_t OLED_RS_pin = 2; //設定コマンド or データコマンドのモード選択ピン
const uint8_t OLED_RW_pin =  5; //書込み or 読み取りモード選択ぴん
const uint8_t OLED_E_pin = 16; //データ確定のEnterピン

int i;

void setup() {
  delay(1000); //電源起動後、動作が安定するまで1秒待つ

  MCP23S08_Ini(); //GPIOエクスパンダ初期化  
  OLED_Graphic_Ini(); //OLED初期化
  
  OLED_XYset(0, 0);
  OLED_DataWrite(B11111111);
  OLED_XYset(0, 1);
  OLED_DataWrite(B01010101);

  OLED_XYset(32, 0);
  for(i=0; i<8; i++){
    OLED_DataWrite(B00000001<<i); //ビットを左へiずつ移動
  }
  OLED_XYset(32, 1);
  for(i=0; i<8; i++){
    OLED_DataWrite(B10000000>>i); //ビットを右へiずつ移動
  }
}

void loop() {
  byte Xplot = 48;
  
  for(i=0; i<8; i++){
    OLED_XYset(Xplot + i, 0);
    OLED_DataWrite(B00000001<<i); //ビットを左へiずつ移動
    if(i>=0){
      OLED_XYset(Xplot + (i-1), 0);
      OLED_DataWrite(0); //ドットを消す
    }
    delay(50);
  }
  OLED_XYset(Xplot+7, 0);
  OLED_DataWrite(0); //ドットを消す
  for(i=0; i<8; i++){
    OLED_XYset(Xplot+8+i, 1);
    OLED_DataWrite(B00000001<<i); //ビットを左へiずつ移動
    if(i>=0){
      OLED_XYset(Xplot+8+(i-1), 1);
      OLED_DataWrite(0); //ドットを消す
    }
    delay(50);
  }
  OLED_XYset(Xplot+8+7, 1);
  OLED_DataWrite(0); //ドットを消す
}

void MCP23S08_Ini(){ //GPIOエクスパンダ MCP23S08初期化
  pinMode(MCP_CS, OUTPUT);
  pinMode(MCP_RST_pin, OUTPUT);
  
  SPI.begin();
  SPI.setFrequency(10000000); //MCP23S08 Max 10MHz
  SPI.setDataMode(SPI_MODE0);

  digitalWrite(MCP_RST_pin, HIGH);
  delay(100);
  digitalWrite(MCP_RST_pin, LOW);
  delay(100);
  digitalWrite(MCP_RST_pin, HIGH);
  delay(100);
  
  digitalWrite(MCP_CS, LOW);
    delay(1);
    SPI.write(B01000000); //デバイスオペコードB01000000 & チップaddress 000
    SPI.write(0x05); //MCP設定レジスタIOCON 
    SPI.write(B00100000); //シーケンシャル動作禁止、SDAスルーレート許可、ハードウェアアドレスピン禁止、INT出力LOW、アクティブドライブ
    delay(1);
  digitalWrite(MCP_CS, HIGH);
  
  digitalWrite(MCP_CS, LOW);
    delay(1);
    SPI.write(B01000000); //デバイスオペコードB01000000 & チップaddress 000
    SPI.write(0x00); // I/O方向レジスタ(IODIR)設定
    SPI.write(B00000000); //8pin ALL OUTPUT
    delay(1);
  digitalWrite(MCP_CS, HIGH);
}

void OLED_Graphic_Ini(){ //OLED WS0010 初期化
  pinMode(OLED_RW_pin, OUTPUT);
  pinMode(OLED_RS_pin, OUTPUT);
  pinMode(OLED_E_pin, OUTPUT);
  
  digitalWrite(OLED_E_pin, LOW);
  digitalWrite(OLED_RW_pin, LOW);
  digitalWrite(OLED_RS_pin, LOW);

  //OLEDリセット
  delayMicroseconds(10);
  OLED_CommandWrite(B00000001);//Display Clear
  delay(10);
  OLED_CommandWrite(B00010011);//Character MODE ON, Power is turned OFF
  delay(10); //リセットは一旦電源を切るべし
  OLED_CommandWrite(B00001000);//Display OFF, Cursor OFF, Brinking OFF 
  delay(1000);
  //ここからディスプレイ初期化設定
  OLED_CommandWrite(B00011111);//Graphics MODE ON, Power is turned ON
  delay(10);
  OLED_CommandWrite(B00111000);//Function Set 8bit-mode 2Line-display
  delay(10);
  OLED_CommandWrite(B00001111);//Display On, Cursor ON, Brinking on 
  delay(10);
  OLED_CommandWrite(B00000001);//Display Clear
  delay(10);
  OLED_CommandWrite(B00000010);//Return HOME
  delay(10);
  OLED_CommandWrite(B00000110);//Entry Mode Set, Increment, No-Shift
  delay(10);
}

void OLED_XYset(uint8_t x, uint8_t y){
   OLED_CommandWrite(0x80 + x);  
   OLED_CommandWrite(0x40 + y);
}

void OLED_CommandWrite(uint8_t b){
  digitalWrite(OLED_RS_pin, LOW);
  MCP23S08_SpiCommandWrite(b);
  digitalWrite(OLED_E_pin, HIGH);//EピンをHIGH→LOWへ変化させると書き込み完了
  digitalWrite(OLED_E_pin, LOW);
}

void OLED_DataWrite(uint8_t b){
  digitalWrite(OLED_RS_pin, HIGH);
  MCP23S08_SpiCommandWrite(b);
  digitalWrite(OLED_E_pin, HIGH);//EピンをHIGH→LOWへ変化させると書き込み完了
  digitalWrite(OLED_E_pin, LOW);
}

void MCP23S08_SpiCommandWrite(uint8_t b){
  digitalWrite(MCP_CS, LOW);
    SPI.write(B01000000);
    SPI.write(0x0A);
    SPI.write(b);
  digitalWrite(MCP_CS, HIGH);
}

【解説】
前回の記事同様、WS0010のデータシートも合わせて参照してみてください。

●5行目:
ESP8266 core for Arduino のSPI標準ライブラリのインクルードです。

●8-11行:
GPIO エキスパンダ用のESPr Developer ( ESP-WROOM-02, ESP8266 )側のピン設定です。

●13-15行:
有機EL ( OLED )用のESPr Developer ( ESP-WROOM-02, ESP8266 )側のピン設定です。

●22行:
GPIO エキスパンダ MCP23S08 の初期化をします。
67-97行で関数化してます。
これの説明は前回の記事を参照してください。

●23行:
OLED (有機EL) ディスプレイをグラフィックモードにする初期化です。
99-129行で関数化してます。
前回の記事のキャラクタモードの初期化との違いは、117行目の第3ビットが1になっていることです。

0ビット目 = 1
1ビット目 = 1
2ビット目 = 電源ON
3ビット目 = グラフィックモードON

キャラクタモードの場合 = 00010111
グラフィックモード = 00011111

●25-28行:
25行で、OLED のドットを表示させる位置を決めます。
まず、原点を(0, 0) とします。
これは131-134行で関数化してます。
このディスプレイの座標は下図の様になってます。

なんか、ビットの並びが縦方向になっているディスプレイが多いですね。
日本語を扱うことが多い私にとっては、水平方向並びの方が扱いやすいのですが・・・。

26行目で、表示させる8ビットデータを送信してます。
143-148行でデータ送信を関数化してます。
この、コマンド送信関数とデータ送信関数の詳細は前回の記事を参照してください。
OLEDに設定コマンドとして0x80 に水平座標のx位置(0~100) を加算すれば、ビットを縦方向でズラッと表示してくれます。0が消灯で、1が点灯です。

●30-37行:
ここでは、連続してデータを送信した場合にどの様に表示されるかをテストしてます。
まず、30行目で表示開始位置を指定して、31-33行で表示ドットを毎回1ビットずつずらしていきます。
34行目でY座標を1にして(2行目に表示)、同じようにビットをずらしていきます。

●40-65行:
ここでは、ドットが時間とともに移動していく簡易アニメーション的なプログラムです。
delay(50)で50ms毎にずらしたビットを表示させてます。
ただ、ビットを移動させたら、直前に表示させたビットを消さないとアニメーションになりません。
このようにY座標をまたいでドットを移動させるにはちょっと面倒な工夫が必要になります。

4.コンパイル実行

では、Arduino IDEのスケッチをコンパイル実行させてみてください。
このように表示されればOKです。

どうでしょうか?
ここまでできれば、日本漢字フォントを表示させることも可能になります。
次回はいよいよ16×16ドットの漢字フォントを表示させてみたいと思います。

ではまた・・・。

Amazon.co.jp 当ブログのおすすめ

スイッチサイエンス ESPr Developer 32 Type-C SSCI-063647
スイッチサイエンス
¥2,420(2024/04/27 03:55時点)
ZEROPLUS ロジックアナライザ LAP-C(16032)
ZEROPLUS
¥22,504(2024/04/27 15:18時点)
Excelでわかるディープラーニング超入門
技術評論社
¥2,068(2024/04/26 21:54時点)

コメント

タイトルとURLをコピーしました