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:
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 🙂
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 ?
I didn’t solder anything on the pcb. The PSB pin must be grounded for serial communication.
It works, thx
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!
Are you sure you have the same lcd as mine? Mine works perfectly when VDD is connected to 5V.
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?
Hardware SPI needs a lot less mcu cycles then software.
Why the contrast doesn’t work is because of the circuitry on the lcd. It’s something I will try to figure out. If you look at the back of the lcd you will see the VO pin is connected to R12 but there is no resistor soldered there. So the VO pin in not connected to anything… I don’t know if just soldering a resistor will do the trick.
No idea about the different versions of the u8glib. I’m just happy that I managed to display some data on the lcd, wasn’t sure about that when I bought it 🙂
http://www.youtube.com/watch?v=0Qhly-ibOsk
I think to change the contrast, it is necessary to select this resistor
http://my.mail.ru/#photo=/mail/shad.s/_mypagephoto/23
excellent guide got my working but now need to also find out a way of making nice graphics and text.
I’ve only used mine to display text for my MP3 alarm clock 🙂 You can find the code here: http://www.bajdi.com/arduino-mp3-alarm-clock/
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?
That is correct 🙂
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?
Hi, The external potentiometer will work, if the J1 is short.
Reg: Mike
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.
what is meant by VOUT, and function
Search google for the datasheet of the Digole 12864zw. It has the information of all the pins.
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?
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
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!
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.
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
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
Learn how to install libraries … http://arduino.cc/en/Guide/Libraries
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
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.
Contact the author of the library.
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
Sorry it’s over 2 years ago since I used the display, can’t remember how I made it work in parallel mode.
thank you so much! you helped me!
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?!?
You have the choice of buying a cheap undocumented component from China or paying a multiple from a decent manufacturer that comes with full documentation.
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
How can i use this library for Stellaris launchpads( TM4c123GXL) on Energia environment which is arduino for ARM microcontrollers.
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.
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
#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