2018年3月6日 星期二

How to use Arduino MEGA 2560 SPI interface and 1.3 inch dot-matrix OLED display module with built-in English&Chinese Font IC


u8g2 is a very good and powerful library for dot-matrix display panels. Due to short program flash memory of Arduino UNO/MEAG 2560, it can not dislpay Chinese font, either BIG5 code (Traditional Chinese character) or GB2312 code (Simplified Chinese character). Hence I adopt 1.3 inch OLED module with built-in Chinese/English font, and use u8g2 drawXBM function to display Chinese(16x16)/English (8x16) character.

There are some interfaces (8bit parallel/I2C/SPI) used in OLED display panels  in the market, the reason I chose SPI is because less pins than 8bit parallel bus and much higher speed than I2C. Access speed between CPU and OLED driver such as SSH1106 (the one I used) and CPU to Chinese/English   Font IC is very important due to there are many data to send and to receive between them and I don't want to see display lag issue in my design.

I use the panel below
https://seller.shopee.tw/portal/product/928548884
http://goods.ruten.com.tw/item/show?21808691338964.

Wire connections as below

Arduino MEGA 2560   1.3" OLED module
46                                  CS2 (chip select for font IC)              
47                                
48                                  CS1    (chip select for SH1106)              
49                                  DC     (Data/Command pin)                    
50 MISO                       FSO    (font IC bitmap data output)                  
51 MOSI                       MOSI (CPU data to font IC or SH1106)    
52 SCK                          CLK                                                
53 SS                              ------                                                
3.3V                               3.3V                                                   
GND                              GND                                                

Demo program show a test string with both Chinese&English characters on the OLED display module below.

uint8_t   TeststringGB231216by16[] = {'H','i','!',0xDC,0xBF,0xCD,0xA5,0xCA,0xF7,0xB9,0xA4,0xD7,0xF7,0xCA,0xD2,0};  // 芸(DCBF),"Hi!芸庭樹工作室"



part number for the font IC is GT20L16S1Y and data sheet below  (http://www.genitop.com/admin/upload/20150511105751675.pdf)

after received Chinese/English font data from font IC, bit map data conversions (subroutine convert8by16FontBitMapforU8G2XBM and convert16by16FontBitMapforU8G2XBM) are  required due to different bit map structure between u8g2.drawXBM and the font IC.

demo program as below

void convert8by16FontBitMapforU8G2XBM(uint8_t *pfont)
{
  uint8_t i,j,k,*pfont1,tempbuffer[16], *pfont2, *pfontbase;
  uint8_t data,mask;

  pfont1 = pfont;     // the last byte for Chinese font bitmap
  pfont2 = &tempbuffer[0];
  for(i=0;i<16;i++)
  {
    *pfont2++ = *pfont1++;
    //pfont2++; pfont1++;
  }
  //printFontToSerial(16);

  pfont2 = pfont;
  pfontbase = &tempbuffer[0];
  for(k=0;k<2;k++,pfontbase+=8) {
    //Serial.print("k="); Serial.print(k,HEX); Serial.println(' ');
    mask=0x01;
    for(i=0; i<8; i++,mask<<=1) {
      //Serial.print("M"); Serial.print(mask,HEX); Serial.print(',');
      for(j=0,data=0,pfont1=pfontbase; j<8; j++) {
        data >>= 1;
        if (*pfont1++ & mask)
          data |= 0x80; //0x8000;  
        //Serial.print(data,HEX); Serial.print(' ');
      }
      *pfont2++ = data;
      //Serial.print(",data="); Serial.print(data,HEX); Serial.println(' ');
    }
  }
  //printFontToSerial(16);
}

void convert16by16FontBitMapforU8G2XBM(uint8_t *pfont)
{
  uint8_t i,j,k,*pfont1,tempbuffer[32], *pfont2, *pfontbase, mask;
  uint16_t data;

  pfont1 = pfont;     // the last byte for Chinese font bitmap
  pfont2 = &tempbuffer[0];
  for(i=0;i<32;i++) {
    *pfont2++ = *pfont1++;
  }

  pfont2 = pfont;
  pfontbase = &tempbuffer[0];
  for(k=0; k<2; k++,pfontbase+=16) {
    for(i=0,mask=0x1,pfont1=pfontbase; i<8; i++,mask<<=1) {
      for(j=0,data=0,pfont1=pfontbase; j<16; j++) {    
          data >>= 1;
          if (*pfont1++ & mask)
            data |= 0x8000;  
          //Serial.print(data,HEX); Serial.print(' ');      
      }
      *pfont2 = data & 0xff;
      *(pfont2+1) = ((data & 0xff00)>>8);
      pfont2 += 2;
      //Serial.print(",data="); Serial.print(data,HEX); Serial.println(' ');
    }
  }
}

void drawFontIC(uint8_t x, uint8_t y, uint8_t *pCodeString)
{
  //uint8_t *ptr;
  //ptr = pCodeString;
  //while(*ptr) {
  //  Serial.print(*ptr++,HEX); Serial.print(' ');
  //while(1);
  //}

  while(*pCodeString) {
      fontIC.getFontBitMap(pCodeString,&FontBuffer[0]);
      //printFontToSerial(32);
      if (*pCodeString > 127) {
        convert16by16FontBitMapforU8G2XBM(&FontBuffer[0]);
        //printFontToSerial(32);    
        u8g2.drawXBM(x,y,16,16,&FontBuffer[0]);
        pCodeString += 2;
        x += 16;
      } else {
         convert8by16FontBitMapforU8G2XBM(&FontBuffer[0]);
         u8g2.drawXBM(x,y,8,16,&FontBuffer[0]);
         pCodeString++;
         x += 8;
      }  
  }
}

void setup(void) {
  Serial.begin(115200);
  pinMode(SPI_CS2,OUTPUT);
  digitalWrite(SPI_CS2,HIGH);
  pinMode(SPI_FSO,INPUT);
  u8g2.begin();
}

void loop(void) {

  u8g2.firstPage();
  do {
 
    u8g2.drawFrame(0,0,127,63);            //  U8G2::drawBox(u8g2_uint_t x, u8g2_uint_t y,   u8g2_uint_t w, u8g2_uint_t h)
 
    drawFontIC(3,3,&TeststringGB231216by16[0]);

    u8g2.setFont(u8g2_font_t0_11_tf);
    u8g2.drawStr(20,32,"Font IC Test OK");

    u8g2.drawTriangle(20,38,5,56,35,56);
    u8g2.drawCircle(64,48,10,U8G2_DRAW_ALL);   // void U8G2:drawCircle(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t opt = U8G_DRAW_ALL)
    u8g2.drawFilledEllipse(100,50,15,5,U8G2_DRAW_ALL);
    Serial.print(F("\r\n\r\n\r\n"));
  } while ( u8g2.nextPage() );
  delay(2000);
  while(1);
}

沒有留言:

張貼留言