LoginSignup
9
5

More than 3 years have passed since last update.

小型カラー液晶SSD1331とAdafruit GFX ライブラリを使用してbitmapを表示する

Last updated at Posted at 2018-11-08

Amazonで購入した小型カラー液晶SSD1331でビットマップを表示してみました。

スクリーンショット 2018-11-08 10.30.55.png

簡単なアニメーションを表示したかったので、ループで drawPixel()をまわすのではなく、drawBitmap()で画像を一度に表示することにしました。

void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color);

drawBitmap()はあくまでも1bitの白黒画像に色をつけて表示する仕組みのようです。
bitmapに2値画像を渡して、1が立っている場所はcolorの色で表示し、0のところは元の色を残してスキップします。

ですので、カラー画像を表示するためには版画の多色刷りのようになんども色を変えてdrawBitmap()する必要があります。

例えば赤、茶、白で構成されたりんごの画像 apple.png を表示したい場合、

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,1,1,0,1,1,1,1,0,0,0,0,
0,0,1,1,1,0,1,0,0,1,0,1,1,1,0,0,
0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,0,
0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,
0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,
0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,
0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,
0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,
0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,
0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,
0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,1,0,1,1,0,1,0,0,0,0,0,
0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

のような2値画像データを用意し、左上→右下の順でMSB->LSB,MSB->LSB,,
のように8ピクセルごとのデータを作っていきます。

nが[0,1]とすると、左上のピクセルが(n_0<<7),左上から右に8番目のピクセルが(n_7<<0)となります。
data[0] = (n_0<<7)+(n_1<<6)+(n_2<<5)+(n_3<<4)+(n_4<<3)+(n_5<<2)+(n_6<<1)+(n_7<<0);
[apple_red]
0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0xF0,
0x3A,0x5C,0x7C,0x3E,0x7F,0xEE,0x7F,0xF6,
0x7F,0xF6,0x7F,0xF6,0x3F,0xFE,0x1F,0xFC,
0x1F,0xFC,0x07,0xF8,0x01,0xE0,0x00,0x00,

[apple_dkred]
0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,
0x05,0xA0,0x03,0xC0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x40,0x00,0x20,0x00,
0x20,0x00,0x18,0x00,0x06,0x00,0x00,0x00,
void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bgcolor);

引数を一つ増やしてbgcolorに値を渡すと、ピクセルのない場所はスキップではなくbgcolorで描画するようになります。なので今回は、

  • 赤い部分を表示&背景を白で表示
  • 茶色部分を表示(それ以外はヌキ)

の2回描画することで背景含め3色の画像を表示しています。

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>

#define sclk 13
#define mosi 11
#define cs   10
#define rst  8
#define dc   9

// Color definitions
#define RED             0xF800
#define DKRED           0x7000
#define WHITE           0xFFFF

#define PIC_SIZE_X (16)
#define PIC_SIZE_Y (16)

Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);

void setup(void) {
  display.begin();

  const uint8_t apple_red[] PROGMEM = {
    0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0xF0,
    0x3A,0x5C,0x7C,0x3E,0x7F,0xEE,0x7F,0xF6,
    0x7F,0xF6,0x7F,0xF6,0x3F,0xFE,0x1F,0xFC,
    0x1F,0xFC,0x07,0xF8,0x01,0xE0,0x00,0x00,
  };
  const uint8_t apple_dkred[] PROGMEM = {
    0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,
    0x05,0xA0,0x03,0xC0,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x40,0x00,0x20,0x00,
    0x20,0x00,0x18,0x00,0x06,0x00,0x00,0x00,
  };

  display.fillScreen(DKRED);
  display.drawBitmap(0, 0, (uint8_t*)apple_red, PIC_SIZE_X, PIC_SIZE_Y,  RED,WHITE);
  display.drawBitmap(0, 0, (uint8_t*)apple_dkred, PIC_SIZE_X, PIC_SIZE_Y, DKRED);
}

void loop() {
}

IMG_6028.jpg

少し時間を置いてから別の画像を表示すればアニメーションとして表示が可能です
Youtube

[追記]
秋葉原ラジオデパート3FのShigezoneで売っていたbluepillクローンでも表示してみました。

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>

// You can use any (4 or) 5 pins 
#define sclk PB9 //13
#define mosi PB8 //11
#define rst  PB7 //8
#define dc   PB6 //9
#define cs   PB5 //10

// Color definitions
#define RED             0xF800
#define DKRED           0x7000
#define WHITE           0xFFFF

#define PIC_SIZE_X (16)
#define PIC_SIZE_Y (16)

// Option 1: use any pins but a little slower
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);  
//Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);

void setup(void) {
  pinMode(7, OUTPUT); // for Vcc
  digitalWrite(7, HIGH);

  display.begin();

  const uint8_t apple_red[] PROGMEM = {
    0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0xF0,
    0x3A,0x5C,0x7C,0x3E,0x7F,0xEE,0x7F,0xF6,
    0x7F,0xF6,0x7F,0xF6,0x3F,0xFE,0x1F,0xFC,
    0x1F,0xFC,0x07,0xF8,0x01,0xE0,0x00,0x00,
  };
  const uint8_t apple_dkred[] PROGMEM = {
    0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,
    0x05,0xA0,0x03,0xC0,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x40,0x00,0x20,0x00,
    0x20,0x00,0x18,0x00,0x06,0x00,0x00,0x00,
  };

  display.fillScreen(DKRED);
  display.drawBitmap(0, 0, (uint8_t*)apple_red, PIC_SIZE_X, PIC_SIZE_Y,  RED,WHITE);
  display.drawBitmap(0, 0, (uint8_t*)apple_dkred, PIC_SIZE_X, PIC_SIZE_Y, DKRED);
}

void loop() {
}

スケッチは液晶をそのままボードに挿せるよう、
高速のSPIモード
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);
から低速のソフトウェアSPIモード
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);
にしてピン番号を変えただけです。

また今回はPlatformIOでビルドしています。
BluePillクローンでビルドを通すためにこちらの処理をしています。
また、必要なライブラリはPlatformIOのライブラリから
Adafruit_GFX
Adafruit_SSD1331
で検索すると出てくるのでポチッとインストールすればOKです。

IMG_8655.jpg

9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5