shonen.hateblo.jp

やったこと,しらべたことを書く.

1.5inch RGB OLED Module の公式のライブラリが全ての色を使えていないので,全ての色を使えるようにする

環境

Arduino Micro

動機

公式の通販サイト https://www.waveshare.com/1.5inch-rgb-oled-module.htm には16bit(65K colors)と書かれているが, 18bitで指定できる設定を見つけたので記事にした.

本当に262k colors発色出来ているかどうか,人がそれを認識できるかどうかはまた別の問題.

やってみる

公式サイトのwiki 1.5inch RGB OLED Module - Waveshare Wiki にサンプルコードがある.

とりあえず,単独で動くようにサンプルコードから抜粋.

下のコードは未だ16bit.

#include "SPI.h"

#define SSD1351_WIDTH   128
#define SSD1351_HEIGHT  128

#define SSD1351_CMD_SETCOLUMN       0x15
#define SSD1351_CMD_SETROW          0x75
#define SSD1351_CMD_WRITERAM        0x5C
#define SSD1351_CMD_READRAM         0x5D
#define SSD1351_CMD_SETREMAP        0xA0
#define SSD1351_CMD_STARTLINE       0xA1
#define SSD1351_CMD_DISPLAYOFFSET   0xA2
#define SSD1351_CMD_DISPLAYALLOFF   0xA4
#define SSD1351_CMD_DISPLAYALLON    0xA5
#define SSD1351_CMD_NORMALDISPLAY   0xA6
#define SSD1351_CMD_INVERTDISPLAY   0xA7
#define SSD1351_CMD_FUNCTIONSELECT  0xAB
#define SSD1351_CMD_DISPLAYOFF      0xAE
#define SSD1351_CMD_DISPLAYON       0xAF
#define SSD1351_CMD_PRECHARGE       0xB1
#define SSD1351_CMD_DISPLAYENHANCE  0xB2
#define SSD1351_CMD_CLOCKDIV        0xB3
#define SSD1351_CMD_SETVSL          0xB4
#define SSD1351_CMD_SETGPIO         0xB5
#define SSD1351_CMD_PRECHARGE2      0xB6
#define SSD1351_CMD_SETGRAY         0xB8
#define SSD1351_CMD_USELUT          0xB9
#define SSD1351_CMD_PRECHARGELEVEL  0xBB
#define SSD1351_CMD_VCOMH           0xBE
#define SSD1351_CMD_CONTRASTABC     0xC1
#define SSD1351_CMD_CONTRASTMASTER  0xC7
#define SSD1351_CMD_MUXRATIO        0xCA
#define SSD1351_CMD_COMMANDLOCK     0xFD
#define SSD1351_CMD_HORIZSCROLL     0x96
#define SSD1351_CMD_STOPSCROLL      0x9E
#define SSD1351_CMD_STARTSCROLL     0x9F

namespace OLED{

  const uint8_t oled_cs = 10;
  const uint8_t oled_rst = 8;
  const uint8_t oled_dc = 7;

  void update_cs(uint8_t x)  {
    digitalWrite(oled_cs, x);
  }
  
  void update_rst(uint8_t x) {
    digitalWrite(oled_rst, x);
  }
  
  void update_dc(uint8_t x) {
    digitalWrite(oled_dc, x);
  }

  void write_command(uint8_t cmd) {
    update_dc(LOW);
    SPI.transfer(cmd);
    update_dc(HIGH);
  }
  
  void write_data(uint8_t dat) {
    update_dc(HIGH);
    SPI.transfer(dat);
    update_dc(LOW);
  }

  void ram_address(){ // ?
    write_command(SSD1351_CMD_SETCOLUMN);
    write_data(0x00);
    write_data(0x7f);
  
    write_command(SSD1351_CMD_SETROW);
    write_data(0x00);
    write_data(0x7f);
  }
  
  void init(void) {
    pinMode(oled_cs, OUTPUT);
    pinMode(oled_rst, OUTPUT);
    pinMode(oled_dc, OUTPUT);
  
    SPI.setDataMode(SPI_MODE0);
    SPI.setBitOrder(MSBFIRST);
    SPI.setClockDivider(SPI_CLOCK_DIV2);
    SPI.begin();
    
    update_cs(LOW);
    update_rst(LOW);
    delay(500);
    update_rst(HIGH);
    delay(500);
      
    write_command(SSD1351_CMD_COMMANDLOCK);
    write_data(0x12);
    write_command(SSD1351_CMD_COMMANDLOCK);
    write_data(0xB1);
  
    write_command(SSD1351_CMD_DISPLAYOFF);
    write_command(SSD1351_CMD_DISPLAYALLOFF);  // Normal Display mode
  
    ram_address();
  
    write_command(SSD1351_CMD_CLOCKDIV);
    write_data(0xF1);
  
    write_command(SSD1351_CMD_MUXRATIO);  
    write_data(0x7F);
  
    write_command(SSD1351_CMD_SETREMAP);  //set re-map & data format
    write_data(0x74); //Horizontal address increment
              //74
    write_command(SSD1351_CMD_STARTLINE);  //set display start line
    write_data(0x00); //start 00 line
  
    write_command(SSD1351_CMD_DISPLAYOFFSET);  //set display offset
    write_data(0x00);
  
    write_command(SSD1351_CMD_FUNCTIONSELECT);  
    write_data(0x01);  // 元のOLED_Driver.cppではwrite_commandだがwrite_dataの間違い?
  
    write_command(SSD1351_CMD_SETVSL);  
    write_data(0xA0);   
    write_data(0xB5);  
    write_data(0x55);    
  
    write_command(SSD1351_CMD_CONTRASTABC);  
    write_data(0xC8); 
    write_data(0x80);
    write_data(0xC0);
  
    write_command(SSD1351_CMD_CONTRASTMASTER);  
    write_data(0x0F);
  
    write_command(SSD1351_CMD_PRECHARGE);  
    write_data(0x32);
  
    write_command(SSD1351_CMD_DISPLAYENHANCE);  
    write_data(0xA4);
    write_data(0x00);
    write_data(0x00);
  
    write_command(SSD1351_CMD_PRECHARGELEVEL);  
    write_data(0x17);
  
    write_command(SSD1351_CMD_PRECHARGE2);  
    write_data(0x01);
  
    write_command(SSD1351_CMD_VCOMH);  
    write_data(0x05);
  
    write_command(SSD1351_CMD_NORMALDISPLAY);
  
    // Clear_Screen();
    write_command(SSD1351_CMD_DISPLAYON);   //display on
  }
  
}


void setup() {
  using namespace OLED;
  OLED::init();
  {
    const uint16_t color = 0xf800;
    uint8_t color0 = uint8_t(color >> 8);
    uint8_t color1 = uint8_t(color & 0x00ff);
    uint16_t i,j;
    ram_address();
    write_command(SSD1351_CMD_WRITERAM);
    for(i = 0; i < 128; i++)  {
      for(j = 0; j < 128; j++)  {
        write_data(color0);
        write_data(color1);
      }
    }
  }
}

void loop() {
}

データシート https://www.waveshare.com/w/upload/a/a7/SSD1351-Revision_1.5.pdf の32ページにある,コマンド表を見る.

Set Re-Mapコマンドの上位2ビットのパラメータで,65k color262k colorが選べるのが読み取れる.よって,

    write_command(SSD1351_CMD_SETREMAP);  //set re-map & data format
    write_data(0x74); //Horizontal address increment

    write_command(SSD1351_CMD_SETREMAP);  //set re-map & data format
    write_data(0xb4);

に書き換えれば,262k colorモードになる.

23ページに色の指定方法が書かれているので,8bits 262kの項目を見ながら

void setup() {
  using namespace OLED;
  OLED::init();
  {
    uint16_t i,j;
    ram_address();
    write_command(SSD1351_CMD_WRITERAM);
    for(i = 0; i < 128; i++)  {
      for(j = 0; j < 128; j++)  {
        write_data(0x3f); // R
        write_data(0x00); // G
        write_data(0x00); // B
      }
    }
  }
}

と書けば真っ赤の画面が表示される.

8bit x3ではなく18bitで無駄なく転送する

todo