SSブログ

I2C OLED (SSD1306)に画像を出す。Wire版 [Arduino]

Wireライブラリー + delay() を使って一般的なArduinoでだいたい動くようにしました。

・ATtiny 412 (megaTinyCore)
・UNO R1 (ATmega328)
・UNO R4 MINIMA (RA4M1)
・RL78/G15 Fast Prototyping Board

で動くことを確認しました。
ATyiny202には 2269バイトとフラッシュメモリ 2kByteをオーバーしてしまい不可でした。

こんな感じで、、
ssd1306_r4_1.jpg
ブレッドボードなしでつないでみた。
ssd1306_r4_2.jpg

// tinyOLEDdemo - controlling an I²C OLED (SSD1306)
#include <Wire.h>

uint8_t const img_i[] = {   32,   32, // px
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x82, 0xee, 0xfe, 0xfe, 0xfc, 0xf8, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0,
  0xf8, 0x7e, 0xff, 0xff, 0xef, 0xc7, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x20, 0x20, 0x30, 0x10, 0x18, 0x1c, 0x0e, 0x0f, 0x07, 0x07, 0x03, 0x01, 0x01,
  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x1e, 0x3f, 0x7f, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
uint8_t const img_qr[] = {  23,   23, // px
  0xff, 0x01, 0x7d, 0x45, 0x45, 0x45, 0x7d, 0x01, 0xff, 0x2b, 0xcb, 0x71, 0xdf, 0x01, 0xff, 0x01,
  0x7d, 0x45, 0x45, 0x45, 0x7d, 0x01, 0xff, 0xff, 0x59, 0x55, 0x7d, 0x71, 0x49, 0x67, 0x55, 0xf9,
  0x3d, 0xc2, 0x8b, 0x57, 0x91, 0x3d, 0x77, 0xc9, 0x27, 0xb9, 0x93, 0x71, 0xf7, 0xff, 0xff, 0xc0,
  0xdf, 0xd1, 0xd1, 0xd1, 0xdf, 0xc0, 0xff, 0xc1, 0xf3, 0xfa, 0xcd, 0xd5, 0xc8, 0xc5, 0xea, 0xe6,
  0xe8, 0xd8, 0xcb, 0xec, 0xff
};

// ---- OLED Implementation ----------------------------------------------------

#define OLED_ADDR       0x3c             // OLED write address (Wire lib.:0x3c)
#define OLED_CMD_MODE   0x00             // set command mode
#define OLED_DAT_MODE   0x40             // set data mode

const uint8_t OLED_INIT_CMD[] = {        // OLED init settings
  0xA8, 0x3F,           // set multiplex (HEIGHT-1): 0x1F for 128x32, 0x3F for 128x64
  0x22, 0x00, 0x07,     // set min and max page                      
  0x20, 0x00,           // set horizontal memory addressing mode
  0xDA, 0x12,           // set COM pins hardware configuration to alternative
  0x8D, 0x14,           // enable charge pump
  0xAF                  // switch on OLED
};

void OLED_init(void) {                    // OLED init function
  Wire.begin();                           //   initialize I2C first
  Wire.beginTransmission(OLED_ADDR);      //   start transmission to OLED
  Wire.write(OLED_CMD_MODE);              //   set command mode
  for (uint8_t i=0; i<sizeof(OLED_INIT_CMD); i++) Wire.write(OLED_INIT_CMD[i]); // send the command bytes
  Wire.endTransmission();                 //   stop transmission
}

void OLED_cursor(uint8_t xpos, uint8_t ypos) {// OLED set the cursor
  Wire.beginTransmission(OLED_ADDR);      //   start transmission to OLED
  Wire.write(OLED_CMD_MODE);              //   set command mode
  Wire.write(xpos & 0x0F);                //   set low nibble of start column
  Wire.write(0x10 | (xpos >> 4));         //   set high nibble of start column
  Wire.write(0xB0 | (ypos & 0x07));       //   set start page
  Wire.endTransmission();                 //   stop transmission
}

void OLED_clear(uint8_t p) {              // OLED clear screen with pattern
  OLED_cursor(0, 0);                      //   set cursor at upper left corner
  for(uint8_t j=1024/16; j; j--) {
    Wire.beginTransmission(OLED_ADDR);    //   start transmission to OLED
    Wire.write(OLED_DAT_MODE);            //   set data mode
    for(uint8_t i=16; i; i--) Wire.write(p);// clear the screen with p
    Wire.endTransmission();               //   stop transmission
  }
}

void OLED_image(uint8_t xpos, uint8_t ypos, const uint8_t *d) {// OLED set image
  const uint8_t w=*d++, h=*d++;
  for(uint8_t y=0, i=0; y<(h+7)/8; y++) {
    OLED_cursor(xpos, ypos + y);          //   set the cursor
    for(uint8_t x=0; x<w; x++) {
      if( !i ) {
        Wire.beginTransmission(OLED_ADDR);//   start transmission to OLED
        Wire.write(OLED_DAT_MODE);        //   set data mode
      }
      Wire.write( *d++ );
      if( ++i==31 || w-x==1 ) {
        Wire.endTransmission();           //   stop transmission
        i=0;
      }
    }
  }
}

void OLED_image2x(uint8_t xpos, uint8_t ypos, const uint8_t *d) {// OLED set 2x image
  const uint8_t x2[]={ 0x0,0x3,0xc,0xf,0x30,0x33,0x3c,0x3f,0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff };
  const uint8_t w=*d++, h=*d++;
  for(uint8_t y=0, i=0; y<(h+3)/4; y++) {
    OLED_cursor(xpos, ypos + y);          //   set the cursor
    for(uint8_t x=0, t; x<w; x++) {
      if( !i ) {
        Wire.beginTransmission(OLED_ADDR);//   start transmission to OLED
        Wire.write(OLED_DAT_MODE);        //   set data mode
      }
      Wire.write( t = x2[ d[x+(y/2)*w] >> (y%2*4) & 0xf ] );
      Wire.write( t );
      if( (i+=2)>29 || w-x==1 ) {
        Wire.endTransmission();           //   stop transmission
        i=0;
      }
    }
  }
}

// ---- Main Function ----------------------------------------------------------

void setup() {
  delay(100);                             // add delay
  OLED_init();                            // setup I2C OLED
}

void loop() {
  OLED_clear(0x00);                       // clear screen with black
  OLED_image( 48, 2, img_i );
  delay(1000);
  OLED_image2x( 32, 0, img_i );
  delay(2000);
  OLED_clear(0xff);                       // clear screen with white
  OLED_image( 52, 2, img_qr );
  delay(1000);
  OLED_image2x( 40, 1, img_qr );
  delay(4000);
}


タグ:OLED SSD1306 I2C
nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。