GLCD 128x64 - U8g2 Bitmap

Hi

I am using KS0108 based GLCD 128x64 with U8g2 library.

I need to display a bmp image and some text. The text portion is working fine but the image is not being displayed. Here is the code:

#include <Arduino.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

////////////////////////////////// D0,D1, D2, D3, D4, D5, D6, D7, EN, RS, CS1, CS2 /////////////////////////////////////////////////
U8G2_KS0108_128X64_1 u8g2(U8G2_R0,  4, 5,  6,  7,  8,  9, 10, 11,  3,  2,  A0,  A1, /*cs2=*/ U8X8_PIN_NONE, /* reset=*/  U8X8_PIN_NONE); 	// Set R/W to low!
//////////////////////////////////// RST = 5V, R/W = GND //////////////////////

const uint8_t Size1_2Width    = 64;
const uint8_t Size1_2Height   = 64;
static const unsigned char Size1_2bmp[] U8X8_PROGMEM  = {
  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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0xf0, 0xf0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x07, 0x87, 0xe3, 0xfb, 0xff, 0xff, 0x3f, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0xfc, 0xff, 0xff, 0x7f, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xf8, 0xfe, 0xff, 0xff, 0x3f, 0x07, 0x01, 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, 0xc0, 0xf0, 0xfe, 0xff, 0xff, 0x3f, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1f, 0x1f, 0x1f, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x0f, 0x01, 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, 0xc0, 0xf8, 0xfe, 0xff, 0xff, 0x3f, 0x07, 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, 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, 0x00, 0xe0, 0xfc, 0xff, 0xff, 0xff, 0x3f, 0x03, 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, 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, 0x00, 0x00, 0x00, 0x03, 0x07, 0x07, 0x03, 0x03, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

void setup() 
{
  u8g2.begin();
}

void loop() 
{
  u8g2.firstPage();
  do 
  {
    u8g2.setFont(u8g2_font_helvR08_tf);
    u8g2.drawStr( 15, 8, "SIZE");
    u8g2.drawStr( 68, 8, "LENGTH");
    u8g2.drawLine(0, 10, 127, 10);
    u8g2.drawStr( 20, 22, "1/2\"");
    u8g2.drawStr( 95, 22,"mm");
    u8g2.drawStr( 20, 32, "5/8\"");
    u8g2.drawStr( 95, 32,"mm");
    u8g2.drawStr( 20, 42, "3/4\"");
    u8g2.drawStr( 95, 42,"mm");
    u8g2.drawStr( 20, 52, "7/8\"");
    u8g2.drawStr( 95, 52,"mm");
    u8g2.drawStr( 29, 62, "1\"");
    u8g2.drawStr( 95, 62,"mm");
    u8g2.setFontMode(1);  /* activate transparent font mode */
    u8g2.setDrawColor(1); /* color 1 for the box */
    u8g2.drawBox(67, 12, 26, 12);
    u8g2.setFontMode(1);  /* activate transparent font mode */
    u8g2.setDrawColor(2); /* color 2 for the font */
  
    u8g2.drawStr( 70, 22, "61.8");
    u8g2.drawStr( 70, 32, "71.8");
    u8g2.drawStr( 70, 42, "81.8");
    u8g2.drawStr( 70, 52, "91.8");
    u8g2.drawStr( 70, 62, "97.8");

  } while ( u8g2.nextPage() );
  
  delay(3000);
  u8g2.clearDisplay();
  u8g2.setBitmapMode(false /* solid */);
  u8g2.drawBitmap(0, 0, Size1_2Width, Size1_2Height, Size1_2bmp);
  delay(2000);
}

Kindly guide me to make the sketch work.

You should put the bitmap through the firstPage, nextPage loop.
Then you should see the result.

david_prentice:
You should put the bitmap through the firstPage, nextPage loop.
Then you should see the result.

Frankly, I had that point in my mind but the delay() commands prevent displaying anything. How do I insert a delay between the text and the image?

By the way, this is just a test code. I was wondering how to do following steps:

a) void loop()
b Display some bmp image & text
c) DigitalRead a button
d) If button is HIGH
e ) clear display
f) display new text
g) Endif
h) EndLoop

Do I need another firstPage/nextPage loop for (f)?

You need a firstPage, nextPage to display anything with the 1, 2 paged constuctors.

I suspect that you are using a Uno which has 2048 bytes of SRAM.
If you are careful, you can use the F full buffer version of the constructor. (needs 1024 bytes)

With the F constructor you can update without redrawing everything.
i.e. use u8g2.sendBuffer() instead of firstPage, nextPage

Look at Oliver's u8g2 examples. And study the Wiki.

Some tips for saving SRAM:

  1. put image in PROGMEM (needs to be XBM format)
  2. put anonymous text in PROGMEM e.g. u8g2.print(F("message"))
  3. use drawXBMP() instead of drawXBM()
  4. unfortunately drawBitmap() can only be drawn from SRAM. There is no drawBitmapP()

David.

p.s. you can store Bitmap in Flash. And use a helper function to copy small sections to SRAM where you can use drawBitmap() to rebuild the whole image from the pieces.

Thanks David for the great tips.

I am using a Nano and have already completed my project successfully using 2 x PCF8574.

So you have connected the KS0108's 14 logic pins to two PCF8574. Should work but pretty slow.
There is a Nick Gammon library for a KS0108 with a MCP23017. Works but slow.
Or just dedicate a Nano to the regular KS0108. Works very fast.

Personally, I would choose a ST7920 and use SPI interface. Works fine. Not many pins used on the Arduino.

Or use a modern LCD or OLED that mostly have native SPI and I2C interfaces.
A regular transreflective LCD panel will use the least current. e.g. black on green-yellow background

David.

david_prentice:
So you have connected the KS0108's 14 logic pins to two PCF8574. Should work but pretty slow.
There is a Nick Gammon library for a KS0108 with a MCP23017. Works but slow.
Or just dedicate a Nano to the regular KS0108. Works very fast.

Personally, I would choose a ST7920 and use SPI interface. Works fine. Not many pins used on the Arduino.

Or use a modern LCD or OLED that mostly have native SPI and I2C interfaces.
A regular transreflective LCD panel will use the least current. e.g. black on green-yellow background

No, I have connected the KS0108 directly to Nano and used 2 PCF8574 I/O expansion modules for my buttons & switches.

Yes, next I would definitely choose ST7920. OLEDs are too small for my current project.

Thanks for the tip about trans-reflective LCD panel.