Go Down

Topic: How to make a complete display solution for user interface? (Read 463 times) previous topic - next topic

Microzod_

Hello.

I have been searching and reading online for days now but I only get more and more confused, I suspect that my efforts are hindered by my quite severe ADD(Attention Deficit Disorder) and I really feel like I have hit a brick wall.

I am developing code for use with a 0,96" OLED display(128*64) possibly even larger but still OLED although I have become quite interested in E-paper displays.
But for now I am using one of those large GLCD displays with a parallel interface but since it is also 128*64 I think it should be fine since I can use U8glib for both.

I have found Bitmap2LCD and are using a trial for that software but I fail to understand what to do with it, there are many articles dealing with different things on that site but I fail completely to put it all together and I have no clue about what to do next.

I know there are already made fonts, and that I can adjust fonts or make my own fonts with a number of different PC software, but when it comes to making animations it get very confusing.

What I am looking for in the end is a system which hare controlled by a small number of buttons, and showing on the display some analog values such as voltage, amperage, ohm, time or similar(the values are changing constantly) but I have understood that such a task is no problem with the use of the function dtostrf() to convert float values to strings and then printed to the display.

But lets say I want a custom made battery indicator, and some other simple conditional features on the display that shows only during certain conditions, can anyone tell me how to do that or direct me towards any resources I can hopefully utilize better than my failed attempts with Bitmap2LCD.

I find the complexity of Bitmap2LCD to be a real obstacle and I am hoping you might now of a simpler way to accomplish these things.

When I begun this research I was hoping to find some application that would in a simple way present me with a grid of squares on which I can prototype figures and then convert that to some format suitable for printing to the display through embedded C, which is exactly what Bitmap2LCD can do but it is to weird/difficult, if there are no other option then I'll simply have to keep banging my head against my keyboard but I don't think that it has to be so convoluted, does it?


Regards

olikraus

Hi

You addressed several problems, i pick out one of it: Bitmaps.
If you would use u8glib (or better u8g2), then you could use XBM pictures. The XBM file format is very old, but usually can still be generated (exported) by most of current image processing/painting tools. So, for example you can create any picture with "GIMP" and export this as a XBM file.

An now here is the trick: XBM is plain C code, which can be easily included (by copy and paste) into your Arduino .ino file.
So you export from your image tool and paste this directly into .ino. U8g2 comes with an XBM example. It looks like this:

Code: [Select]

// start of XBM file
// XBM file start, paste the content of the XBM file directly into the .ino file
// variable name changed from
// static unsigned char u8g2_logo_97x51_bits[]
// to
// static const unsigned char u8g2_logo_97x51_bits[] U8X8_PROGMEM


#define u8g2_logo_97x51_width 97
#define u8g2_logo_97x51_height 51
static const unsigned char u8g2_logo_97x51_bits[] U8X8_PROGMEM = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x3c, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00,
   0x00, 0x00, 0x3c, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
   0x03, 0x00, 0x00, 0x3c, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0xff, 0x03, 0x00, 0x00, 0x3c, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x80, 0xcf, 0x07, 0x00, 0x00, 0x3c, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x80, 0x83, 0x07, 0x00, 0x00, 0x3c, 0x80, 0x07, 0xf8, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x81, 0x07, 0x00, 0x00, 0x3c, 0x80, 0x07, 0xfc, 0x03,
   0x1c, 0x00, 0x3e, 0x1c, 0xc0, 0x03, 0x00, 0x00, 0x3c, 0x80, 0x07, 0xff,
   0x07, 0x7f, 0x80, 0xff, 0x3f, 0xe0, 0x01, 0x00, 0x00, 0x3c, 0x80, 0x07,
   0xff, 0x8f, 0xff, 0xc1, 0xff, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x3c, 0x80,
   0x87, 0xff, 0xdf, 0xff, 0xc1, 0xc3, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x3c,
   0x80, 0x87, 0x0f, 0xfe, 0xff, 0xe3, 0x81, 0x03, 0x1e, 0x00, 0x00, 0x00,
   0x3c, 0x80, 0xc7, 0x07, 0xfc, 0xe3, 0xe3, 0x81, 0x07, 0x0f, 0x00, 0x00,
   0x00, 0x3c, 0x80, 0xc7, 0x07, 0xf8, 0xc1, 0xe7, 0x81, 0x87, 0xff, 0x07,
   0x00, 0x00, 0x3c, 0x80, 0xc7, 0x03, 0xf0, 0x80, 0xe7, 0xc3, 0x87, 0xff,
   0x07, 0x00, 0x00, 0x3c, 0x80, 0xc7, 0x03, 0x70, 0x80, 0xc7, 0xe7, 0x83,
   0xff, 0x07, 0x00, 0x00, 0x3c, 0x80, 0xc7, 0x03, 0x78, 0x80, 0xc7, 0xff,
   0x03, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x80, 0xc7, 0x03, 0xf8, 0xc0, 0x87,
   0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x80, 0xc7, 0x07, 0xfc, 0xc1,
   0xc7, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xc0, 0x87, 0x0f, 0xfe,
   0xff, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xc0, 0x83, 0xff,
   0xdf, 0xff, 0xe3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf1, 0x03,
   0xff, 0x8f, 0xff, 0xe1, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff,
   0x01, 0xfe, 0x0f, 0xff, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xe0,
   0xff, 0x00, 0xfc, 0x03, 0x7c, 0xc0, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,
   0x80, 0x3f, 0x00, 0xf8, 0x01, 0x00, 0xe0, 0x01, 0x1e, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x1e, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x1e, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xf0, 0xc7, 0x0f,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xe0, 0xff,
   0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0,
   0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff,
   0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff,
   0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x24, 0x20, 0x00,
   0x00, 0x08, 0x46, 0x02, 0x00, 0x80, 0xc0, 0x40, 0x00, 0x0c, 0x6e, 0x6a,
   0xc0, 0xa4, 0x48, 0x04, 0xaa, 0xac, 0x8c, 0xaa, 0xac, 0x00, 0x6a, 0xa4,
   0xaa, 0x20, 0xea, 0xa4, 0x64, 0x66, 0xaa, 0x46, 0x4a, 0x8a, 0x00, 0x4c,
   0xa4, 0xaa, 0x20, 0xaa, 0xa2, 0x44, 0x2a, 0xaa, 0x28, 0xaa, 0x4c, 0x00,
   0xe8, 0xa8, 0x6c, 0xc4, 0xa4, 0x42, 0xee, 0x2a, 0xcc, 0x26, 0x6c, 0xe8,
   0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00 };

// end of XBM file

void setup(void) {
  u8g2.begin(); 
}

void loop(void) {
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB14_tr);
    u8g2.drawXBMP(0,0, u8g2_logo_97x51_width, u8g2_logo_97x51_height, u8g2_logo_97x51_bits);
  } while ( u8g2.nextPage() );
  //delay(1000);
}


For Uno and other ATmega boards, you need to add the PROGMEM statement as described above. Use drawXBMP to make your image visible on the display.

So... no need of other special tools to create the bitmap.
Hope this helps.

Oliver

Nick_Pyner

Assuming Bitmap2LCD does what it says, I think the first thing you need to do is question if you really need it. I understand your intention is to send data to a screen - a very small screen, and sending bitmaps as well seems rather futile. I submit the GLCD code will do all you need. I use the Henning Karlsen library, as I found it easiest, but I believe they are all much the same.

Microzod_

This is going to be a somewhat confused post, but I have been trying to grasp this for a while now without succeeding.

I have an LCD(an ST7920 128*64 running with U8glib but I am about to try U8g2), if I will use U8g2 then there seems to be other options besides using a picture loop but with U8glib there is only the picture loop possibility.

Any way, a picture loop must write everything that is going to show up on one screen because the next time the picture loop runs it will clear the display.

I have managed to talk to a ADXL345 3-axis accelerometer and collect data and convert that data to strings which is then printed to the screen showing simply, for example:

X: -7
Y: -2
Z: 251

But now I got trouble with U8g2.

But with U8g2 the constructor is not the same and I am making something wrong but I really can't decipher what the creator wants me to change, below are first the U8glib constructor that worked for me, then follows the U8g2 constructor:
Code: [Select]
U8GLIB_ST7920_128X64_4X u8g(45, 43, 41, 39, 37, 35, 33, 31, 47, 51, 49);   
//                      u8g(D0, D1, D2, D3, D4, D5, D6, D7, enable, di, rw)

U8G2_ST7920_128X64_1_8080 u8g2(U8G2_R0, 45, 43, 41, 39, 37, 35, 33, 31, 47, 51, 49/*, 25*/);
//                        u8g2(Rotation, D0, D1, D2, D3, D4, D5, D6, D7, enable, cs, dc [, reset])


When I leave the last parameter(/*, 25*/) in comments the display is showing something but it is all wrong, if I include that parameter then nothing shows but that is the pin the RST of the display is connected to,I guess it was never used before.
No now it isn't showing anything however I treat that last RST parameter.

I am much more akin to C than C++ so I can't really interpret what is going on in that constructor description, I have only written the simplest form of constructors for my self.

Does anyone of you know how U8glib constructor parameters "di, rw" should be changed to fit with U8g2 constructor parameters "cs, dc [, reset]"?

I don't know what to do exactly at this point. I feel as the answer might be right in front of me but my thoughts has gone haywire by now and I don't know.

I will search for the map I drew with the exact wire connection diagram that I wrote for this display, it hooks right on to the dual pin header of the Due so it isn't about to change without a solder iron.

Nick_Pyner

..........picture loop...
I have managed to talk to a ADXL345 3-axis accelerometer and collect data
This is going to be a somewhat confused post,
It already is.
Quote
I will search for the map I drew
A diagram of what you hope to eventually see on the screen might help.

olikraus

But now I got trouble with U8g2.

But with U8g2 the constructor is not the same and I am making something wrong but I really can't decipher what the creator wants me to change, below are first the U8glib constructor that worked for me, then follows the U8g2 constructor:
Code: [Select]
U8GLIB_ST7920_128X64_4X u8g(45, 43, 41, 39, 37, 35, 33, 31, 47, 51, 49);   
//                      u8g(D0, D1, D2, D3, D4, D5, D6, D7, enable, di, rw)

U8G2_ST7920_128X64_1_8080 u8g2(U8G2_R0, 45, 43, 41, 39, 37, 35, 33, 31, 47, 51, 49/*, 25*/);
//                        u8g2(Rotation, D0, D1, D2, D3, D4, D5, D6, D7, enable, cs, dc [, reset])

The rw signal is not required for u8glib and u8g2. U8glib forces it to "low". For u8g2 you must manually apply digitalWrite(49, 0) or tie the signal directly to GND.
The cs signal is not used by the ST7920. It was not there with u8glib, but now appears in u8g2. Reason: In U8g2 I use a genearic 8-bit interface, which includes the cs signal. So it appears here although it is not used. So you have to set it to U8X8_PIN_NONE.

Code: [Select]

U8G2_ST7920_128X64_1_8080 u8g2(U8G2_R0, 45, 43, 41, 39, 37, 35, 33, 31, 47, U8X8_PIN_NONE, 51);
//                        u8g2(Rotation, D0, D1, D2, D3, D4, D5, D6, D7, enable, cs, dc [, reset])


Oliver



Edit, see also:
https://github.com/olikraus/u8g2/wiki/gallery#26-nov-2016-st7920-128x64-lcd-in-8080-parallel-mode
https://github.com/olikraus/u8g2/issues/90

Microzod_

Yes now it works, thank you.

I haven't actually use them yet but I think that the option for buttons is a very nice feature.

I have been having a hard time getting started trying to wrie code for a menu, I have a rough idea of what I want(although I will probably write a test menu first just to get an idea about how it works) but I don't really know what to do next.

I have downloaded GIMP so now I can make and export bitmaps as XBM files, and I am using the full page option for running U8g2lib.

I have been reading about state machines lately and thought I would write a state machine using a function pointer, the details of how this state machine works can be found here.

However I have started thinking that maybe a state machine isn't really suitable, though I don't know so until I discover whether it is or not I will continue on that idea. Thus far I haven;t really made any progress at all but this is what it looks like(this isn't suppose to compile correctly yet and is only meant to show if I am on a bad path or not):
Code: [Select]
#include <U8g2lib.h>
#include <U8x8lib.h>

U8G2_ST7920_128X64_F_8080 u8g2(U8G2_R1, 45, 43, 41, 39, 37, 35, 33, 31, 47, U8X8_PIN_NONE, 51);  // 1 page picture loop

#define BUTTON_SUPPLY 13
#define MENU_SW 10
#define NEXT_SW 11
#define PREV_SW 12

// State-machine function pointer type definition:
typedef void *(*StateFunc)();

// States
void *page1();
void *page2();

void *page1()
{
 
  return page2; // next state
}

void *page2()
{
 
  return 0; // next state
}


void draw(void);

bool render = 0;
bool transition = 0;

void setup()
{
  StateFunc statefunc = page1;
  u8g2.begin(/*Select/Menu=*/ MENU_SW, /*Right/Next=*/ RIGHT_SW, /*Left/Prev=*/ LEFT_SW, /*Up=*/ U8X8_PIN_NONE, /*Down=*/ U8X8_PIN_NONE, /*Home=*/ U8X8_PIN_NONE);
 
}

void loop()
{
  // picture loop 
  u8g2.clearBuffer();
  statefunc = (StateFunc)(*statefunc)(); // this executes the pointed to function and expects the called function to return another pointer.
  if(render)
    u8g2.sendBuffer();
 

 
}

void draw(void)
{
  // graphic commands to redraw the complete screen should be placed here
  // reference strings fromthe upper left:
  u8g2.setFontPosTop();
  u8g2.setFont(u8g2_font_unifont_t_latin);
  //u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g2.drawStr( 0, 0, "X:");
  u8g2.drawStr( 0, 15, "Y:");
  u8g2.drawStr( 0, 30 , "Z:");
  u8g2.drawStr( 18, 0, "000");
  u8g2.drawStr( 18, 15, "000");
  u8g2.drawStr( 18, 30, "000");
}



I think I have thought about this a little wrong and this isn't a suitable situation for using that state machine, the draw() function is simply left over code from testing but I might use it... We'll see.

I will draw a menu illustration and post that so everybody can see what my goal are.

Microzod_

I think I have started in the wrong end by my due to my interest in learning about state machines.

So I started in another end, I have drawn a pictogram showing how the menu should work but I think it really shows I have never done this before:

(Look at the attachment, why isn't it possible to include pictures in the post? or am I stupid and don't get how...)

Look at the picture, I use colour to illustrate "boundaries"(although the colours inside the square labeld "Main screen" isn't related to any part of the scheme, the texts/numbers enclosed in red is stuff that is going to be ether adjusted as an effect of menu option selections or periodically updated when the device is activated), there are 3 buttons controlling this user interface. These are:
"<<"(left/decrease)
">>"(right/increase)
"¤"(activate/select)

When the device is idle the main screen is showed, then if the "¤" button is pressed 3 times quite rapidly then the first item of the options screen is shown, at that point I can ether press "¤" again to choose the first option item, or "<<"/">>" to select between other option items(these are 3-5 items in the end and repeated presses in one direction will circle through all the options)

If we pressed "¤" directly after having pressed "¤" 3 times we would be in the square marked 1.1, and just in the way there where options using "<<" or ">>" while being in the "Top level", there are more option items here which structurally works in the same way.

Assume we again pressed "¤"(which would bring us to the square marked 1.1.1), then a screen would appear at which we can ether use "<<" or ">>" to adjust a single value shown on the screen(or not adjust it) and then press "¤" again to advance to the next option value, or after a certain amount of time has passed the menu advances automatically.

1.1.2 works like 1.1.1 and when we advance from that screen we are taken back to the main screen which is now updated with the values that we might have changed in the menu(if those values are even visible on the main screen which isn't necessarily the case).

What I am now trying to grasp if to which extent U8g2lib allows me to use other types of button presses other than simple single press events, I want to be able to use single-presses, rapid triple-presses and long hold-presses(this isn't super duper important but a preferred option).


Also, is there no way of using custom fonts with U8g2lib?

That would be a problem because I am quite picky with the fonts used and I want to create a font entirely of my own creation, if it isn't supported by functions would it be possible to simply high-jack a font(select a font, change it's data and then use that?

I have not thoroughly search the U8g2lib reference page but I looked over it and searched google for something with custom fonts, and it seems to present a great number of fonts but no reference to anything custom was found.

I have of course no insight into what it requires from a lib like U8g2lib to be able to manage custom fonts and I can imagine it to be both quite easy and simple, and very hard and complex.


These are thoughts expressed as I think them, but I think I will write a function for each separate square as shown in the picture, every square would start by re-drawing the display with appropriate information as well as starting timer set to 7,5 seconds or something and then start polling the buttons to catch any action(the mcu has nothing else it needs to do during this time anyway) and then depending on which button is pressed a different pointer is returned from the function(which will be executed next).

olikraus

Writing down the menu structure is always a good starting point. Thinking about state machines is also a good approach.
But remember, that you may need state machines on different levels: A state machine within one dialogwindow, where the "state" is the current focus for the different fields on the dialog box. And then a state machine which deals with the different menues which then call the dialogs (leaf menues).

But actually i wanted to answer your u8g2 custom font question.

U8g2 fonts are all based on the bdf format (https://en.wikipedia.org/wiki/Glyph_Bitmap_Distribution_Format).
BDF files are converted into a c array, which is then passed as argument to setFont().
The conversion happens with bdfconv, which is available for download (see the u8g2 FAQ for details: https://github.com/olikraus/u8g2/blob/master/doc/faq.txt)

So the idea is this:
BDF-File --> bdfconv.exe --> c-code --> setFont()

There are many tools which create BDF files. Within u8g2 i use the tool otf2bdf for TTF conversion. So for the well known TTF files, the chain looks like this:
TTF-File --> otf2bdf --> BDF-File --> bdfconv.exe --> c-code --> setFont()

There are also font editing tools, which can directly create BDF files, one nice tool is fony.exe (http://hukka.ncn.fi/?fony). The chain would look like this:
Fony.exe --> BDF-File --> bdfconv.exe --> c-code --> setFont()

Let me know if you require more help for bdfconv.exe. It is a little bit tricky, because you need to select proper modes and also a suitable subset of the glyphs inside the BDF-file (If your BDF file contains 100000 chars, than you probably only want some of them in your ROM limited microcontroller)

Oliver

Microzod_

I have started to think that this might be a too complicated application of an LCD and menu system and that it is unsuitable as a first larger project, this is a project that I simply have to accomplish but perhaps I should divert my attention to making a simple number system converter/logic operator calculator.

"simply" a matrix keypad and an LCD to make a device that would convert decimal/hexadecimal/binary into binary/hexadecimal/decimal numbers, and maybe also be able to combine values using logic operators.
That last functionality might be a little to much though.

If I choose to do that this thread will remain inactive for a while but unless the workings of the Arduino forum prevents me this will sooner or later be re-started.

But I am facing some confusion which I am not able to clear up.

I understand the basic difference between U8g2lib's full buffer mode and page buffer mode but I fail to comprehend there following implications for the over all microcontroller functionality(related to going through a design phase and what compromises needs to be done and so on).

Could someone whom understands this extrapolate a little further into the ramifications of this situation, full- vs page-buffer?

olikraus

Full-Buffer Mode:

A complete copy of the display frame buffer is reserved in the RAM of the microcontroller:

u8g2 draw procedures --> uC RAM --> SendBuffer --> Display RAM

I guess, most other libs follow the same approach, especially the Adafruit GFX lib will also use this approach.


The trouble starts, if you want to drive e.g. 256x64 OLED with an Arduino Uno. In such a case the buffer will require 256*64/8 = 2048 bytes of the uC RAM. This is exactly the amount, which is available in the Uno. But because the Uno requires some extra RAM for various other tasks, this will not work. So, this is why there is the buffer mode.

I once tried to explain this here:

https://github.com/olikraus/u8glib/wiki/tpictureloop

So maybe you read this article first. Feel free to ask further questions to that buffer mode.

Oliver






Go Up