store and display picture

Thread Starter

Pushkar1

Joined Apr 5, 2021
416
I have many pictures in jpge which I want to store in microcontroller and then show them on display. I do not want to use any development board in this experiment.

1) I want to know what type of display can be used in this experiment it will be even better if you suggest the model number

2) Which of the following series of microcontrollers should be used ARM/PIC
 

ronsimpson

Joined Oct 7, 2019
2,988
How good of a display do you want? How much storage and in what format? (camera storage card?) SD card?

You could and people have made a PIC talk to large SD cards and talk to LCD displays like what in your phone or smaller. You will need to learn how to read and write SD and how to talk LCD.

If you are thinking ARM then think Raspberry Pi. While a Pi-0 will do the job it is limited and will take some work to write the program. For the prototype I would start out with any of the larger Raspberry Pi(s). It has a SD card port and a video port to talk directly to a TV or monitor. You can develop on the Pi or on a PC but I do it on the Pi. It talks USB keyboard and USB mouse. The operating system knows how to talk SD card and LCD display with out you learning how. In minutes you can learn how to move a picture from storage to display. When you are ready I think you could move your program to the small low cost Pi-0.

My opinion. Worth what you payed. RonS.
 

nsaspook

Joined Aug 27, 2009
13,081
I have many pictures in jpge which I want to store in microcontroller and then show them on display. I do not want to use any development board in this experiment.

1) I want to know what type of display can be used in this experiment it will be even better if you suggest the model number

2) Which of the following series of microcontrollers should be used ARM/PIC
Is this something fairly simplistic you want to build from parts as a learning experience or a full capability digital frame?
 

Thread Starter

Pushkar1

Joined Apr 5, 2021
416
How good of a display do you want? How much storage and in what format? (camera storage card?) SD card?
consider 2,560 x 1,440 resolution
Storage 100 MB
Take images from micro SD card
If you are thinking ARM then think Raspberry Pi. While a Pi-0 will do the job it is limited and will take some work to write the program.
I don't want to use raspberry pi
 

nsaspook

Joined Aug 27, 2009
13,081
If you want to learn about computer graphics systems a simple first step is to use a BW bit-map of the image stored in the flash of the controller.

First you need to transform the image format into a 1 bit per pixel bit-map.
https://javl.github.io/image2cpp/
Output: plain bytes, Vertical - 1 bit per pixel
PXL_20211104_160648489.jpg
select image
PXL_20211104_160748580.jpg
convert image to hex format
PXL_20211104_161001863.jpg
store the hex image data in a C const array

https://www.lcd-module.com/fileadmin/eng/pdf/grafik/dogxl240-7e.pdf
Use GLCD driver software to load and display image

https://github.com/nsaspook/vcan/tree/i400_fix/firmware/lcd_drv
My driver is a very modified version of the driver for this display.
https://digilent.com/reference/pmod/pmodoled/start?redirect=1

C:
#include "lcd_drv.h"

/*
* This 'driver'is a merge of two  libs so it's a bit of a jumble
* with hardware specific statements in at least two source files.
* Because the PIC32MK version will likely only be used with graphic
* displays much of the code is unused and will one-day be removed
* after functional testing is complete.
* 10/15/2021
* uses SPI3 with a 15MHz clock for the LCD chip.
*/
static volatile uint8_t NOPER = 0;

void init_lcd_drv(LCD_DVR_STATE init_type)
{
    switch (init_type) {
    case D_MISC:
    case D_INIT: // send the GLCD buffer data via DMA
#ifdef EDOGM
        init_display();
        eaDogM_CursorOff();
#endif
#ifdef EDOGS
        SPI_EN1_Set(); // select SPI GLCD display, DOGXL240 @15MHz SPI clock
        dmtdelay(IS_DELAYPOWERUP); // > 400ms power up delay
        lcd_init();
        OledInit();
        OledSetCharUpdate(0); // manual LCD screen updates for speed
        OledMoveTo(bmp_x, bmp_y); // position image
        OledPutBmp(bmp_size, bmp_size, (uint8_t *) foo_map); // upload bitmap image from C array
        dmtdelay(BMP_DELAY); // show image for a bit
#endif
        break;
    default:
        break;
    }
}

/*
* delay routine that clears the DMT in the required instruction count window
*/
void dmtdelay(const uint32_t delay)
{
    static uint32_t dcount;
    uint32_t dmt_clear_count = DMT_INST_COUNT;

    for (dcount = 0; dcount <= delay; dcount++) { // delay a bit
        if (!dmt_clear_count--) {
            DMT_Clear(); // clear the Dead Man Timer
            dmt_clear_count = DMT_INST_COUNT;
        }
        NOPER++;
    };
}
OledPutBmp moves and formats the bit-map data into the controllers memory buffer for the display
C:
/***    OledPutBmp
**
**    Parameters:
**        dxco        - width of bitmap
**        dyco        - height of bitmap
**        pbBits        - pointer to the bitmap bits 
**
**    Return Value:
**        none
**
**    Errors:
**        none
**
**    Description:
**        This routine will put the specified bitmap into the display
**        buffer at the current location.
*/

void OledPutBmp(int32_t dxco, int32_t dyco, uint8_t * pbBits)
{
    int32_t xcoLeft;
    int32_t xcoRight;
    int32_t ycoTop;
    int32_t ycoBottom;
    uint8_t * pbDspCur;
    uint8_t * pbDspLeft;
    uint8_t * pbBmpCur;
    uint8_t * pbBmpLeft;
    int32_t xcoCur;
    uint8_t bBmp;
    uint8_t mskEnd;
    uint8_t mskUpper;
    uint8_t mskLower;
    int32_t bnAlign;
    int32_t fTop;

    /* Set up the four sides of the destination rectangle.
     */
    xcoLeft = xcoOledCur;
    xcoRight = xcoLeft + dxco;
    if (xcoRight >= ccolOledMax) {
        xcoRight = ccolOledMax - 1;
    }

    ycoTop = ycoOledCur;
    ycoBottom = ycoTop + dyco;
    if (ycoBottom >= crowOledMax) {
        ycoBottom = crowOledMax - 1;
    }

    bnAlign = ycoTop & 0x07;
    mskUpper = (1 << bnAlign) - 1;
    mskLower = ~mskUpper;
    if (disp_frame) {
        pbDspLeft = &rgbOledBmp0[((ycoTop / 8) * ccolOledMax) + xcoLeft];
    } else {
        pbDspLeft = &rgbOledBmp1[((ycoTop / 8) * ccolOledMax) + xcoLeft];
    }
    pbBmpLeft = pbBits;
    fTop = 1;

    while (ycoTop < ycoBottom) {
        /* Combine with a mask to preserve any upper bits in the byte that aren't
         ** part of the rectangle being filled.
         ** This mask will end up not preserving any bits for bytes that are in
         ** the middle of the rectangle vertically.
         */
        if ((ycoTop / 8) == ((ycoBottom - 1) / 8)) {
            mskEnd = ((1 << (((ycoBottom - 1)&0x07) + 1)) - 1);
        } else {
            mskEnd = 0xFF;
        }
        if (fTop) {
            mskEnd &= ~mskUpper;
        }

        xcoCur = xcoLeft;
        pbDspCur = pbDspLeft;
        pbBmpCur = pbBmpLeft;

        /* Loop through all of the bytes horizontally making up this stripe
         ** of the rectangle.
         */
        if (bnAlign == 0) {
            while (xcoCur < xcoRight) {
                *pbDspCur = (*pfnDoRop)(*pbBmpCur, *pbDspCur, mskEnd);
                xcoCur += 1;
                pbDspCur += 1;
                pbBmpCur += 1;
            }
        } else {
            while (xcoCur < xcoRight) {
                bBmp = ((*pbBmpCur) << bnAlign);
                if (!fTop) {
                    bBmp |= ((*(pbBmpCur - dxco) >> (8 - bnAlign)) & ~mskLower);
                }
                bBmp &= mskEnd;
                *pbDspCur = (*pfnDoRop)(bBmp, *pbDspCur, mskEnd);
                xcoCur += 1;
                pbDspCur += 1;
                pbBmpCur += 1;
            }
        }

        /* Advance to the next horizontal stripe.
         */
        ycoTop = 8 * ((ycoTop / 8) + 1);
        pbDspLeft += ccolOledMax;
        pbBmpLeft += dxco;
        fTop = 0;
    }
}
We send the local data buffer to the display via the SPI connection and boom, we have the picture on the display.
PXL_20211104_163429279.jpg
 
Last edited:

ronsimpson

Joined Oct 7, 2019
2,988
consider 2,560 x 1,440 resolution
Storage 100 MB
Take images from micro SD card
A PIC is going to take time to move the image. If the image is compressed that takes time. I think ARM is better.
2560x1440 will probably be HDMI so you need a computer that talks HDMI.

Several times I said "Pi" and every one laughed and said we can make one cheaper. Six months of development and we have a ARM board that costs more than a Pi and does less.
 
Top