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 color
,262k 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