Go Down

Topic: Need help with graphical LCD library and PROGMEM (Read 955 times) previous topic - next topic

sjfaustino

I'm very new to the Arduino and to C/C++, so please be patient :)

I'm trying to do a bootlogo on a graphic LCD but since it uses a lot of RAM, I thought of putting the logo in ROM and change the LCD library to read it from there.

The code below works perfectly without the progmem and pgm_read_byte_near. If I add the as below, the lcd image is corrupted but I can see the logo string correctly on the serial monitor and the debug print shows no memory being used (well, 1 byte :)).
I'm having trouble getting the LCD library to use the ROM data. Can't get it to work with the Flash library or with PROGMEM directly.
A bit of help?

Code: [Select]
///////////////////////////////////////////////////////////////////////////////
// Define DEBUG to produce verbose output to console
// Note: _DO NOT_ define DEBUG if using D0 (RX) and D1 (TX) for serial comms
#define DEBUG
#define BAUD_RATE 115200 // Baud rate, for serial communication with PC
///////////////////////////////////////////////////////////////////////////////
// Define GRAPHIC_LCD to use a 128x64 LCD from DFRobot.com
// Note: define GRAPHIC_LCD_BOOTLOGO to show a boot logo. USES HUGE AMOUNTS OF RAM!
#define GRAPHIC_LCD
#define GRAPHIC_LCD_BOOTLOGO

///////////////////////////////////////////////////////////////////////////////
// Allows us to debug the sketch during development and in case of issues
#ifdef DEBUG
 #include "DebugUtils.h"
#endif

///////////////////////////////////////////////////////////////////////////////
//
#include <Flash.h>
///////////////////////////////////////////////////////////////////////////////
//
#ifdef GRAPHIC_LCD
 #include <LCD12864RSPI.h>
#endif
///////////////////////////////////////////////////////////////////////////////
//
#ifdef GRAPHIC_LCD_BOOTLOGO
/*------------------------------------------------------------------------------
; LCD bitmap - size 128x64 pixels, black/white image
------------------------------------------------------------------------------*/
prog_uchar logo[] PROGMEM =
{
'S', 'T', 'A', 'R', 'T', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*                                                                                                                                  */
                                                                                           */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*                                                                                                                                  */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*                                                                                                                                  */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 'E', 'N', 'D', /*                                                                                                                                  */
};
#endif

void setup()    // run once, when the sketch starts
{
 #ifdef DEBUG
   Serial.begin(BAUD_RATE);
 #endif

 DEBUG_PRINTLN("Booting sketch.");

 #ifdef GRAPHIC_LCD
   DEBUG_PRINTLN("Initializing 128x64 Graphic LCD.");  
   LCDA.Initialise(); // INIT SCREEN
   delay(100);
   #ifdef GRAPHIC_LCD_BOOTLOGO
     DEBUG_PRINTLN("Displaying 128x64 1bit monochrome boot logo.");
     LCDA.DrawFullScreen(logo);//LOGO
     delay(3000);
   #endif
   DEBUG_PRINTLN("Clear LCD.");  
   LCDA.CLEAR();
   delay(10);

for(int i=0; i<1024; ++i)
{
   Serial.print(pgm_read_byte_near(&logo[i]));
}


 #endif
}

void loop()    // run over and over again
{
}


Below is the function that shows the bitmap on the lcd. Part of the LCD12864RSPI library from DFRobot.com
Code: [Select]

void LCD12864RSPI::DrawFullScreen(uchar *p)
{
     int ygroup,x,y,i;
     int temp;
     int tmp;
           
     for(ygroup=0;ygroup<64;ygroup++)           //дÈëÒº¾§ÉÏ°ëͼÏ󲿷Ö
       {                           //дÈë×ø±ê
if(ygroup<32)
{
x=0x80; // Set Graphic Display RAM Address - vertical address first
y=ygroup+0x80;
}
          else
          {
             x=0x88;
             y=ygroup-32+0x80;    
          }        
          WriteCommand(0x34);        //дÈëÀ©³äÖ¸ÁîÃüÁî - Function Set - 8 bit Interface - Extended Instruction
          WriteCommand(y);           //дÈëyÖá×ø±ê
          WriteCommand(x);           //дÈëxÖá×ø±ê
          WriteCommand(0x30);        //дÈë»ù±¾Ö¸ÁîÃüÁî - Function Set - 8 bit Interface - Basic Instruction
          tmp=ygroup*16;
          for(i=0;i<16;i++)
{
   temp=p[tmp++];
   WriteData(temp);
              }
         }
       WriteCommand(0x34);        //дÈëÀ©³äÖ¸ÁîÃüÁî - Function Set - 8 bit Interface - Extended Instruction
       WriteCommand(0x36);        //ÏÔʾͼÏó - Function Set - 8 bit Interface - Extended Instruction - Graphic Display ON
}


Since the Flash Library has a "#define FLASH_LIBRARY_VERSION 3", I was thinking of changing the LCD library function to something like:

Code: [Select]
#ifdef FLASH_LIBRARY_VERSION
//new code for Flash
else
// old code, no flash access
#endif


PS: had to cut the logo var when pasting here since the forum will not allow more than 9500 characters.

ECHO413

Could you  tell me how to change or Set the SPI  Baudrate ? In the SPI lib , there is not the function to do it . Thanks !

Graynomad

#2
Apr 24, 2011, 01:36 pm Last Edit: Apr 24, 2011, 01:38 pm by Graynomad Reason: 1
AFAIK you can't reference the PROGMEM array directly, ie

LCDA.DrawFullScreen(logo);

There are macros to to this but I can't remember right now what they are. I'm sure if you Google PROGMEM you'll find examples.

BTW, why do you have 'S', 'T', 'A', 'R', 'T' and 'E', 'N', 'D' in the array.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

Go Up