Continuing with the previous post, I’m sharing the black and white converter for the Adafruit 1.44″ TFT. This program converts any .PNG image into a constant char array that can be included and shown directly on screen. This program and accompanying code shows monochrome bitmaps (custom foreground and background colors) on the ST7735R driver. It was tested on a green tab TFT and is substantially much faster than the stock bitmap drawing routines.
As explained in the previous post, this screen wants data in a packed RGB 565 format. That means that each pixel requires 16 bits of information as shown below.
I followed a routine that follows the same approach as the color bitmap drawing, but with a small twist. I now only check a bit mask for a 1 in a packed array, and if its true I transmit the foreground color, else I send the background color. The address window is also only set once, so we have a high efficiency usage of the SPI port, yet we only use 1/16th of the space that the color version uses.
void Adafruit_ST7735::bitmapBW(int16_t x, int16_t y, const unsigned char *map, int16_t w, int16_t h,
int16_t foreground, int16_t background )
{
char dw, dh, xx, yy;
char fgA = foreground >> 8;
char fgB = foreground & 0xFF;
char bgA = background >> 8;
char bgB = background & 0xFF;
dw = w;
dh = h;
// rudimentary clipping (drawChar w/big text requires this)
// out of screen
if((x >= _width) || (y >= _height)) return;
if((x + w - 1) >= _width){ // positive clipping
dw = _width - x;
setAddrWindow(x, y, _width-1, y+h-1);
} else if((y + h - 1) >= _height){
dh = _height - y;
setAddrWindow(x, y, x+w-1, _height-1);
} else if( x < 0 ){ // negative clipping
setAddrWindow(0, y, x+w-1, y+h-1);
} else {
setAddrWindow(x, y, x+w-1, y+h-1);
}
_rs = 1;
_cs = 0;
for(yy=0; yy<dh; yy++) {
for(xx=0; xx<dw; xx++) { if( xx+x >= 0){
if( map[ (yy*w +xx)/8 ] & ( 1<<(xx%8) ) ){
spi_port.write( fgA );
spi_port.write( fgB );
} else {
spi_port.write( bgA );
spi_port.write( bgB );
}
}
}
}
_cs = 1;
}
I did some more clipping logic to allow negative x values as well, so you can do better GUIs that might require images to transition in and out of the screen.
In order to use this function, we need to have a byte array that fits a packed bit structure like this.
I made an application in DarkBasic that handles this and also does some animations while doing the conversion. This program will search for a file named “input.png” in the current directory and will output a file called “converted.txt”. For illustration purposes I used a black and white play icon, but note that color images can be used as well. If the luma compoment is below 128 it will be considered white, else it will be black.
The output of the program looks like this:
/**================================================+
* Auto generated image |
*+================================================*/
const unsigned char IMAGE[512]= {
0, 0, 0, 128, 3, 0, 0, 0,
0, 0, 0, 255, 255, 1, 0, 0,
0, 0, 224, 255, 255, 15, 0, 0,
0, 0, 248, 255, 255, 63, 0, 0,
0, 0, 254, 255, 255, 255, 0, 0,
0, 128, 255, 255, 255, 255, 3, 0,
0, 192, 255, 255, 255, 255, 7, 0,
0, 224, 255, 255, 255, 255, 15, 0,
0, 240, 255, 255, 255, 255, 31, 0,
0, 248, 255, 255, 255, 255, 127, 0,
0, 252, 255, 255, 255, 255, 127, 0,
0, 254, 255, 255, 255, 255, 255, 0,
...
};
After using the function outlined above, this is what shows on the screen. This particular image used red as the foreground and white as the background. The rest of the text is drawn with the standard font routines.
The converter can be found in these mirrors:
http://www.mediafire.com/download/aj8tx2lz2pn6uao/Image_Converter_Adafruit_BW.rar
The mbed library can be found here:
http://developer.mbed.org/users/AlfredoER/code/Adafruit_ST7735/
Happy drawing!