bitmap display on 130*130 SSD1283A TFT display

Hi all,

Working with an SSD1283A 130*130 TFT display the graphical part is no problem: text, lines, circles, squares, triangles and the like. This is done using the <LCDWIKI_SPI.h> library. An example can be seen atmy arduino projects at thesolaruniverse.wordpress.com.

The next step in this adventure is to display pictures. I am intentionally powering the TFT with an Arduino Nano, so limitations apply.

I prepared with LCD-image-converter a 90x90 pixel 8-bit monochrome bitmap array. The sketch places the c array in pgmspace, and the display should display the image. However, instead of a 90x90 Donald Duck the display produces 90x90 pixel gibberish.

the constructor for my display is:
LCDWIKI_SPI mylcd(SSD1283A,10,9,8,A3); // hardware spi,cs,cd,reset

the constructor that attempts to print to TFT is:
mylcd.Draw_Bit_Map (5, 5, 100, 100, duck_90_bitmap[1200],1);

Here is the complete sketch:

// Nano_90x90_TFT_duck_90x90_progmem_nn

   #include <LCDWIKI_GUI.h> //Core graphics library
   #include <LCDWIKI_SPI.h> //Hardware-specific library
   #include <avr/pgmspace.h>

   #define MAGENTA 0xF81F

   LCDWIKI_SPI mylcd(SSD1283A,10,9,8,A3); // hardware spi,cs,cd,reset

    const uint8_t duck_90_bitmap[1200] PROGMEM = {
      
    0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 

... and  alot hex stuff .... left out to save space ...
    
    0x44, 0x09, 0x00, 0x94, 0xa1, 0xdb, 0x6e, 0xde, 0x7f, 0xff, 0xff, 0xc0
};

void setup() {

   Serial.begin (9600);
   mylcd.Init_LCD();                    
   mylcd.Fill_Screen (MAGENTA);
  
   Serial.println ("in setup starting to draw bitmap");   
   mylcd.Draw_Bit_Map (5, 5, 100, 100, duck_90_bitmap[1200],1);   // draw the bitmap on the TFT display
     
}

void loop() 
{    
  
}

I've succeeded in producting correct 90x90 bitmap display of this array on a ST7789 1240X240 display driven by the <Arduino_ST7789.h> library, but the SSD1283A is a different baby!
Sketch is attached (would exceed 9,000 characters in message limit)
Help! Any suggestions?

Nano_130x130_TFT_duck_90x90_progmem_001_forum.ino (32.1 KB)

OOPS: correct TheSolaruniverse url is: Connecting a 130×130 pixel TFT display – SSD1283A controller to an Arduino – thesolaruniverse

-photoncatcher

LCDWIKI_GUI.h

 void Draw_Bit_Map(int16_t x, int16_t y, int16_t sx, int16_t sy, const uint16_t *data, int16_t scale);

This is designed for colour pixel arrays in PROGMEM

You want a monochrome bitmap array like Adafruit_GFX e.g.

      drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w,
                 int16_t h, uint16_t color),
      drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w,
                 int16_t h, uint16_t color, uint16_t bg),

LCDWIKI constructed its methods from a Scrabble bag. The methods mostly mimic UTFT class with a spelling breakdown.

They do not support the more intuitive Adafruit_GFX style. But it is simple enough to write your own drawBitmap() function using the LCDWIKI methods. e.g.

// Nano_90x90_TFT_duck_90x90_progmem_nn

#include <LCDWIKI_GUI.h> //Core graphics library
#include <LCDWIKI_SPI.h> //Hardware-specific library
#include <avr/pgmspace.h>

#define MAGENTA 0xF81F
#define WHITE   0xFFFF
#define BLACK   0x0000

LCDWIKI_SPI mylcd(SSD1283A, 10, 9, 8, A3); // hardware spi,cs,cd,reset

#include "duck_bitmap.h"

void showbgd(int x, int y, const uint8_t *bmp, int w, int h, uint16_t color, uint16_t bg, uint8_t pad = 7)
{
    int yy, xx;
    uint8_t first = 1, RVS = pad & 0x80;
    uint16_t pixel;
    pad &= 31;
    uint16_t wid = (w + pad) & ~pad;                    //bits per row
    //tft.setAddrWindow(x, y, x + w - 1, y + h - 1); //
    mylcd.Set_Addr_Window(x, y, x + w - 1, y + h - 1); //
    for (yy = 0; yy < h; yy++) {
        uint32_t ofs = (RVS ? (h - yy - 1) : yy) * wid; //bit offset
        const uint8_t *p = bmp + (ofs >> 3);            //flash address
        uint8_t mask = 0x80 >> (ofs & 7);               //bit mask
        uint8_t c = pgm_read_byte(p++);
        for (xx = 0; xx < w; xx++) {
            if (mask == 0) {
                c = pgm_read_byte(p++);
                mask = 0x80;
            }
            pixel = (c & mask) ? color : bg;
            //tft.pushColors(&pixel, 1, first);
            mylcd.Push_Any_Color(&pixel, 1, first, 0);
            first = 0;
            mask >>= 1;
        }
    }
    //tft.setAddrWindow(0, 0, tft.width() - 1, tft.height() - 1);
    mylcd.Set_Addr_Window(0, 0, mylcd.Get_Width() - 1, mylcd.Get_Height() - 1);
}

void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color, uint16_t bg)
{
    showbgd(x, y, bitmap, w, h, color, bg, 7);
}

void setup()
{

    Serial.begin (9600);
    mylcd.Init_LCD();
    Serial.println ();
    Serial.println ("Hello! SSD1283A 130*130 Donald Duck 90x90 pix 8bit image");
    Serial.println ("on Arduino Uno - Nano");


    Serial.println ("in setup print screen 0x07E0");
    mylcd.Fill_Screen (MAGENTA);

    Serial.println ("in setup starting to draw bitmap");
    //mylcd.Draw_Bit_Map (5, 5, 100, 100, duck_90_bitmap[1200],1);   // draw the bitmap on the TFT display
    drawBitmap(5, 5, duck_90_bitmap, 90, 90, WHITE, BLACK);   // draw the bitmap on the TFT display

}

void loop()
{

}

I put the bitmap array into a local sketch tab i.e. "duck_bitmap.h"
Note that the bitmap array size is actually:

const uint8_t duck_90_bitmap[(96/8)*90] PROGMEM = {

The array is padded so that each row appears on a byte boundary. Hence it is 12 bytes per row (96/8) because 90/8 = 11.25

David.

hi David, thanks for paying so much of your attention to this obnoxious display.
I saved the duck_90.c output file as duck_bitmap.h in the library folder containing <LCDWIKI_SPI.h>
and ran your sketch with the "own drawBitmap() function using the LCDWIKI methods.'

Then compiled. Still gibberish as you can see, however with som pattern. i get an impression of some interlacing (?) (also still gibberish when the duck bitmap is in progmem)

The 90x90 duck should look like this!


regards, photoncatcher

Hi David,

After a little tinkering with the sketch, with your suggestions implemented, it is now running as expected!

here is the picture:

iI always gives a sea of satisfaction when things work (blood sweat and tears for photoncatcher!). Anyway, a great experience, and thanks for your help. Next challenge: let's see whether I can produce a 30x30 color Donald Duck.
Many thanks, photoncatcher

What did you do wrong? (or right)

I strongly suggest that you put local bitmaps into local sketch tabs.
Only put global stuff into library folder. e.g. an important Font that you intend to use in many sketches.

I also suggest that you use an Adafruit_GFX style library.
I am gobsmacked by the LCDWIKI choice of badly-spelled UTFT style class methods.

Regarding scaling bitmaps. Use a PC program like IrfanView with JPG, PNG, BMP files.
Then use an online program to create the Adafruit-style monochrome bitmap array.

David.

Hi David,

What did you do wrong? (or right)

Actually I don't know. First I copy-pasted your snippet into my existing sketch and uploaded --> gibberish. Then I straightened out the sketch and threw all unneccessary stuff out .... then it worked!

I strongly suggest that you put local bitmaps into local sketch tabs.

Does the compiler support paths ?

I also suggest that you use an Adafruit_GFX style library.
I am gobsmacked by the LCDWIKI choice of badly-spelled UTFT style class methods.

This TFT display at hand has a SSD1283A controller and as far as I know this controller is not supported by Adafruit_GFX. I found LCDWIKI_GUI and got my display working nothwithstanding the gobsmacking badly spelled instructions . I am aware of Jean-Marc Zingg's <SSD1283A.h> library but haven't tried that one yet. Reason is that I am not so happy with the 130130 SSD1283A TFT. The 240240 ST7789 TFT displays perform so much better - see picture below - that I bought a few more of these jewels. They are 3.3V and pair perfectly with the NodeMCU ESP8266 and Wemos D1 mini.

Hi David,

Regarding scaling bitmaps. Use a PC program like IrfanView with JPG, PNG, BMP files.
Then use an online program to create the Adafruit-style monochrome bitmap array.

The pictures above is a basic image of both displays lined up, nicely next to each other. The 130130 SSD1283A display is running a '120120 pixel duck image here at 5V power supply - and stil dim compared with the 240240 TFT. I had to superimpose a 120120 pixel 'duck' bitmap onto the spot where it is on the 240*240 TFT display (but way too light - beyond dynamic range of my poor camera).

Superimposition and labeling was done here in XaraX, basically a vector based dawing program, but with wonderful and very powerful tools to handle bitmaps - and you can run Photoshop in XaraX as a kind of plugin. I frequently use IrfanView for fast viewing large numbers of images and for batch format conversion. For specialist image analysis, there is good old ImageJ, currently Fiji. The Gimp (and Photoshop under Wine) are my main tools on my fast Linux machine - my favorite computer. All Arduino compilation is done on the Linux machine. Gobsmackingly fast !

Once more: thanks for all your assistance and suggestions.

Does the compiler support paths ?

Yes. But you normally use wedges for system includes and quotes for local includes e.g. a local sketch tab.
The Arduino "INO" translation will search library directories for quote-style includes.
The regular C++ language would expect you to specify any non-system directories

You can use an absolute path or a relative path.

I strongly recommend that you use local sketch tabs for local files.

I have not tried Jean-Marc's SSD1283 library. If it is Adafruit_GFX style, it would be a good choice.
And you would use the same intuitive methods for SSD1283 as for ST7789

The SSD1283 is transreflective and only needs a backlight in the dark.
You can adjust GAMMAs on both displays.
Not so easy to adjust backlight on ST7789. You need PWM on the BLK pin.
Likewise with SSD1283 on the LED pin.

The SSD1283 is ok with 5V VCC and 5V GPIO. It contains regulator and level shifter buffer.
The ST7789 is strictly 3.3V only. There is no regulator. No buffer. No CS pin. So you can't even share the SPI bus.

David.

Thanks! I learned a lot!