Cheap 128×64 graphic lcd (12864zw)

GLCD 128x64

GLCD 128×64

I bought me a cheap 128×64 graphic lcd on Ebay, cost me less then 7€ including shipping. It didn’t come with a datasheet or any instructions. After some googling, reading lots of websites and trying out a couple of different Arduino libraries I got it to work 🙂
I first needed to find out how to connect it to an Arduino. The glcd has no brand printed on it, there is just a type number printed on the back, 12864zw. Google came up with a datasheet from a Digole ST7920 LCD. This gave me a bit more information on how this thing works. The ST7920 chip supports parallel and synchronized serial interface (SPI) mode. You can choose which mode to use by setting the PSB pin high or low.
I first tried to get the lcd to work with the glcd Arduino library. This library uses the parallel mode to communicate with the lcd. You need most of the pins of an ATmega328 when using this mode. I could not get my lcd to work with the library. Maybe I made some mistake in the wiring.
I then switched to the U8glib and had some more luck. This library supports the parallel and SPI mode. I first tried the parallel mode and got it working. Then I used the hardware SPI mode of the Arduino to control the lcd. Using this mode you need only 3 pins (SCK, MOSI and CS) on the Arduino to control the lcd. This is how I connected the lcd to the Arduino:

GLCD pinout

GLCD pinout

On some lcd’s you need to connect the 5V to the blacklight through a resistor. My lcd seems to have those resistors on the PCB. I measured 20ohms between the BLK pin and the K pad (on the back of the board) and also between the BLA pin and the A pad.
Regulating the contrast of the lcd is normally done with a potentiometer. On the back of the PCB there are 3 pads for a potentiometer, unfortunately the potentiometer is not fitted to the board of my lcd. I tried using an external potentiometer by connecting one (outer) leg of the potentiometer to gnd, the middle pin of the pot to the Vo pin and the other leg of the pot to the Vout pin of the lcd. But it did not work, there are a couple of resistors/jumpers on the back of the pcb which make it impossible to make it work. Luckily the contrast seems to be fine with the current setup without the potentiometer.
The lcd also has a reset pin (RST), you can connect this to the reset pin of the Arduino. In my case it made it impossible to upload sketches to the Arduino with the reset pin connected. So I just left it unconnected, it doesn’t seem to make a difference to the lcd.
I tried the different example sketches that come with the U8glib library. In the beginning of the sketch you must create an u8g object. When using the hardware SPI port of the Arduino you only need to define the chipselect (CS) pin like this: U8GLIB_ST7920_128X64_1X u8g(10);
Now I only need to figure out how to display nice graphics on the lcd 🙂

37 responses to “Cheap 128×64 graphic lcd (12864zw)”

  1. Ramon

    Hi there,

    Good post 🙂
    I have same display i think…
    On the back of the display i see j7 next to R8 en its
    connected to the psb pin, did you solder
    jp7 ? it selects between serial and parallel ?
    When i solder this in serial or parallel must i ground
    the psb ?

  2. Ramon

    It works, thx

  3. Vlad

    Hello, I managed to connect the lcd using SPI on arduino duemilanove, but I cannot figure something out:

    1. What is the difference between hw spi and sw spi (if they are, what are the advantages or disadvantages);
    2. The lcd works only if I connect the VDD (pin 2 on lcd) to the 3.3 v on the arduino, else it all white (if I connect it to 5v);
    3. Why the V0 (contrast doesn’t work).;
    4. What is the difference between 512b and 128b version (in the device list on u8glib);

    The main mystery is question nr. 2.

    Thanks!

  4. Vlad

    Yep is the same, on the back it says 12864ZW, the only difference I guess is that I don’t use arduino code, I use C. What about the other questions?

  5. shads

    I think to change the contrast, it is necessary to select this resistor
    http://my.mail.ru/#photo=/mail/shad.s/_mypagephoto/23

  6. Neil Harding

    excellent guide got my working but now need to also find out a way of making nice graphics and text.

  7. Neil Harding

    just a quick question about this line
    When using the hardware SPI port of the Arduino you only need to define the chipselect (CS) pin like this: U8GLIB_ST7920_128X64_1X u8g(10);

    Some examples I see 3 ports defined. I’m I guessing 3 are used if using software SPI?

  8. Phil

    Hi,

    the Contrast of the LCD is not enough, my Display has Darken Background and more Darkener active Pixels. Not enough Contrast on V0 to VDD. Any Solution?

  9. Mike

    Hi, The external potentiometer will work, if the J1 is short.
    Reg: Mike

  10. Phil

    The Solution for my 12864zw was to set Contrast Voltage 5V+1V Vdd.

    I uses Voltage Doubler to Generate 10V for Potentiometer and the Contrast is White/Blue.

  11. FAHMI

    what is meant by VOUT, ​​and function

  12. Jan

    Hi! I have a very similar display to the one depicted here, but I am dealing with the strange problem: Whenever I connect PSB to the GND on Arduino UNO, both the display and the Arduino shuts down (the backlit on the display and leds on arduino go off). Only if PSB is connected to logical 1 or left floating, the Arduino stays on (as well as LCD backlight). However, to use SPI, I need to pug PSB to 0, as it is the pin that switches between serial (0) and paralel(1) interface and I’d like to use SPI to control the display.

    Has anybody encountered anything like this?

  13. Mike

    Hi Jan, maybe U mixed the wires. I’m sorry just not found the picture link, what I used. 1./Vss/ is go to the 20./Bl-K/ this goto the -power. 2./Vdd/ > 19./Bl-A/, and the + power. If U want use PSB mode the 15./Psb/ > 20. Now use only the 4. /RS/, 5/ R/W /, 6, /E/ signals. The pins goes direct to the chip without guard-resistor so only carefully.
    Reg:Mike

  14. Jan

    After some investigation I found out what the problem was: the display I was using was hardwired for parallel mode, with PSB pin connected to VDD with a 0-resistor. By connecting PSB to GND I effectively shorted +5v to GND with the results I described above. After I desoldered the resistor, everything started to work.
    Anyway, thanks for a nice tutorial, it helped me greatly!

    1. Dennis

      Hi Jan.

      I encountered the same problem. Having bought the display, I found out that there was no datasheet or electrical scheme present. I can see a couple of components in a row on the board, with r8, c5 and r9 occupied and r10 empty. Can you tell me which resistor you desoldered? That would save me a lot of research.

  15. Mike

    Hi, Welcome. If U wanna use the PSB mode must see one U8glib directory with the all subdirectories and sketch files. The skecth files contains the all display type’s drivers. “// devices with all constructor calls is here: http://code.google.com/p/u8glib/wiki/device
    //U8GLIB_NHD27OLED_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
    //U8GLIB_NHD27OLED_2X_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
    //U8GLIB_NHD27OLED_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9 …….and more. U must choose one if good for Ur display.

    Mine is working this type:”U8GLIB_ST7920_128X64_1X u8g(12, 11, 10); // SPI Com: SCK > E = 18, MOSI > r/w = 16, CS > RS = 15 This not an IC pin Nr, Its an I/O Nr. !!!!!!!!!!!!!! U can change the pins, if already used. Only change the Nr-s which have in the sketch. Reg:Mike

  16. Biswajit Das

    I am beginner in Arduino enviroment. I started to work with Arduino Uno Board and 128X64 graphical display.I got u8glib_arduino_v1.16.zip and started to compile.I copy the zip file “C:\arduino-1.0.5-r2-windows\arduino-1.0.5-r2\libraries” and added the zip file from sketch tab(Import library). But at the time of compiling I am getting the following errors:

    HelloWorld.ino: In function ‘void draw()’:
    HelloWorld:130: error: ‘u8g’ was not declared in this scope
    HelloWorld.ino: In function ‘void setup()’:
    HelloWorld:144: error: ‘u8g’ was not declared in this scope
    HelloWorld.ino: In function ‘void loop()’:
    HelloWorld:160: error: ‘u8g’ was not declared in this scope

    Plz give me feedback on this issue.

    Thanks&Regards
    Biswajit

  17. biswajit

    as per your instruction I have installed the library and its showed in file–exaple tab. I opened the “hello world” from examples but no sucess,again its show the following error—

    HelloWorld.ino: In function ‘void draw()’:
    HelloWorld:130: error: ‘u8g’ was not declared in this scope
    HelloWorld.ino: In function ‘void setup()’:
    HelloWorld:144: error: ‘u8g’ was not declared in this scope
    HelloWorld.ino: In function ‘void loop()’:
    HelloWorld:160: error: ‘u8g’ was not declared in this scope

    Plz provide the solution or any contact(mobile/land line/team viewer)

    Thanks
    Biswajit

    1. John P. Sigler

      did you uncomment the line to the device you are using near the beginning of the sketch? mine looks like this:

      …//U8GLIB_ST7920_128X64_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
      //U8GLIB_ST7920_128X64_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
      //U8GLIB_ST7920_128X64_1X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17
      U8GLIB_ST7920_128X64_4X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17
      //U8GLIB_ST7920_192X32_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
      //U8GLIB_ST7920_192X32_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
      //U8GLIB_ST7920_192X32_1X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17
      //U8GLIB_ST7920_192X32_4X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17

      the device you are using needs the ‘//’ deleted to uncomment, then compile and it should work.

  18. garphi

    Hi bajdi,
    I’ve read your article and I#m very glad, that you got it working in parallel and serial mode.
    I’m trying to connect the lcd in parallel mode (SPI is working, but a little bit to slow.) and stuck at the correct init of the lcd:

    #define d0 PA0 //PIN7
    #define d1 PA1 //PIN8
    #define d2 PA2 //PIN9
    #define d3 PA3 //PIN10
    #define d4 PA4 //PIN11
    #define d5 PA5 //PIN12
    #define d6 PA6 //PIN13
    #define d7 PA7 //PIN14
    #define en PB0 //PIN6 enable
    #define cs PB1 //PIN4 Chip select

    u8g_Init8Bit(&u8g, &u8g_dev_st7920_128x64_8bit, d0, d1, d2, d3, d4, d5, d6, d7, en, cs, U8G_PIN_NONE, U8G_PIN_NONE, U8G_PIN_NONE, U8G_PIN_NONE);

    Can you tell me how you’ve connected and init in parallel mode?

    Thx and best regards
    garphi

  19. Nitko

    thank you so much! you helped me!

  20. Angry Adam

    Just a general thought:
    Isn’t it totally ridiculous that dozens or hundreds of hobby-developers have to figure out the function of a “component” that was once designed by an engineer who obviously did NOT properly document (and publish) his design in any way?!?

  21. Nabin paudel

    hlw i need library file of glcd 12864ZW …please help..
    will library file of open glcd works for it..please give me some links or website toget this..thankyou

  22. vishal kakade

    How can i use this library for Stellaris launchpads( TM4c123GXL) on Energia environment which is arduino for ARM microcontrollers.

  23. Robert

    How can I initialise graphics mode, clear the screen, and display a small graphic
    bitmap line at location y, x?
    I read the digole 12864zw manual however examples are poor. I have a dotted display
    after trying some code on a PIC16F84A but it is just dotted mess of the whole screen.

  24. luigi andreoni

    Ciao

    scusa se ti disturbo ma non riesco a far funzionare questo LCD 128×64 con MPU6050 ho la possibilità di avere Arduino Mega 2560 e Arduino/ Genuino Uno

    Grazie

  25. EMMa

    #include
    #include
    #include
    #include
    U8GLIB_ST7920_128X64_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
    Servo myServo;
    uint8_t *buf;

    const int servoPin = 6;
    //for sonar
    const int triggerPin = 4;
    const int echoPin = 3;
    int distance;
    int locationOfObjects[180];
    void drawDial(int angle) {
    u8g.drawCircle(64, 24, 63, U8G_DRAW_ALL);//center(64,24) radius:63
    u8g.drawCircle(64, 24, 48, U8G_DRAW_ALL);//center(64,24) radius:48
    u8g.drawCircle(64, 24, 33, U8G_DRAW_ALL);//center(64,24) radius:33
    u8g.drawCircle(64, 24, 18, U8G_DRAW_ALL);//center(64,24) radius:18
    int x = 64 – 63 * cos(angle * 3.14 / 180);
    int y = 24 – 63 * sin(angle * 3.14 / 180);
    u8g.drawLine(64, 24, x, y);
    }
    void drawObjectLine(int value, int angle) {
    int x0 = 64 – 63 * cos(angle * 3.14 / 180);
    int y0 = 24 – 63 * sin(angle * 3.14 / 180);
    int x1 = 64 – value * cos(angle * 3.14 / 180);
    int y1 = 24 – value * sin(angle * 3.14 / 180);
    u8g.drawLine(x1, y1, x0, y0);
    }
    int getDistance() {
    long duration;
    digitalWrite(triggerPin, LOW);
    delayMicroseconds(2);
    digitalWrite(triggerPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(triggerPin, LOW);
    duration = pulseIn(echoPin, HIGH);
    // Calculating the distance
    return duration * 0.034 / 2;
    }
    void clearArray() {
    for (int i = 0; i < 180; i++) {
    locationOfObjects[i] = 0;
    }
    }
    void setup(void) {
    u8g.begin();
    myServo.attach(servoPin);
    Serial.begin(9600);
    }

    void loop(void) {
    for (int i = 0; i < 180; i++) {
    myServo.write(i);
    u8g.clearDisplay();
    drawDial(i);
    distance = getDistance();
    if (distance < 50) {
    locationOfObjects[i] = distance;
    } else {
    locationOfObjects[i] = 0;
    }
    for (int k = 0; k 0; i–) {
    Servo1.write(i);
    u8g.clearDisplay();
    drawDial(i);
    distance = getDistance();
    if (distance i; k–) {
    if (locationOfObjects[k]) {
    drawObjectLine(locationOfObjects[k], k);
    }
    }
    u8g.initDisplay();
    delay(50);
    }
    clearArray();
    }

    the code doesn’t comply iDONT KNOW WHY HELP PLEASE

Leave a Reply

*