ST7920 Interface Question

Hi,

i purchased a DFRobot 128x64 Graphic LCD (FIT0021) a few weeks ago, because it is able to display graphics.
I am very new to arduino, so I don't know if it would have been better to buy a different one.
After studying the documentation and doing some tests with the api that can be downloaded from dfrobot and another selfmade api from someone how has posted this youtube-video I am very unhappy with the results. Other than in the video the screen-refresh in graphics-mode is painfully slow. It takes nearly one second to repaint the entire screen.

Now I am wondering if I am doing something wrong.

I use the serial interface right now. Is it because of this? Is the parallel interface faster?
Should i buy a display with a different/better(?) controller than the st7920?

I don't have my source-code here in the office right now but it is more or less the same code that is posted with the video.

Any help would be appreciated!

Regards
Christian

Hi
With my (similar) displays, I usually see more than 15 frames per seconds with Arduino Uno. I once reached 73 fps with a ChipKit Uno and a serial dogs102 display.

I could assist you to write a low level driver for Google Code Archive - Long-term storage for Google Code Project Hosting.
There should also be a st7920 in my lab, but i did not have time until now to wire it and write that low level driver.

Oliver

Thanks for your reply, but i coudn't find a driver for my chip in your lab.
But maybe i find some helpful lines of code there which lead to a solution.

am i correct in assuming that in general hardware SPI is faster than software SPI?
and what about parallel? or does that depend mainly on the hardware itself?

is this display supported by your drivers?
it has a chip that is mentioned on your list but the displays serial-no DOGL128S itself not.
http://www.reichelt.de/DOG-LCD-Module/EA-DOGL128S-6/index.html?;ACTION=3;LA=2;ARTICLE=86717;GROUPID=3007;artnr=EA+DOGL128S-6;SID=11TwbsI38AAAIAADqjBAQ666e9b5422cc5bcd05dc6d15d45e4b53

Hi

U8glib does not yet support this controller. I have a display with this controller here. I always wanted to build something with it, but did not do so until no. So, there is no driver for the ST7920 yet.

SPI: Usually HW SPI is faster, especially for a slow CPU. I did not measure parallel bus yet.

Oliver

You will need parallel connection for read operations. spi doesn't support read. I have a multimode driver that I have almost finished. It allows Read/Write via parallel, shift registers, spi based shifting.
In the slowest mode ( writing out via shift registers ) is around 5 - 6 fps for writing to whole screen.

The ST7920 serial mode would be the fastest, but only up to a point due to the time the LCD needs to process most commands. I think a very efficient 8-bit parallel mode could reach similar speeds. From what I think I understand is, the ST7029 simply reconstructs the serial and 4-bit data into 8-bit mode data anyway.

When I have some testing completed and results to show I'll start a thread for this display.

I have not considered direct SPI as I see no circumstance where read operations won't benefit, as the Arduino does not have enough ram for a screen buffer. But this mode can be inserted easily.

EDIT: what arduino do you have, An uno for example may limit you to serial or shift registers if you need pins for other things, on a mega you have the freedom to choose.

Shift registers may suffice if you are only animating like a 32x32 object. ( 8x faster than writing whole screen, minus a bit for address changes ) ~40 fps or ~16 fps for 2 objects.

Static info and graphs ( status display for some device ) that don't need to be refreshed are perfect candidates for shifting.

i have the arduino uno. right now i am using half of it's ram as a screen buffer. i manipulate pixels there and then copy the entire 1024 byte to the lcd. i am using shiftOut() for that, clock is pin 3 and data is pin 9. as mentioned earlier, i have 1 fps max. is it because i am using software spi? is the arduino the limiting factor in terms of speed? can i increase the data-rate? is it possible to use hw spi with this display? in which circumstances do i have to read from the lcd (reading busyflag?)?

I have not considered direct SPI as I see no circumstance where read operations won't benefit, as the Arduino does not have enough ram for a screen buffer. But this mode can be inserted easily.

Can you describe this in more detail?

what i want to do:
i needed a text-display with 24x5 chars. since i only found displays up to 4 lines i ended up purchasing a lcd that is able to display graphics and is large enough so that i can create my own font and do the text output by myself. i don't have to move sprites or something like that but displaying an entire textpage takes (as i said before) almost 1sec and that is to long for my usecase. (the hw-text-mode of the display is only 16x4 chars)

Again, thank for any kind of help...

Regards
Christian

What I mean by direct SPI is:
Arduino SPI to ST7920 SPI rather than << Serial connection does not support write.
Arduino SPI to shift registers to ST7920 parallel.

Here is a link to some shiftout functions I wrote to speed things up, these inplace of arduino shiftout will give you easily 4 extra frames per second.

Just to clarify my initial post on u8glib: It does not use a full frame buffer, it does not need read access to the display memory, it works fine with SPI, it usually has 20 and more frame per second. But unfortunately there is no low level driver for the ST7920 at the moment...

Oliver

(This probably should be another thread, and I don't want to derail this thread.
This is more for thought than to kick of additional discussion in this thread)

I see references to "Frames per second", I'm very curious what that means to people when they
are quoting them for the speeds of their library routines.
The time to render and draw a "frame" can very substantially depending on what is being done per "frame".
For example doing a clear screen by writing 8 pixels at a time by writing out contiguous bytes to the glcd pages is
going to be much faster than actually drawing/setting each individual pixel.
If the screen displaying text, the "frame" rate could vary substantially depending on the font size
and how much of the screen is actually being written to or updated
and whether the display is being fully erased between "frames".
If drawing a bitmap(s), it can vary substantially depending on on the size of the bitmap,
and where it is located (in RAM or flash/progmem).

So while I'm seeing FPS numbers being bantered about, I'm not sure they really mean much
since what is being done on each is not consistent
so there is no real way to compare them to each other across different library implementations.

The glcd library also report a "FPS" rate in a sketch. It uses a somewhat arbitrary collection of things:
It does some line and object drawing intermixed with text and a full display clear between each "frame".
Even that FPS value is useless for comparison to other libraries.

So while a "FPS" value is of interest when looking at different displays running the same sketch and
library, it really isn't useful for comparing across different libraries until there is common
"frame rate" sketch defined that can be run on each library.

--- bill

I have a 128x64 ST7920 that I drive in serial mode, using a driver I wrote myself. I've tried hardware SPI (fast), ShiftOut (very slow) and an improved version of ShiftOut which is between the two in speed. I use 1K of RAM as a frame buffer - this is half the RAM of an atmega328 but in this application I can afford it. Using only 2 wires instead of lots for a parallel interface is a big advantage.

@Bill

Yes sure, I fully agree: FPS is difficult to measure and dangerous to compare. I just wanted to say, that I am very confident that U8glib will be faster than 1 FPS.

@dc42
I agree, shiftOut is very slow. There had been some discussion about improvements here. I also wrote my high speed version. I guess for the atmega328 HW SPI is always faster than SW SPI. Things change with the PIC32 of a ChipKit board. SW SPI has equal speed. Indeed, I had to slow down SW SPI, otherwise speed is above specification and i indeed go dropouts on the display.

There is only one issue with the Atmel HW SPI subsystem. Of course we need clock and data out lines. But additionally the HW SPI subsystem occupies the "data in" line. So we loose one line here (at least to what i know, and i never was able to use this pin for something else)

Oliver

olikraus:
There is only one issue with the Atmel HW SPI subsystem. Of course we need clock and data out lines. But additionally the HW SPI subsystem occupies the "data in" line. So we loose one line here (at least to what i know, and i never was able to use this pin for something else)

Did you try using the pin for something else, e.g. a digital input? I can't see any reason why enabling hardware SPI would prevent a digitalRead of the MISO pin from working. I'll try it when I get a chance. OTOH the SS pin definitely has to be configured as an output.

It takes nearly one second to repaint the entire screen.

This is what I based my FPS measurement on, Writing data to the entire display.

Finally, U8glib writes to my ST7920 display. The latest version v0.09 supports ST7920 displays:
http://code.google.com/p/u8glib/downloads/list

I did not do any FPS measures :wink:

Oliver

Hello Oliver !

I can't get u8glib to work with my ST7920 display that is exactly similar to the DFRobot display.

I can't understand what is the correct pinout. In your wiki you give constructor as:

U8GLIB_ST7920_128X64(cs, a0 [, reset])

But in the lib examples (HelloWorld etc) it is given as:

U8GLIB_ST7920_128X64 u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9

Also, to my understanding A0 = RS ... but RS is also CS in this module for serial mode. So how can the constructor require both CS and A0 ?

I've tried several ways of hooking up the display, but I only get datarubbish on the screen.

Could you please clarify the pinout and constructor for ST7920 ?

Oliver:

I tried out ST7920 via the parallel 8-bit interface.

I think your library is wonderful, and its the closest thing to something I could really use. I've spent some time writing device headers for ST7920 for the glcd library, and got it to initialize and so, but the trouble is that the ST7920 memory mapping differs so much from the ks1080 that I would have to rewrite the WriteData function for glcd to get it to work.

This is why I would really like to see u8glib work for real with ST7920.

With my graphics module (from china) based on the ST7920 there is a problem with u8glib: u8glib cn only draw half the screen. The reason for this (quite common with ST7920 based 128x64 displays) is that the memory is mapped as shown in the following image.

I looked around u8glib but didn't want to start knifing around with no idea how its built. There are so many layers of abstraction.

Do you think there is a way to take this memory mapping model into account in u8glib ?

Hi smultron

ST7920 SPI Interface:
With the initial author of this thread I currently try to get SPI mode working.
We just realized, that the SPI mode is completly different to what I have seen
from similar controllers. So, SPI mode is broken in the current u8glib and I have
fix this.

Library Software Architecture:
After writing dogm128 lib with many requests to support this or that device,
I decided to rewrite everything from scratch. Especially I wanted to introduce
a clear software architecture.

Starting from lowest level, there are:

  • Communication interface: Does the physical transfer, abstracts SPI, Parallel
    Mode, maybe I2C in the future.
    Filenames: "u8g_com_..."
  • Device/Controller level
    Contains display specific init sequence and data transfer.
    Connects to the com interface and defines the high level memory
    structure. Does (if required) the translation of the high level memory
    to controller level memory.
    So it does abstraction for parts of the memory architecture,
    init sequence and data transfer sequence.
    Filenames: "u8g_dev_..."
  • High level memory management (Page Buffer, pb)
    Takes care on the sub frame buffer handling inside the AVR,
    writes pixel values to the AVR RAM.
    In prinziple it does an abstraction of the write pixel functionality.
    Filenames: "u8g_pb..."

Memory Architecture:
Your request only affects the data transfer itself, so only the Device
level is affected. The high level memory management will be the same.

In the device "u8g_dev_st7920_128x64" the current code is:

	u8g_WriteByte(u8g, dev, 0x080 | y );      /* y pos  */
	u8g_WriteByte(u8g, dev, 0x080  );      /* set x pos to 0*/

this must be changed to:

	if ( y < 32 )
	{
		u8g_WriteByte(u8g, dev, 0x080 | y );      /* y pos  */
		u8g_WriteByte(u8g, dev, 0x080  );      /* set x pos to 0*/
	}
	else
	{
		u8g_WriteByte(u8g, dev, 0x080 | (y-32) );      /* y pos  */
		u8g_WriteByte(u8g, dev, 0x080 | 4);      /* set x pos to 64*/
	}

well, i am not sure about the "4" here.
I will create an issue for this and add the code to u8glib.

Thanks for your input!

Oliver

smultron:
Hello Oliver !

I can't get u8glib to work with my ST7920 display that is exactly similar to the DFRobot display.

I can't understand what is the correct pinout. In your wiki you give constructor as:

U8GLIB_ST7920_128X64(cs, a0 [, reset])

But in the lib examples (HelloWorld etc) it is given as:

U8GLIB_ST7920_128X64 u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9

Also, to my understanding A0 = RS ... but RS is also CS in this module for serial mode. So how can the constructor require both CS and A0 ?

I've tried several ways of hooking up the display, but I only get datarubbish on the screen.

Could you please clarify the pinout and constructor for ST7920 ?

My ST7920 display uses 2 wires for serial interface, not 4. The pin marked E (Enable when using the parallel interface) becomes SCLK, and the R/W pin becomes SDATA or MOSI. RS has to be set high, the datasheet says this is the CS pin but also says that SCLK and SDATA should not be toggled when the chip is not enabled.

Hi dc42

Yes, i just saw the problem with SPI mode. It is completly broken. Parallel mode is almost fine (see my post before).
The SPI mode is totally different what i saw with other controllers from the same company. I had to change bigger parts of the software.

Thanks,
Oliver

I have code to drive the display in SPI mode if you need it.