Compress black & white pixel data on an 8-bit microprocessor - c

I need to compress the data of a 102x64 pixel black and white LCD screen using an 8-bit microprocessor. The data is coming in as a stream as shown below:
unsigned char data[8][102] =
{
{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, 0x38, 0x28, 0xfe, 0x82, 0xba, 0xba, 0x82, 0xba, 0xba, 0x82, 0xba, 0xba, 0x82, 0xfe, 0x00,
0x00, 0x38, 0x44, 0x44, 0x38, 0x00, 0x40, 0x4c, 0x50, 0x60, 0x00, 0x28, 0x00, 0x40, 0x7c, 0x00,
0x4c, 0x54, 0x54, 0x24, 0x00, 0x00 },
{0x00, 0x20, 0x20, 0x20, 0x3f, 0x3f, 0x20, 0x20, 0x20, 0x00, 0x6f, 0x6f, 0x00, 0x0f, 0x0f, 0x08,
0x08, 0x0f, 0x0f, 0x08, 0x08, 0x0f, 0x07, 0x00, 0x07, 0x0f, 0x0a, 0x0a, 0x0e, 0x06, 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, 0xc0, 0xcf, 0x0e, 0x0d, 0x0d, 0x0d, 0xce, 0xcf, 0x0d, 0xcd, 0xcd, 0x0d,
0x0c, 0xcf, 0xc0, 0x00, 0x00, 0xc0, 0xc2, 0x02, 0x83, 0xc0, 0x40, 0x40, 0x41, 0x42, 0x02, 0x02,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x01, 0x02, 0x02,
0x02, 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, 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, 0xff, 0x07, 0xfb, 0xfb, 0xfb, 0x07, 0xff, 0xff, 0xfb, 0xc7, 0x3f,
0xff, 0xff, 0x00, 0x84, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x04, 0x04, 0x00, 0x04, 0x0c, 0x14, 0x24,
0xc4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x30, 0x50, 0x90, 0x10, 0xfc, 0x10, 0x00, 0xf8, 0x04, 0x04,
0x04, 0xf8, 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, 0x3f, 0x3f, 0x20, 0x20, 0x30, 0x1f, 0x0f, 0x00, 0x01, 0x0b, 0x0a, 0x0a, 0x0f, 0x07, 0x00,
0x08, 0x3f, 0x3f, 0x08, 0x08, 0x00, 0x07, 0x0f, 0x0a, 0x0a, 0x0e, 0x06, 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, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0x81, 0x02, 0x02, 0x82, 0xc1, 0x40, 0x42, 0xc2, 0xc3, 0x00,
0x00, 0xc0, 0xc0, 0x40, 0x40, 0x00, 0x81, 0xc2, 0x42, 0x42, 0x41, 0x40, 0x02, 0x02, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x01, 0x00, 0x01, 0x02, 0x02, 0x02,
0x01, 0x00, 0x01, 0x02, 0x02, 0x02, 0x01, 0x00, 0x01, 0x02, 0x02, 0x02, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0x04, 0x04, 0xf8, 0x00, 0x04, 0x04, 0xfc, 0x04,
0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0xf8, 0x04, 0x04, 0x04, 0xf8, 0x00, 0x04, 0x04, 0xfc, 0x04,
0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x0c, 0x14, 0x24, 0xc4, 0x00, 0xf8, 0x04, 0x04, 0x04,
0xf8, 0x00, 0xf8, 0x04, 0x04, 0x04, 0xf8, 0x00, 0xf8, 0x04, 0x04, 0x04, 0xf8, 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, 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 }
};
However I'm unable to fit it completely into the microprocessor's RAM. I can only access it in 51 or less byte chunks.
For those who are curious - the data will produce the following image:
I like to transfer the data using a slow serial interface. It takes way too much time to send the data as is. My goal is to double the speed by shrinking the data by a factor of 2. A normal zip compression will achieve factor 2.46 by compressing the 816 byte to 332 bytes.
My first idea was to shrink the data by grouping the byte that do have the same value in a sequence. For instance the data {0x20, 0x20, 0x20, 0x3f, 0x3f, 0x20, 0x20, 0x20} will be compressed from 8 byte to 6 byte into this {{0x20, 0x03}, {0x3f, 0x02}, {0x20, 0x03}}.
Is there a method that works better for black & white pixel data and the limited recourses that a 8-bit microprocessor provides?

Fax machines use a combination of Huffman compression for lines, and then the following few lines only encode the differences from the last complete line.
It's the same principle as video compression: you compress one full frame, and then compress the differences for the next few frames (that's not 100% accurate, of course).
It should help the compression, but the code becomes a bit more complex.
I'd start with Huffman compression, as the image is definitely not random and should compress nicely. I don't think fax machines have a huge amount of memory so it might be possible to squeeze it in.

I don't know much about compression, but for something that's even more effective than RLE, specifically designed for a LCD, I'd perhaps consider something like this (inventing this algorithm as I write) :
{tag, x coord, y coord, data, data, data, ..., tag, x coord, ... and so on.
This is based on the idea that everything on the LCD is blank by default, and you just fill in the data. So it removes the need of storing a lot of 0x00. Instead, the value 0x00 can be used as a tag to describe where a new data segment begins and ends.
It would look like this:
uint8_t data[N] = {0x00, 0x05, 0x01, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0xAA, 0xBB, 0xCC };
This will print the data FFFF at location (5,1) to (6,1) on the LCD, and then the data AABBCC at location (1,2) to (3,2). A wrap-around at end of line could easily be implemented. 0x00 may appear as one of the coordinates but never as data.

I created a test using the RLE method (which was really easy to implement) and compressed a similar image from 816 to 446 byte (factor 1.82) - which is more than I expected from such a simple method.

If you consider a huffman compression you can try a pre-processing like delta code or a move-to-the-front of the data. A delta code records the difference from the next byte and a mtf swaps the data using a dictionary. It can improve the compression rate of a statistial compressor. If a huffman is to expensive you may look into a golomb code. Mtf is used in bzip2 before a BWT transformation.

Related

Invalid start of buffer (garbage pixel on LCD) ST7565

This is my first post on stackoverflow, and please be kind :). Ok i have problem like here (garbage pixel on LCD, image of the letters is mirrored.) https://github.com/olikraus/u8g2/issues/1187 My display have driver st7565, and this is my library
#include <stdlib.h>
#include <stdint.h>
#include "stm32f1xx_hal.h"
#include "ST7565.h"
#include <string.h>
#include "spi.h"
#include "font.h"
#define ST7565_STARTBYTES 0
extern SPI_HandleTypeDef hspi2;
//extern void DelaymS(vu32 nTime);
//extern void DelayuS(vu32 nCount);
uint8_t is_reversed = 0;
// a handy reference to where the pages are on the screen
//const uint8_t pagemap[] = { 3, 2, 1, 0, 7, 6, 5, 4 };
const uint8_t pagemap[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
// a 5x7 font table
extern const uint8_t font[];
int pData;
// the memory buffer for the LCD
uint8_t st7565_buffer[1024] = {
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, 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, 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, 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, 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, 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, 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, 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, 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};
// reduces how much is refreshed, which speeds it up!
// originally derived from Steve Evans/JCW's mod but cleaned up and
// optimized
#define enablePartialUpdate
#ifdef enablePartialUpdate
static uint8_t xUpdateMin, xUpdateMax, yUpdateMin, yUpdateMax;
#endif
static void ST7565_updateBoundingBox(uint8_t xmin, uint8_t ymin, uint8_t xmax, uint8_t ymax) {
#ifdef enablePartialUpdate
if (xmin < xUpdateMin) xUpdateMin = xmin;
if (xmax > xUpdateMax) xUpdateMax = xmax;
if (ymin < yUpdateMin) yUpdateMin = ymin;
if (ymax > yUpdateMax) yUpdateMax = ymax;
#endif
}
void ST7565_drawbitmap(uint8_t x, uint8_t y, const uint8_t *bitmap, uint8_t w, uint8_t h, uint8_t color) {
uint8_t i, j;
for (j=0; j<h; j++) {
for (i=0; i<w; i++ ) {
if (bitmap[i + (j/8) * w] & (1<<(j%8))) {
ST7565_my_setpixel(x+i, y+j, color);
}
}
}
ST7565_updateBoundingBox(x, y, x+w, y+h);
}
void ST7565_drawstring(uint8_t x, uint8_t line, char *c) {
while (c[0] != 0) {
ST7565_drawchar(x, line, c[0]);
c++;
x += 6; // 6 pixels wide
if (x + 6 >= LCDWIDTH) {
x = 0; // ran out of this line
line++;
}
if (line >= (LCDHEIGHT/8))
return; // ran out of space :(
}
}
void ST7565_drawstring_P(uint8_t x, uint8_t line, const char *str) {
char c;
while (1) {
c = *str++;
if (! c)
return;
ST7565_drawchar(x, line, c);
x += 6; // 6 pixels wide
if (x + 6 >= LCDWIDTH) {
x = 0; // ran out of this line
line++;
}
if (line >= (LCDHEIGHT/8))
return; // ran out of space :(
}
}
void ST7565_drawchar(uint8_t x, uint8_t line, char c) {
uint8_t i;
for (i =0; i<5; i++ ) {
st7565_buffer[x + (line*128) ] = font[((unsigned char)c * 5) + i];
x++;
}
ST7565_updateBoundingBox(x-5, line*8, x-1, line*8 + 8);
}
// bresenham's algorithm - thx wikpedia
void ST7565_drawline(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1,
uint8_t color) {
uint8_t steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) {
swap(x0, y0);
swap(x1, y1);
}
if (x0 > x1) {
swap(x0, x1);
swap(y0, y1);
}
// much faster to put the test here, since we've already sorted the points
ST7565_updateBoundingBox(x0, y0, x1, y1);
uint8_t dx, dy;
dx = x1 - x0;
dy = abs(y1 - y0);
int8_t err = dx / 2;
int8_t ystep;
if (y0 < y1) {
ystep = 1;
} else {
ystep = -1;}
for (; x0<=x1; x0++) {
if (steep) {
ST7565_my_setpixel(y0, x0, color);
} else {
ST7565_my_setpixel(x0, y0, color);
}
err -= dy;
if (err < 0) {
y0 += ystep;
err += dx;
}
}
}
// filled rectangle
void ST7565_fillrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color) {
uint8_t i, j;
// stupidest version - just pixels - but fast with internal buffer!
for (i=x; i<x+w; i++) {
for (j=y; j<y+h; j++) {
ST7565_my_setpixel(i, j, color);
}
}
ST7565_updateBoundingBox(x, y, x+w, y+h);
}
// draw a rectangle
void ST7565_drawrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color) {
uint8_t i;
// stupidest version - just pixels - but fast with internal buffer!
for (i=x; i<x+w; i++) {
ST7565_my_setpixel(i, y, color);
ST7565_my_setpixel(i, y+h-1, color);
}
for (i=y; i<y+h; i++) {
ST7565_my_setpixel(x, i, color);
ST7565_my_setpixel(x+w-1, i, color);
}
ST7565_updateBoundingBox(x, y, x+w, y+h);
}
// draw a circle outline
void ST7565_drawcircle(uint8_t x0, uint8_t y0, uint8_t r, uint8_t color) {
ST7565_updateBoundingBox(x0-r, y0-r, x0+r, y0+r);
int8_t f = 1 - r;
int8_t ddF_x = 1;
int8_t ddF_y = -2 * r;
int8_t x = 0;
int8_t y = r;
ST7565_my_setpixel(x0, y0+r, color);
ST7565_my_setpixel(x0, y0-r, color);
ST7565_my_setpixel(x0+r, y0, color);
ST7565_my_setpixel(x0-r, y0, color);
while (x<y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
ST7565_my_setpixel(x0 + x, y0 + y, color);
ST7565_my_setpixel(x0 - x, y0 + y, color);
ST7565_my_setpixel(x0 + x, y0 - y, color);
ST7565_my_setpixel(x0 - x, y0 - y, color);
ST7565_my_setpixel(x0 + y, y0 + x, color);
ST7565_my_setpixel(x0 - y, y0 + x, color);
ST7565_my_setpixel(x0 + y, y0 - x, color);
ST7565_my_setpixel(x0 - y, y0 - x, color);
}
}
void ST7565_fillcircle(uint8_t x0, uint8_t y0, uint8_t r, uint8_t color) {
ST7565_updateBoundingBox(x0-r, y0-r, x0+r, y0+r);
int8_t f = 1 - r;
int8_t ddF_x = 1;
int8_t ddF_y = -2 * r;
int8_t x = 0;
int8_t y = r;
uint8_t i;
for (i=y0-r; i<=y0+r; i++) {
ST7565_my_setpixel(x0, i, color);
}
while (x<y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
for (i=y0-y; i<=y0+y; i++) {
ST7565_my_setpixel(x0+x, i, color);
ST7565_my_setpixel(x0-x, i, color);
}
for (i=y0-x; i<=y0+x; i++) {
ST7565_my_setpixel(x0+y, i, color);
ST7565_my_setpixel(x0-y, i, color);
}
}
}
void ST7565_my_setpixel(uint8_t x, uint8_t y, uint8_t color) {
if ((x >= LCDWIDTH) || (y >= LCDHEIGHT))
return;
// x is which column
if (color)
st7565_buffer[x+ (y/8)*128] |= (1<<(7-(y%8)));
else
st7565_buffer[x+ (y/8)*128] &= ~(1<<(7-(y%8)));
}
// the most basic function, set a single pixel
void ST7565_setpixel(uint8_t x, uint8_t y, uint8_t color) {
if ((x >= LCDWIDTH) || (y >= LCDHEIGHT))
return;
// x is which column
if (color)
st7565_buffer[x+ (y/8)*128] |= (1<<(7-(y%8)));
else
st7565_buffer[x+ (y/8)*128] &= ~(1<<(7-(y%8)));
ST7565_updateBoundingBox(x,y,x,y);
}
// the most basic function, get a single pixel
uint8_t ST7565_getpixel(uint8_t x, uint8_t y) {
if ((x >= LCDWIDTH) || (y >= LCDHEIGHT))
return 0;
return (st7565_buffer[x+ (y/8)*128] >> (7-(y%8))) & 0x1;
}
void ST7565_begin(uint8_t contrast) {
ST7565_st7565_init();
ST7565_st7565_command(CMD_DISPLAY_ON);
ST7565_st7565_command(CMD_SET_ALLPTS_NORMAL);
ST7565_st7565_set_brightness(contrast);
}
void ST7565_st7565_init(void) {
// toggle RST low to reset; CS is low so it'll listen to us
// if (cs > 0)
// digitalWrite(cs, LOW);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET); // CS LOW
// digitalWrite(rst, LOW);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET); // RST LOW 0.5sec
// wait 0.5sec
HAL_Delay(500);
// digitalWrite(rst, HIGH);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET); // RST HIGH
// LCD bias select
ST7565_st7565_command(CMD_SET_BIAS_7);
// ADC select
ST7565_st7565_command(CMD_SET_ADC_NORMAL);
// SHL select
ST7565_st7565_command(CMD_SET_COM_NORMAL);
// Initial display line
ST7565_st7565_command(CMD_SET_DISP_START_LINE);
// turn on voltage converter (VC=1, VR=0, VF=0)
ST7565_st7565_command(CMD_SET_POWER_CONTROL | 0x4);
// wait for 50% rising
HAL_Delay(50);
// turn on voltage regulator (VC=1, VR=1, VF=0)
ST7565_st7565_command(CMD_SET_POWER_CONTROL | 0x6);
// wait >=50ms
HAL_Delay(50);
// turn on voltage follower (VC=1, VR=1, VF=1)
ST7565_st7565_command(CMD_SET_POWER_CONTROL | 0x7);
// wait
HAL_Delay(10);
// set lcd operating voltage (regulator resistor, ref voltage resistor)
ST7565_st7565_command(CMD_SET_RESISTOR_RATIO | 0x6);
// initial display line
// set page address
// set column address
// write display data
// set up a bounding box for screen updates
ST7565_updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1);
}
inline void ST7565_spiwrite(uint8_t c) {
//shiftOut(sid, sclk, MSBFIRST, c);
//while (SPI_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET);
//SPI_SendData(SPI2, c);
HAL_SPI_Transmit(&hspi2, &c, 1, 500);
}
void ST7565_st7565_command(uint8_t c) {
// digitalWrite(a0, LOW);
// GPIO_ResetBits(GPIOA, GPIO_Pin_4);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
ST7565_spiwrite(c);
}
void ST7565_st7565_data(uint8_t c) {
// digitalWrite(a0, HIGH);
// GPIO_SetBits(GPIOB, GPIO_Pin_11);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
ST7565_spiwrite(c);
}
void ST7565_st7565_set_brightness(uint8_t val) {
ST7565_st7565_command(CMD_SET_VOLUME_FIRST);
ST7565_st7565_command(CMD_SET_VOLUME_SECOND | (val & 0x3f));
}
void ST7565_display(void) {
uint8_t col, maxcol, p;
/*
Serial.print("Refresh ("); Serial.print(xUpdateMin, DEC);
Serial.print(", "); Serial.print(xUpdateMax, DEC);
Serial.print(","); Serial.print(yUpdateMin, DEC);
Serial.print(", "); Serial.print(yUpdateMax, DEC); Serial.println(")");
*/
for(p = 0; p < 8; p++) {
/*
putstring("new page! ");
uart_putw_dec(p);
putstring_nl("");
*/
#ifdef enablePartialUpdate
// check if this page is part of update
if ( yUpdateMin >= ((p+1)*8) ) {
continue; // nope, skip it!
}
if (yUpdateMax < p*8) {
break;
}
#endif
HAL_Delay(1);
ST7565_st7565_command(CMD_SET_PAGE | pagemap[p]);
HAL_Delay(1);
#ifdef enablePartialUpdate
col = xUpdateMin;
maxcol = xUpdateMax;
#else
// start at the beginning of the row
col = 0;
maxcol = LCDWIDTH;
#endif
ST7565_st7565_command(CMD_SET_COLUMN_LOWER | ((col+ST7565_STARTBYTES) & 0xf));
HAL_Delay(1);
ST7565_st7565_command(CMD_SET_COLUMN_UPPER | (((col+ST7565_STARTBYTES) >> 4) & 0x0F));
HAL_Delay(1);
ST7565_st7565_command(CMD_RMW);
HAL_Delay(1);
for(; col < maxcol; col++) {
//uart_putw_dec(col);
//uart_putchar(' ');
ST7565_st7565_data(st7565_buffer[(128*p)+col]);
//DelayuS(10);
}
}
#ifdef enablePartialUpdate
xUpdateMin = LCDWIDTH;// - 1;
xUpdateMax = 0;
yUpdateMin = LCDHEIGHT;//-1;
yUpdateMax = 0;
#endif
}
// clear everything
void ST7565_clear(void) {
memset(st7565_buffer, 0, 1024);
ST7565_updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1);
}
// this doesnt touch the buffer, just clears the display RAM - might be handy
void ST7565_clear_display(void) {
uint8_t p, c;
for(p = 0; p < 8; p++) {
/*
put
("new page! ");
uart_putw_dec(p);
putstring_nl("");
*/
ST7565_st7565_command(CMD_SET_PAGE | p);
for(c = 0; c < 128; c++) {
//uart_putw_dec(c);
//uart_putchar(' ');
ST7565_st7565_command(CMD_SET_COLUMN_LOWER | (c & 0xf));
ST7565_st7565_command(CMD_SET_COLUMN_UPPER | ((c >> 4) & 0xf));
//DelayuS(10);
ST7565_st7565_data(0x0);
}
}
}
(I'm not an experienced programmer)
I tried to find answers in the forums, and i found it https://github.com/olikraus/u8g2/issues/1187.
I cannot adapt the solution to my library. The problem as above matches my 100%

Can I initialize string with NULLs in C

I have an 128x64px display. Current picture on display is saved in
uint8_t bufferOLED[(HEIGHT * WIDTH / 8)+1]; // uint8_t bufferOLED[1025];
If I load bufferOLED with strcpy and print to display everything works fine.
Now I want to initialize bufferOLED with some logo that will show up when booting application.
uint8_t bufferOLED[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //0
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //1
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //2
...
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, //49
0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, //50
...
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //100
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //101
0x00, 0x00, 0x00, 0x00 //102
}
Logo prints OK, but after I load bufferOLED with different content and print to display, image on display gets corrupted.
When writing to display I'm just sending bufferOLED with some commands to OLED:
for(int i=0; i<1024; i+=16) twiPrint(OLED, 0x40, bufferOLED+i, 16); //twiPrint(uint8_t twiAddress, uint8_t twiCommand, uint8_t *twiTransmitData, uint8_t twiTransmitDataLen)
I know that NULL character is used for terminating string. So is initialization with mix of NULL and not NULL characters allowed?

Arduino Pro Mini Splash Screen

I want to build this Altimeter: https://www.youtube.com/watch?v=mMiMNTv25Bw. While I was waiting for the parts to arrive, I started looking over the code. I have a Splash.c file.
This is the code in the file:
*
// Splash.c
// Font type : Splash Screen
// Font size : 128x64 pixels
// Memory usage : 1024 bytes
#include <avr/pgmspace.h>
uint8_t Splash[] 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, 0x00, 0x00, 0x00,
0x0f, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0f, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
0x0f, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0xc0,
0x0f, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0xc0,
0x0f, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x78, 0x01, 0xc0,
0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x20, 0x01, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0xfc, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xe0, 0x01, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0xfe, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xf0, 0x03, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0xff, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xf8, 0x0f, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0xff, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0xfc, 0x0f, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0xef, 0x9f, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc7, 0xdf, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x9f, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x3f, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x1f, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x1f, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x78, 0x0f, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x0f, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x0f, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x1f, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0xff, 0xc0,
0x01, 0xf8, 0x3f, 0x3f, 0x3f, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x09, 0xff, 0xc0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x01, 0xff, 0xc0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3f, 0xff, 0xc0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x7f, 0xff, 0xc0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 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,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x7c, 0x0f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x7c, 0x0f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x7c, 0x0e, 0x0f, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff,
0xfe, 0x00, 0x7c, 0x0e, 0x0f, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff,
0xfe, 0x00, 0x3c, 0x0e, 0x0f, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff,
0xfe, 0x00, 0x3c, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff,
0xfe, 0x08, 0x3c, 0x0c, 0x01, 0x03, 0x02, 0x06, 0x07, 0xe0, 0x07, 0x80, 0x3c, 0x00, 0xf0, 0x23,
0xfe, 0x08, 0x3c, 0x0c, 0x01, 0x03, 0x00, 0x00, 0x03, 0xc0, 0x01, 0x80, 0x38, 0x00, 0x30, 0x03,
0xfc, 0x08, 0x3c, 0x0c, 0x01, 0x03, 0x00, 0x00, 0x03, 0x80, 0x01, 0x80, 0x30, 0x00, 0x30, 0x03,
0xfc, 0x08, 0x1c, 0x0c, 0x01, 0x03, 0x00, 0x00, 0x03, 0x80, 0x01, 0x80, 0x30, 0x00, 0x30, 0x03,
0xfc, 0x18, 0x1c, 0x0c, 0x01, 0x03, 0x03, 0x03, 0x83, 0x80, 0x01, 0x80, 0x30, 0x00, 0x30, 0x3f,
0xfc, 0x1c, 0x1c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x81, 0xc1, 0xc1, 0xf0, 0x38, 0x30, 0x3f,
0xfc, 0x1c, 0x1c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x81, 0xc1, 0xc1, 0xf0, 0x38, 0x30, 0x3f,
0xfc, 0x1c, 0x1c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x81, 0x81, 0xc1, 0xf0, 0x30, 0x30, 0x3f,
0xf8, 0x00, 0x1c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x80, 0x01, 0xc1, 0xf0, 0x00, 0x30, 0x3f,
0xf8, 0x00, 0x0c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x80, 0xff, 0xc1, 0xf0, 0x1f, 0xf0, 0x3f,
0xf8, 0x00, 0x0c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x81, 0xff, 0xc1, 0xf0, 0x3f, 0xf0, 0x3f,
0xf8, 0x00, 0x0c, 0x0e, 0x0f, 0x03, 0x03, 0x03, 0x83, 0x81, 0xff, 0xc1, 0xf0, 0x3f, 0xf0, 0x3f,
0xf8, 0x00, 0x0c, 0x0e, 0x01, 0x03, 0x03, 0x03, 0x83, 0x80, 0x01, 0xc0, 0x30, 0x00, 0x30, 0x3f,
0xf8, 0x1c, 0x0c, 0x0e, 0x01, 0x03, 0x03, 0x03, 0x83, 0x80, 0x01, 0xc0, 0x30, 0x00, 0x30, 0x3f,
0xf0, 0x3c, 0x0c, 0x0e, 0x01, 0x03, 0x03, 0x03, 0x83, 0x80, 0x01, 0xc0, 0x30, 0x00, 0x30, 0x3f,
0xf0, 0x3c, 0x04, 0x0f, 0x01, 0x03, 0x03, 0x03, 0x83, 0xc0, 0x01, 0xe0, 0x38, 0x00, 0x30, 0x3f,
0xf0, 0x3e, 0x04, 0x0f, 0x81, 0x03, 0x03, 0x03, 0x83, 0xe0, 0x07, 0xf0, 0x3c, 0x00, 0xf0, 0x3f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
*
This is for the splash screen when the device boots, right? ( see YT link )
Can someone explain what it means and how it's made? I want to create my custom splash screen but I don't understand this code. Thanks!
I believe that is just a bitmap. The values indicate where to draw a pixel. The 0x00 values are just the blank space (probably black screen), and any where where there is a value greater than zero there will be pixels drawn (a 1 will be a pixel). All the painted pixels come together to create an image.
I think if you search, you should be able to find some kind of editor that will let you draw what you want and it will generate the bitmap for you.

OLED 128x64 bitmap display issue [ARDUINO]

I am using the following display : https://www.adafruit.com/products/938
I ran the code they have on git and it works perfectly, I can see all their tests and all it's fine however the moment I add my own bitmap(via LCD assistant) as follows :
const unsigned char tedst [] = {
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, 0x80, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 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, 0x38, 0x7C,
0x7C, 0x3C, 0x3E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x3E, 0x3E, 0xFE, 0xFE, 0xFE, 0xFE,
0xDE, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x0C, 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, 0xFE, 0xFF, 0xFF, 0xFF, 0x07, 0x01, 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, 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, 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, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 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, 0x01, 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, 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, 0xFF, 0xFF, 0xFF, 0xFF,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF8, 0xFE, 0xFF, 0xFF, 0x8F, 0x87, 0x87, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x87, 0x8F, 0xFF, 0xFF, 0xFE, 0xFC, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xC0,
0xC0, 0xC0, 0xC0, 0x81, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xC0, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x7F, 0xFF, 0xFF, 0xFF, 0xC7, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF8, 0xFC, 0xFE, 0x3F, 0x1F, 0x0F, 0x07, 0x07,
0x03, 0x03, 0x07, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xC0, 0xC0, 0x80, 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, 0x7F, 0xFF, 0xFF, 0xFF, 0xE0,
0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x1F, 0x0F, 0x00, 0x00, 0x01, 0xC3, 0xFF, 0xFF, 0xFF,
0xFF, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x1F, 0x3F, 0x3F, 0x7E, 0xF8,
0xF8, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF8, 0xF8, 0x7C, 0x3E, 0x3F, 0x1F, 0x0E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x7F, 0xFF, 0xFF, 0xFF, 0xC0, 0x80, 0x80, 0x00, 0x00,
0x00, 0x80, 0xE0, 0xFC, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xF8, 0xC0, 0x80, 0x03, 0x07, 0x07,
0x03, 0x83, 0xC3, 0xFF, 0xFF, 0xFF, 0xFE, 0x18, 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, 0x01, 0x07, 0x0F,
0x0F, 0x1F, 0x1E, 0x3E, 0x3E, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3E, 0x1F, 0x1F, 0x0F, 0x07, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x07, 0x03, 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,
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
};
I then follow up with :
display.clearDisplay();
display.drawBitmap(0, 0, tedst, 128, 64, 1);
display.display();
As the image is as big as the screen and when I do so the screen flickers with half of your logo(the first image, I did not alter the loop so all animations will be there) and random artifacts. The moment I delete my 3 lines, it is all back to normal, ideas why please?
use dot factory at http://www.pavius.net/wp-content/uploads/the-dot-factory/versions/TheDotFactory-0.1.4.7z where you set the output as binary, the thing works perfectly

Problem with c written server displaying a bmp image

First off, if anyone would like to compile the server and run it
go to http://pastebin.com/qPnE3jV0
compile and run it
go to your browser and type http://localhost:7191/
The function I'm looking at particularly is:
void serveHTML (int socket) {
char *message;
int i;
int j;
//image data
char bmpheader[54] = {0x42, 0x4D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
char bmpimagedata[36] = {0x07, 0x07, 0xFF, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFF, 0xFF, 0x07, 0x07, 0x07, 0x07, 0x07, 0x66, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFF, 0xFF, 0xFF, 0x46, 0x00, 0x00};
message = "HTTP/1.0 200 OK\r\n"
"Content-Type: image/bmp\r\n"
"Content-Length: 90\r\n";
printf ("%s\n", message);
write (socket, message, strlen(message));
// now send the contents of the web page to be displayed
i=0;
j=0;
while (i < 54) {
printf("%c", bmpheader[i]);
write (socket, &bmpheader[i], 1);
i++;
}
while (j < 36) {
printf("%c", bmpimagedata[j]);
write (socket, &bmpimagedata[j], 1);
j++;
}
}
What I've done here is stored the hex
data of a 3x3 bmp file into two
arrays (for convenience of
modification) the header and the
image data. I try to get it to
serve this bmp on a web browser.
However it fails.
I've placed printf's all over the
place to print what the server is
spitting out... however I think I'm
missing something (possibly a
footer?).
Any help would be appreciated, I'm pulling my hair out as to why it doesn't work.
Headers need to end with two \r\n - Append \r\n to your message constant.
A few points:
Don't use such bizarre code to write out the arrays. Just use plain write(socket, bmpheader, sizeof bmpheader); and the same for the data.
Inspect the return value of write(); it can fail.

Resources