Pages: 1 2 [3] 4   Go Down
Author Topic: ST7920 Interface Question  (Read 12936 times)
0 Members and 1 Guest are viewing this topic.
Finland
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

in my case it was a question of EN timing.

I started looking at whats going on through my logic analyzer. I've now crushed the EN toggle period to 4microseconds = 244 theoretical frames per second.

Time to start slowing the code down. I think I'll have to eat my words about the 7920  smiley-red
Logged

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 70
Posts: 2763
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

To be able to compare FPS numbers,
I think it would it make sense to define some reproducible "FPS" operations
that represent what is done on each "frame".

That way we can actually compare equivalent operations across libraries and glcd modules.

How about any of these or even some combination of multiple ones.

a) render a full display bitmap
b) clear the display (might be done in s/w or by the module itself)
c) turning on all pixels, one pixel at a time.
   (might even want to do two of these as painting horizontally might be different than vertically)
d) render a full display of text in a natural font size like 6x8 or 8x8
 (maybe pick a single character like '@' so that everyone is rendering the same character).


I think it would be very interesting to be able to really compare between
libraries, glcd modules, and even different interface modes on the same module.

It would be pretty simple to do a or a and b together to offer at least one FPS data point
that could be compared.

--- bill
Logged

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1551
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good idea. The display size should be mentioned. Maybe the FPS should be scaled to a virtual 64x64 display:
If mFPS is the measured FPS rate and w and h are the display dimensions, then a comparable, size independent iFPS might be

iFPS = mFPS * 64 * 64 / (w * h)

Oliver
Logged

Finland
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, the results are in.

ST7920 - 25.6 frames per second in constant clear screen operation (toggle between B&W by writing whole screen to GRAM)

Soooo ... it is not a bad display after all, and in the morning I was like it ain't ever gonna work  smiley-mr-green

Edit: Pinout Screen to Arduino Nano 328 in case someone wants to try it out
No guarantees ! Use on your own risk !

VSS -> GND
VDD -> +5
V0 -> NC
RS -> pin A0
RW -> pin A1
E -> pin A2
D0...D3 -> pin 8-11
D4...D7 -> pin 4-7
PSB -> high (Parallel / Serial bus select)
RST -> high (reset)
VOUT -> NC
BLA -> +5
BLK -> GND via 200 ohm resistor
 
Measured with logic analyzer and done with parallel interface and the following code:

Code:

#include <avr/io.h>
#include <util/delay.h>

#define LCD_ON 0x0C
#define LCD_OFF 0x08
#define LCD_SET_PAGE        0x80 // X-address
#define LCD_SET_ADD 0x80 // y-address
#define LCD_RAM_ADDRESS_MODE 0x02
#define LCD_FUNCTION_SET_EXT 0x36
#define LCD_FUNCTION_SET_BASIC 0x30
#define LCD_CURSOR_CONTROL_SET 0x18
#define LCD_DISP_CLEAR        0x01
#define LCD_ENTRY_MODE_SET        0x06 // Display cursor shift left to right, page shift scroll down

#define DI           14 // same as RS, PORT C, bit 0
#define RW           15 // PORT c, bit 1
#define EN           16 // PORT c, bit2
// RESET ... straight to high

void setup() {
  Serial.begin(9600);  
  DDRD = DDRD | B11110000; // pins d7-d4 to output
  DDRB = DDRB | B1111; // pins d8 to d11 to output
  DDRC = DDRC | B111; // pins A0 to A2 to output
  digitalWrite(DI, LOW);
  initlcd();
}

void initlcd(void) {
  delay(50);
  WriteCommand(LCD_FUNCTION_SET_BASIC);
  _delay_us(100);  
   WriteCommand(LCD_FUNCTION_SET_EXT);
  _delay_us(100);  
  WriteCommand(LCD_ON);
  _delay_us(100);
  WriteCommand(LCD_DISP_CLEAR);
  delay(50);  
  WriteCommand(LCD_ENTRY_MODE_SET);
}

void WriteCommand(byte cmd)
{
  PORTC = B100; // EN | RW | DI
  _delay_us(7);
  lcdDataOut(cmd);
  _delay_us(10);
  PORTC = B000; // EN | RW | DI
  _delay_us(30);
}

void WriteData(byte data) {
  PORTC = B101; // EN | RW | DI  
  _delay_us(3);
  lcdDataOut(data);
  _delay_us(5);
  PORTC = B001; // EN | RW | DI
  _delay_us(25);
}

void lcdDataOut(byte data) {  
  byte dataD = data & B11110000; //bits 7 to 4 for pins 4-7
  byte dataB = data & B1111; //bits 3 to 0 for pins 8-11
  PORTB &= B11110000;
  PORTB |= dataB; //
  PORTD &= B00001111;  
  PORTD |= dataD; //lower nibble of 8 bits
}

void loop() {
        for (int i = 0; i < 32; i++) {
        WriteCommand(LCD_SET_PAGE | i);
        WriteCommand(LCD_SET_ADD);
          for (int j =0; j < 16 ; j++) {
              WriteData(0xFF);
              WriteData(0xFF);
          }
        }
        for (int i = 0; i < 32; i++) {
        WriteCommand(LCD_SET_PAGE | i);
        WriteCommand(LCD_SET_ADD);
        for (int j =0; j < 16 ; j++) {
          WriteData(0x00);
          WriteData(0x00);
        }
       }
}
« Last Edit: January 24, 2012, 08:22:28 pm by smultron » Logged

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 76
Posts: 2247
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all, have just done a bit of testing on my library, anybody else having some problems with the display being to slow?

I'm controlling the display via shift registers and animation is too fast for the screen to fully illuminate its pixels. In fact without a delay the pixels barley change colour.

Has anybody suffered this same fate ( need faster screen, to keep up with arduino ) or is it due to contrast. I have a POT connected to 5v and GND with the wiper going to backlight anode. What is the proper way to do contrast on these displays as this just dims the backlight. Pixels to backlight contrast is still equal.

The only Identifiying marks my screen has is 'HJ12864ZW' and the datasheet is entirely in chinese, So I have had to use the generic ST7920 datasheet.

BTW: my screen is a blue screen with white pixels. Anyone with pictures of the ST7920 rendering an animated sprite?

And also, is the power supply speed ( arduino 5v ) a  possible culprit ( not enough juice to quickly illuminate pixels ). would a bypass capacitor help accross the Vdd - Vss kind of like IC decoupling?
« Last Edit: January 24, 2012, 09:53:24 pm by pYro_65 » Logged


Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 70
Posts: 2763
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good idea. The display size should be mentioned. Maybe the FPS should be scaled to a virtual 64x64 display:
If mFPS is the measured FPS rate and w and h are the display dimensions, then a comparable, size independent iFPS might be

iFPS = mFPS * 64 * 64 / (w * h)

Oliver

ooooo. I really like that.
But I think the math is flipped?
Shouldn't it be
iFPS = mFPS * (w*h) / 64*64

I think  the "virtual" 64x64 display FPS rate should be double the measured rate with a 128x64 display right?

This would be useful even for some of the sed1520 displays the glcd library supports
that are 120x32 or 122x32

While things don't scale exactly linearly for different sizes,
it is about as good as it gets for comparisons of dissimilar displays.

--- bill

Logged

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1551
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, yes, thanks for the correction.

Oliver
Logged

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 70
Posts: 2763
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, so the FPS and iFPS (64x64) got me really curious.
I went and tested the glcd library on a ks0108 just to see how it compared
to the ST7920.
(I wrote a nifty little iFPS sketch that does the calculations)

With glcd on a 128x64 ks0108 using a clearscreen FPS test:
FPS = 79.08
iFPS = 158.16

glcd was using 8 bit direct port i/o driving all the glcd lines
(using nibbles on two ports vs 8 bits on single port slowed it down by 8 FPS)
glcd also uses delays with more accurate timing to match glcd spec timing
like Tas and Tdsw rather than using longer delays using <util/delay.h>
<util/delay.h> has many issues in its delay cycle calculations.
If you don't have the very latest AVRlibC you can get delays
that are many times longer or shorter than you ask for depending
on what you ask for and the F_CPU value.
This effect is worst at the low end like sub 3-5us which is where
these kinds of delays often are.

glcd uses Hans Hendriech's delay_x delay package instead.

So I think getting an FPS of 25.6 using much longer than needed timing delays
for control line setup, data hold times and strobe widths is actually quite good.

If the delays in WriteData() and WriteCommand() were
cut down closer to the spec, the fame rate would go up.

--- bill

Logged

Finland
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

glcd also uses delays with more accurate timing to match glcd spec timing
like Tas and Tdsw rather than using longer delays using <util/delay.h>
<util/delay.h> has many issues in its delay cycle calculations.
...
If the delays in WriteData() and WriteCommand() were
cut down closer to the spec, the fame rate would go up.

Oops. I was looking at the datasheet a bit better this morning. The delays were indeed ns not us... oh well, that's a bit embarrassing. But its nice to know there is still easy room for improvement.

The purpose of the test was to see quickly whether this display is a completed dud. Now I'm confident something can be made of it, and getting rid of the crude delay is the next thing to do.
« Last Edit: January 25, 2012, 03:52:19 am by smultron » Logged

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 76
Posts: 2247
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Can one of you please post a picture of it refreshing at or above 15 - 20 fps?
From 10 frames to 40 frames per second on my screen ( slowed with delays ), a 64x64 block is pretty much invisible as it scrolls across or down the screen.
Is anyone intending to use it for animation. I ask as I'm not sure weather it is my screen that is really slow or if all st7920 models are ( not the st7920 driver but actual display ).
Please see my post above...

Maybe I just need to purchase a green-black one as they might be faster ( mine is blue bg & white px ).
Logged


United Kingdom
Offline Offline
Tesla Member
***
Karma: 227
Posts: 6639
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You're right, the liquid crystal in the display doesn't react fast enough for animation. I refresh the data on mine (while on blue) at 2 fps, because it takes around 0.5 sec for the display contrast to settle when the pixels change.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1551
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bill, can you publish your code for the FPS measurement?
I would like to know how to calculate the overall FPS rate.

Thanks,
Oliver
Logged

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1551
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here are some results from u8glib:

  ST7920_192X32, SPI:    FPS: Box=7.6   @=9.8                iFPS: Box=11.4  @=14.7
  ST7920_192X32, 8Bit:   FPS: Box=6.2   @=7.5                iFPS: Box=9.3 @=11.2
  DOGM128 SW SPI:         FPS: Box=5.1   @=5.9               iFPS: Box=10.2 @=11.8
  DOGM128 HW SPI:         FPS: Box=5.5   @=6.3               iFPS: Box=11.0 @=12.6

The "Box" mode is what Bill has measured. I also added the @-draw test.
Not a surprise: U8glib is much slower. But it also supports write-only devices without the need of a full frame buffer.

Oliver
Logged

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 70
Posts: 2763
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

One of the things that glcd lib does, which is what makes the rendering code, especially for text
so complex is that it will avoid reads of display memory whenever possible.

For example, when rendering, it renders or paints pixels into a local 1 byte register
that is used as a 1 byte page buffer and then writes that byte to page memory.
Whenever the size of what is to be rendered is a multiple of the page size (8 pixels)
and aligns on a page boundary (8 pixels) then there will be no reads.

When clearing the screen, there are no reads from memory just writes to the glcd memory.
There will also be no reads from glcd/frame-buffer memory if rendering text that is 8, 16, 24, 32, ...
pixels in height that land on a vertical modulo 8 pixel boundary.
Nor would there be any reads from memory to render a bitmap that is a multiple of 8 pixels in height
and lands on a vertical module 8 pixel boundary.

While this is very fast and works great to eliminate reads, this rendering method only works
well for devices that use 8 pixel vertical pages. It also doesn't allow doing things like changing the x,y origin,
rotating the display orientation, or rotating the actual text.

In the big picture, once you get much beyond 4-5 FPS, it's pretty much ok since
the liquid crystal in the display often takes a while to change anyway.
The biggest thing is does the user notice any lag in the display being updated
or does it slow down the CPU to prevent it from getting its other tasks done.


--- bill


Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bumping this topic.

Has anybody suffered this same fate ( need faster screen, to keep up with arduino ) or is it due to contrast. I have a POT connected to 5v and GND with the wiper going to backlight anode. What is the proper way to do contrast on these displays as this just dims the backlight. Pixels to backlight contrast is still equal.

The only Identifiying marks my screen has is 'HJ12864ZW' and the datasheet is entirely in chinese, So I have had to use the generic ST7920 datasheet.

I have the same screen and the same problem. Pot wiper to v0 won't do anything, in fact, I haven't been able to change contrast at all.

The datasheet says "VLCD (V0 to VSS): max 7V". Also, under "DC characteristics": VLCD (LCD Voltage) Test condition:V0-VSS 3.0-7V .

Can anybody give me a clue?

Thanks!
Logged

Pages: 1 2 [3] 4   Go Up
Jump to: