1

I am using an Arduino Mega and a 12864ZW LCD with the u8glib library and the following code to draw to the LCD:

U8GLIB_ST7920_128X64 Display(LCD_E_PIN, LCD_RW_PIN, LCD_RS_PIN, U8G_PIN_NONE);

void loop(){
   Draw();
}

void Draw(){
   Display.firstPage();

   do{
      Display.setPrintPos(10, 10);
      Display.print("This is a test");
   }while(Display.nextPage());
}

The problem is that the display is constantly redrawing itself. When I used LCD displays in the past, they usually only required to write to the LCD once unless you wipe the display. When I adjusted the code to:

U8GLIB_ST7920_128X64 Display(LCD_E_PIN, LCD_RW_PIN, LCD_RS_PIN, U8G_PIN_NONE);
bool needsUpdate = true;

void loop(){
   Draw();
}

void Draw(){
   if (needsUpdate){
       Display.firstPage();
       do{
          Display.setPrintPos(10, 10);
          Display.print("This is a test");
       }while(Display.nextPage());
       needsUpdate = false;
   }
}

I do not get anything drawn on the LCD. Is there a parameter that needs to be set so I only have to redraw the LCD if something changes? Am I using an outdated library? Is there a better library I should be using?

EDIT

I think the main problem I have with using this library is does the Draw loop need to be executed continuously to display on the LCD or is there a way to only draw the screen once until it is needed to be drawn again?

1

You haven't shown us all the code – in particular, the call to Draw() from loop() is missing – so this answer is speculative, based on the assumption your loop() is as follows.

void loop(void) {
    Draw();
}

If so, your first bit of code will constantly redraw because loop() runs repeatedly without delay. Try adding a delay(1000); after Draw() in that case.

Your second bit of code will begin by drawing your image once, and in that Draw() call it will set needsUpdate to false. Then loop() runs again, and the firstPage() call erases the screen. Since needsUpdate now is false and remains false, subsequent calls don't draw an image.

Rather than putting your picture loop into Draw(), perhaps use Draw() just to draw primitives, and keep your controls in loop():

void loop(void) {
  Display.firstPage();  
  do {     // picture loop
    Draw();
  } while( Display.nextPage() );    
  delay(1000); // delay before next picture
}

If you still get repeated fast redraws, for troubleshooting comment out the do and } while lines.

  • Thanks for the answer, I updated my question with the missing bits and also changed where the firstPage is located but still getting the same results. I tried commenting out the while loop when I do nothing gets drawn. – Andy Braham Nov 26 '15 at 18:54
  • @AndyBraham, does thelloworld work ok (changed to use your own constructor) ? If so you may need to add font selection, eg Display.setFont(u8g_font_unifont);, in your own Draw, and/or drawStr vs print – James Waldby - jwpat7 Nov 26 '15 at 19:16
  • Yes the Helloworld example you gave works fine. I guess my main hangup is that the LCD has to have a loop going all the time instead of only when things need updating and how long the Display takes to redraw each time. Seems to me that it is requiring allot of time to refresh the screen if it has much to draw. I will eventually have some highlight functionality that will be driven from Buttons and I am trying to figure out how the lcd code should work. As it is performing now the Draw is taking so much time that any inputs won't be caught. – Andy Braham Nov 26 '15 at 19:50
  • @AndyBraham, you might be able to just call nextPage() after each Draw() call (to tell u8g drawing is done) and ignore its output [1 or 0 as another Draw is needed or not]. I haven't looked closely but imagine nextPage() is supposed to test whether new objects being drawn have made a write-from-scratch necessary. If you already know that from how you update the image, just ignore output of nextPage(). Re inputs, use PCI's, pin-change-interrupts, which can happen and probably can be handled during drawing. – James Waldby - jwpat7 Nov 26 '15 at 20:34
  • Thanks a bunch! You got me on the right track, I posted an answer on here that shows the correct way (I feel) that this should be done. – Andy Braham Nov 26 '15 at 21:07
1

Much thanks to jwpat7 for getting me on the right track with this. So I found out how this LCD should really be setup. I am not sure why the examples I was able to find online and even on the u8glib wiki showed the usage like my question but I was able to get this library functioning right.

First thing is the .firstPage() and .nextPage() functions. The .firstPage() function actually clears the screen and the .nextPage() function displays what is waiting in the queue (thanks jwpat7). When the .nextPage() finishes there is no need to write to the LCD again until you need a refresh. I put together a very simple code example that uses a input to change the text without having to continuously update the LCD.

U8GLIB_ST7920_128X64 Display(LCD_E_PIN, LCD_RW_PIN, LCD_RS_PIN, U8G_PIN_NONE);
bool redraw = true;
String strOut = "This is a test...";

void loop() {

    if (redraw){
        Display.firstPage();  //Clear the LCD

        //Main Difference while the LCD needs drawing will return 1
        while(Display.nextPage()){
            Display.setFont(u8g_font_04b_03b);
            Display.setPrintPos(20, 20);
            Display.print(strOut);
        }

        redraw = false;  //Clear flag to redraw
    }

    //check if any of the pins in PINA have been pressed 
    if (~PINA & 0xff){
        strOut = "Of the emergency broadcast ...";

        redraw = true; //Set flag to redraw the screen
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.