Sunday, January 13, 2013

Photo Log: Horse Running Animation

Complex figures are tough to build programmatic-ally(dynamic creation), so such figures are converted from an image to equivalent header files, and then called after a certain time delay(creating frame rate) so to it seem as animated.  CLick to view swf. 

This is the gif i choose.

Horse Running GIF.

 This is frame by frame image.

Frame by Frame Image.

So obviously the next step is to separate each image by cropping. Using any image editor. As shown below.

Cropping Individual Image.

Now separated image needs to be converted to monochrome. To see how to do view this post. Converting Bitmap Image to Equivalent Header File.

Difference Grayscale and Monochrome Image

Make individual header files where number of header files = number of images/frames.

Individual Header Files.

The LoadBitmap Function that was used to show bitmap images is used here to show the frame by frame animation.

void LoadBitmap(unsigned char *bitmap)

{

uint16_t i, j,by;

for(i=0; i<64; i+=8)


                                for(j=0; j<128; j++)

                                {

                                                by=pgm_read_byte(bitmap++);

                                                ks0108GotoXY(j, i);

                                                ks0108WriteData(by);

                                }

}
Here is the main function as shown below.
void main()
{
    for(volatile uint16_t i=0; i<15000; i++);
    ks0108Init(0);
    ks0108ClearScreen();
    while(1)
    {
        LoadBitmap(horse001);
        for(volatile uint16_t i=0; i<15000; i++);
        LoadBitmap(horse002);
        for(volatile uint16_t i=0; i<15000; i++);
        LoadBitmap(horse003);
        for(volatile uint16_t i=0; i<15000; i++);
        LoadBitmap(horse004);
        for(volatile uint16_t i=0; i<15000; i++);
        LoadBitmap(horse005);
        for(volatile uint16_t i=0; i<15000; i++);
        LoadBitmap(horse006);
        for(volatile uint16_t i=0; i<15000; i++);
        LoadBitmap(horse007);
        for(volatile uint16_t i=0; i<15000; i++);
        LoadBitmap(horse008);
        for(volatile uint16_t i=0; i<15000; i++);
        LoadBitmap(horse009);
        for(volatile uint16_t i=0; i<15000; i++);
        LoadBitmap(horse010);
        for(volatile uint16_t i=0; i<15000; i++);
        LoadBitmap(horse011);
        for(volatile uint16_t i=0; i<15000; i++);
       
    }//end of while loop
}

Currently the frame rate is 15frames per second one can vary and change the speed of display by varying the value of i.  To make a more precise frame rate stay connect for future post.

This is the final output.

Monday, January 7, 2013

Converting Bitmap Image to Equivalent Header File(very simple tutorial))

A simple tutorial to convert bitmap images to equivalent header files. 
Few Points to know for best display of graphic.
1) Its a monochrome GLCD so image is going to be pixelised.
2) Display cannot be predicted if you directly convert color image to monochrome equivalent.
3) So go to photoshop first convert it to grayscale and see if its viable to display it in monochrome. If not then make suitabke changes in the photoshop and see output in monochrome first and then if your satisfied export as bitmap.
4) take the exported bitmap and follow the steps.

Choose an Image

Open FastLCD Standalone Application

Define your screen Size.

Open Grayscale image in bitmap container in the FastLCD.

Paste or Stretch the Image whichever looks best as image may not be proportional in size.

Make some adjustments if neccseary

Store as basic file.

While saving save basic files as .h format

This is how your file will look after export

Make changes as show on in first line and find &h and replace them with 0x.

This is how your file header file will look. Now its ready to be used in the program.






Displaying Bitmap on Graphic LCD

Monochrome GLCD provides control for each and every pixel on the screen. As it has no colors barring black and white its pixel controllers are pretty simple. Basically a 128x64 resolution graphic LCD has 2 controllers each controlling 64x64 pixels on the screen. In short the screen is divided into 2 columns. (Left and Right).

Different manufacturers use different controllers. The most common is the ks0108 controllers. The code shown here is tested on a GLCD ks0108 controlled interfaced with an AVR atmega16/32. But as written in C can be ported to any other AVR controller.

Bitmap images can be easily displayed on the screen as bmp files are basicall hexadecimal code stored in either RLE compression or directly into a bmp container. To be used with non sd card reading controllers, one can convert these bitmaps into an equivalent header files. 

See image below.
Ya!! its popye the sailor man image.

Its equivalent header file looks like this...

static uint8_t sailor_man[] 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,
0xF0,0x78,0x28,0x28,0x68,0x48,0x48,0xD8,
0x90,0x10,0x10,0xF0,0x00,0x00,0x00,0x00,
.
.
.
0x1A,0x18,0x1A,0x72,0x32,0x7A,0x3A,0x76,
0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};


The array is basically stored as 64 rows and 128 columns format. 
Meaning the first 128 values in the array is for the 1st row. 2nd 128 values for 2nd row and so on....
Depending on the converter you use these set can be arranged in any form. The converter i used is a small application called FastLCD. (Download).

The tutorial to use FastLCD though very simple is shown here.

Yes one more thing store this array in the program memory of the AVR.
Now we require a loop to read these values from the program memory in the form of row and columns and display on the screen. The below loop will do the trick.

uint16_t i, j,by;
for(i=0; i<64; i+=8)
       for(j=0; j<128; j++)
      {
             by=pgm_read_byte(bitmap++);
             ks0108GotoXY(j, i);
             ks0108WriteData(by);
      }


So as the ks0108 controller can directly read hexa decimal values we just read the byte from the program memory and arrange it in rows and columns and just write the data....
Is it really this simple.???
Yes it is....

same can be converted into a function to improve portability.

void LoadBitmap(unsigned char *bitmap)
{
uint16_t i, j,by;
for(i=0; i<64; i+=8)

                                for(j=0; j<128; j++)
                                {
                                                by=pgm_read_byte(bitmap++);
                                                ks0108GotoXY(j, i);
                                                ks0108WriteData(by);
                                }
}

This is how one can display various monochrome bitmaps in the GLCD.
See images from my experiments...
Addidas Logo on GLCD

Sailor Man on GLCD.
You can download source code from here.