How to use this 128X64 graphic LCD by Arduino UNO?

I am a beginner .
Now I got a 128x64 Chip on glass LCD , I want to light it up by Arduino uno to draw some characters and pic on it.

The question is the LCD driver ux IC 1705 needs 4 - wires serial protocol as the timing pic 1 shows.but how can I identify the OUTPUT PINS ( SCK , SDA) on Arduino( as pic 2 shows)?

if there is no way to do that directly how can I deal with it ? If yes please kindly provide me some advice, thanks a lot !


I do not see any photo but SDA = A4 & SCL=5 on UNO.
You need to find out the address for the display. Look for I2C scanner on Google or Arduino.cc.
Have you used I2C before ? You know the drill ?

raschemmel ,
thanks a lot , I am searching for I2C spec now. I didn't find any I2C protocol sample code for Arduino, if you know could mind give me some tips? I post the pictures again, hope it works this time :sweat_smile:


2.

3.

According to your latest diagram this is NOT I2C. It seems to be a SPI bus.

Moreover, the controller 1705 is not listed on the ultrachip page http://www.ultrachip.com/habout-100.html .
Maybe it is compatible (at least signal names look so) with the UC1701, which is in turn compatible with the ST7565.

SCK = clock signal of the SPI bus
SDA/SDI = data signal of the SPI bus
CD = Extra signal for the display to send data and command bytes
CS0 = Chip Select
RST = Reset Line

All in all, you might try U8glib for Arduino (Google Code Archive - Long-term storage for Google Code Project Hosting.) with the ST7565 or UC1701 constructor.

Oliver

Thank you very much, Oliver~!
I will try the lib and later update the news.
Here is the datasheet of[ UC 1705 if someone is interested in it , please check it. :slight_smile:

I had a quick look at the UC1705 datasheet. It seems to be almost identical to the UC1701. So i would say, any library for the ST7565 or UC1701 will work (except for memory layout and contrast which might need to be adjusted).

Oliver

Agreed.
Oliver is correct.

the OUTPUT PINS ( SCK , SDA) on Arduino( as pic 2 shows)?

"CS" would be the "SS" in a SPI interface and "SDI" is definately a SPI
signal . Note this quote from Tronixstuff Tutorial here:

Vdd connects to 5V, Vss to GND, CS to digital 10, SCK to digital 13, SDI to digital 11 and SDO to digital 12. Now let’s run through the available values of the MCP4162 in the following sketch:

If you refer to the attached pinouts of the UNO "digital 11" is the "MOSI" pin, so the SDI should go to "digital-11" on UNO.
The SCK obviously goes to digital-13 based on the UNO pinout illustration. That leaves "CD" as possibly the MISO signal
to digital-12 (see attached illustration)
Here's my guess:
SCK = UNO-pin-13 (clock)
SDA/SDI = UNO-pin-11 (data signal of the SPI bus)
CD = UNO-pin-12 (MISO)
CS0 = UNO-pin-10 (Chip Select)
RST = UNO- RESET

mcp4162pinout.jpg

Based on Figure 4 which you posted (from page 26 of the datasheet) it looks like you could just tie
the "CD" line HIGH and it would always assume the data is to be displayed and not a command.
If you plan to write commands to the controller specifically then you would need to use this line in your
code.

Based on Figure 4 which you posted (from page 26 of the datasheet) it looks like you could just tie
the "CD" line HIGH

"commands" are required to setup the display correctly and to define the x/y position of the data. Because of this, the controller needs full controll on the CD line. See page 12 of the datasheet, column "c/d" (3rd column). For example to set the contrast, the controller has to send the "set electronic volume" command, which requires the CD line to be zero.

Oliver

Right.
I see it.
If the uC needs to control it then it can't be the MISO signal, and all the other SPI signals are accounted
for so if this isn't the MISO then do you think it is not used for an LCD ?
Robert

For some strange historical reason these LCDs always need an additional signal to accept "command" input. In fact, this has been taken over to all modern OLED and TFT controllers. So the SPI communication needs four signals going from the uC to the LCD controller:

  • clock signal
  • serial data
  • c/d signal
  • chip select

This is also called "4-wire" SPI as mentioned on page 7 in the UC1705 data sheet.

There is also no MISO signal, so you can not read back any data from the controller in SPI mode. This also makes the programming somehow difficult.

Oliver

raschemmel:
Agreed.
Oliver is correct.

the OUTPUT PINS ( SCK , SDA) on Arduino( as pic 2 shows)?

"CS" would be the "SS" in a SPI interface and "SDI" is definately a SPI
signal . Note this quote from Tronixstuff Tutorial here:
Tutorial: Arduino and the SPI bus | tronixstuff.com

Here's my guess:
SCK = UNO-pin-13 (clock)
SDA/SDI = UNO-pin-11 (data signal of the SPI bus)
CD = UNO-pin-12 (MISO)
CS0 = UNO-pin-10 (Chip Select)
RST = UNO- RESET

thank you very much for you guys ! I learn a lot from the Tronixstuff Tutorial about SPI.h library, so far as my understanding
I have tried in this way:
SCK = UNO-pin-13 (clock)
SDA/SDI = UNO-pin-11 (data signal of the SPI bus)
CD = UNO-pin-7
CS0 = UNO-pin-10 (Chip Select)
RST = UNO- pin-6
vss = ground
vdd= 3.3 V

cuz I am totally a beginner so I try to write a sketch as my understanding of IC 1705 spec as below ,try to draw a 8-pixels line on the display somewhere(no idea about where ) :


#include "SPI.h"
const int CD=7; // set 7pin=CD
const int ss=10; //set 10pin=CS=ss
const int RST=6; //set 6pin= RST
void setup()
{
pinMode(ss, OUTPUT); // SET CS=ss, PIN10
pinMode(CD,OUTPUT);
pinMode(RST,OUTPUT);

//*********************************** try to initial thIS display as IC SPEC P35 sequence below:

digitalWrite(RST,LOW);
delay (1);
digitalWrite(RST,HIGH);
delay(5); // reset display
//***********************************
SPI.begin();
SPI.setBitOrder(MSBFIRST); // set MSB
digitalWrite(ss,LOW); // slave chip selected
digitalWrite(CD,LOW);//command mode

SPI.transfer(160);//set SEG
SPI.transfer(192);//set COM

SPI.transfer(32);
SPI.transfer(162);
SPI.transfer(129);
SPI.transfer(0);//set voltage

SPI.transfer(47);
SPI.transfer(160);//set power
SPI.transfer(175);//set display on

delay(100);

//********************************* initial finished

SPI.transfer(180); //set page of drawing address
SPI.transfer(17);//set column of drawing address

}

void loop()
{
digitalWrite(CD,HIGH);//data mode
SPI.transfer(228);// sent data to display ram as IC spec P35
digitalWrite(ss,HIGH); //finished transfer
}

There are my question :

  1. Should SPI.transfer ( ) only tranfers decimal number or how to write it to send other types of data?

for example : SPI.transfer(160);//set SEG ,
I intend to send command as below:

because of D7-D0: 1010,0000 = 160 decimal, is my interpretation right in this way?

power up sequence for reference:

  1. How to set the display column address ( -Y ) see ic spec P13 , command as blow , how to pick a specific column of pixels?

  2. Should all arduino sketches need a loop () function? what if I only want the program run for once? for display how to do it?

  3. As I uploaded this sketch on Arduino ,and display shows like this firstly then all pixels off after 2-3 seconds. pic shows later

I will keep trying thanks a lot.

olikraus:
For some strange historical reason these LCDs always need an additional signal to accept "command" input. In fact, this has been taken over to all modern OLED and TFT controllers. So the SPI communication needs four signals going from the uC to the LCD controller:

  • clock signal
  • serial data
  • c/d signal
  • chip select

This is also called "4-wire" SPI as mentioned on page 7 in the UC1705 data sheet.

There is also no MISO signal, so you can not read back any data from the controller in SPI mode. This also makes the programming somehow difficult.

Oliver

thanks a lot Oliver !

PART 1: Let me start to answer the none-display questions.

1010,0000 = 160 decimal, is my interpretation right in this way?

In C and C++ (which is the programming language used by Arduinos), all numbers are decimal unless they are prefixed with 0 (zero) or 0x (zero x).
If a number has an initial zero, then the number is interpreted as octal number. This means that "010" has the value 8!
If a number has an initial prefix of "0x" then the number is interpreted as hexadezimal value.
Actually i try to avoid octal numbers, but hexadezimal number are quite useful to send to a display controller.
So, 1010,0000 can be written as 0xa0 (or 0xA0) because four bits equal exactly one hexadecimal digit:
binary 1010 = hex a
binary 0000 = hex 0

  1. Should SPI.transfer ( ) only tranfers decimal number or how to write it to send other types of data?

SPI.transfer can transfer a value between 0 and 255. The range is important, but not the representation of the number.
It does not matter if you write SPI.transfer(160) or SPI.transfer(0xa0). In both cases a specific sequence of 8 bits is transfered.
You could also transfer a single letter: SPI.transfer('B') which is equal to SPI.transfer(66).

  1. Should all arduino sketches need a loop () function? what if I only want the program run for once? for display how to do it?

let me split this into three questions:

Should all arduino sketches need a loop () function?
Yes. I leave it as an excercise to you to try to compile without "loop()"

what if I only want the program run for once?
Put all your code into setup().

Microcontroller do have the ability to go to some shutdown mode in order to reduce power consumtion to a minimum, but i think this is beyond the scope of this thread.

for display how to do it?
Do what? If you just want to display something static until power is switched of, then put all your init and display code into "setup()". But for my own applications it is more like this:

setup() {
init display
output something to the user
}

loop() {
wait for some input
display something
// loop will start at the beginning and wait for some input again
}

If the input is a temperature sensor, then this could look like this:
loop() {
read temperature from sensor
display temperature
delay for 1 second
}

This wil update the display every second.

PART 2: Display specifc answers

First, i think you understood the concept of communication with the display controller. The code looks quite good regarding the setting of the command/data and the chip select line.

  1. How to set the display column address ( -Y ) see ic spec P13 , command as blow , how to pick a specific column of pixels?

Quick answer: Either the display vendor tells you this or you have to figure this out by testing and analysis.

Long answer:
For the display Chip on Glas module on your picture, probably three or four companies are involved:
Company 1: Creates the actual liquid crystal
Company 2: Creates the display controller (UC1705)
Optional Company B: Creates LED backlight
Company 3: Assembles the liquid crystal, the optional backlight and the display controller to something which is called COG Module.

The problem is: We do not know how company 3 has connected the display controller with the liquid crystal. For example:
The controller actually has 132x65 dots, but the liquid crystal only has 128x64. Which line and which colums are invisible? This is a decision that was taken by company 3 during the wiring of the two subcomponents.
Let as consider the binary value 1000,0000 at position 0 in the controller ram.
Upper left pixel of the 128x64 might be swithed on. But it might also be the lower left corner.
Also it might be the 7th pixel of the display on the top row if the byte order is swapped.
It might also be invisible if the liquid crystal if the crystal is connected to rows 1 to 65.
It might also be invisible if the liquid crystal is connected to colums 4 to 132.
But there might be also a pixel visible at position 3 if the lc is connected from 4 to 132 and the byte order is swapped.

This means: If company 3 does not provide you enough information, then you have to set some pixel on the screen do some reverse engineering how the interconnection between controller and crystal.

There are also several registers in the controller which allow you to setup the controller so that some parts of the swapping is done automatically (like SEG and COL direction).

This is my suggested procedure on an unknown LCD:
Step 1: Try to make something visible. This includes

  • Activate charge pump
  • Activate Display
  • Activate "all pixel on" mode or write some random pixels in the middle of the display
  • setup display contrast
  • activate other LCD parameters
    Step 2: Fine tuning
  • Figure out bit order
  • Analyse how the 128x64 is mapped to the 132x65 RAM area
  • Apply correct COM and SEG order

Of course a good datasheet from company 3 will tell you all these details :wink:

So my question: Do you see something on the screen already?

Oliver

olikraus:
PART 1: Let me start to answer the none-display questions.

1010,0000 = 160 decimal, is my interpretation right in this way?

In C and C++ (which is the programming language used by Arduinos), all numbers are decimal unless they are prefixed with 0 (zero) or 0x (zero x).
If a number has an initial zero, then the number is interpreted as octal number. This means that "010" has the value 8!
If a number has an initial prefix of "0x" then the number is interpreted as hexadezimal value.

gcc also supports binary constants by a leading 0b

so all these are the same value:
0b01011010 (binary)
0132 (octal)
90 (decimal)
0x5A (hex)
'Z' (ascii character)

--- bill

thank you very much , Bill!

olikraus:
PART 1: Let me start to answer the none-display questions.

1010,0000 = 160 decimal, is my interpretation right in this way?

In C and C++ (which is the programming language used by Arduinos), all numbers are decimal unless they are prefixed with 0 (zero) or 0x (zero x).
If a number has an initial zero, then the number is interpreted as octal number. This means that "010" has the value 8!
If a number has an initial prefix of "0x" then the number is interpreted as hexadezimal value.
Actually i try to avoid octal numbers, but hexadezimal number are quite useful to send to a display controller.
So, 1010,0000 can be written as 0xa0 (or 0xA0) because four bits equal exactly one hexadecimal digit:
binary 1010 = hex a
binary 0000 = hex 0

  1. Should SPI.transfer ( ) only tranfers decimal number or how to write it to send other types of data?

SPI.transfer can transfer a value between 0 and 255. The range is important, but not the representation of the number.
It does not matter if you write SPI.transfer(160) or SPI.transfer(0xa0). In both cases a specific sequence of 8 bits is transfered.
You could also transfer a single letter: SPI.transfer('B') which is equal to SPI.transfer(66).

  1. Should all arduino sketches need a loop () function? what if I only want the program run for once? for display how to do it?

let me split this into three questions:

Should all arduino sketches need a loop () function?
Yes. I leave it as an excercise to you to try to compile without "loop()"

what if I only want the program run for once?
Put all your code into setup().

Microcontroller do have the ability to go to some shutdown mode in order to reduce power consumtion to a minimum, but i think this is beyond the scope of this thread.

for display how to do it?
Do what? If you just want to display something static until power is switched of, then put all your init and display code into "setup()". But for my own applications it is more like this:

setup() {
init display
output something to the user
}

loop() {
wait for some input
display something
// loop will start at the beginning and wait for some input again
}

If the input is a temperature sensor, then this could look like this:
loop() {
read temperature from sensor
display temperature
delay for 1 second
}

This wil update the display every second.

PART 2: Display specifc answers

First, i think you understood the concept of communication with the display controller. The code looks quite good regarding the setting of the command/data and the chip select line.

  1. How to set the display column address ( -Y ) see ic spec P13 , command as blow , how to pick a specific column of pixels?

Quick answer: Either the display vendor tells you this or you have to figure this out by testing and analysis.

Long answer:
For the display Chip on Glas module on your picture, probably three or four companies are involved:
Company 1: Creates the actual liquid crystal
Company 2: Creates the display controller (UC1705)
Optional Company B: Creates LED backlight
Company 3: Assembles the liquid crystal, the optional backlight and the display controller to something which is called COG Module.

The problem is: We do not know how company 3 has connected the display controller with the liquid crystal. For example:
The controller actually has 132x65 dots, but the liquid crystal only has 128x64. Which line and which colums are invisible? This is a decision that was taken by company 3 during the wiring of the two subcomponents.
Let as consider the binary value 1000,0000 at position 0 in the controller ram.
Upper left pixel of the 128x64 might be swithed on. But it might also be the lower left corner.
Also it might be the 7th pixel of the display on the top row if the byte order is swapped.
It might also be invisible if the liquid crystal if the crystal is connected to rows 1 to 65.
It might also be invisible if the liquid crystal is connected to colums 4 to 132.
But there might be also a pixel visible at position 3 if the lc is connected from 4 to 132 and the byte order is swapped.

This means: If company 3 does not provide you enough information, then you have to set some pixel on the screen do some reverse engineering how the interconnection between controller and crystal.

There are also several registers in the controller which allow you to setup the controller so that some parts of the swapping is done automatically (like SEG and COL direction).

This is my suggested procedure on an unknown LCD:
Step 1: Try to make something visible. This includes

  • Activate charge pump
  • Activate Display
  • Activate "all pixel on" mode or write some random pixels in the middle of the display
  • setup display contrast
  • activate other LCD parameters
    Step 2: Fine tuning
  • Figure out bit order
  • Analyse how the 128x64 is mapped to the 132x65 RAM area
  • Apply correct COM and SEG order

Of course a good datasheet from company 3 will tell you all these details :wink:

So my question: Do you see something on the screen already?

Oliver

Oliver,
Thank you so much for your time to give me such a detail answer! I really appreciate of it ! Here are 2 pics I tried by former sketch on Arduino . Pic 1 show when the power on , some horizontal lines appeared , after 2-3 seconds , they all faded away gradually .
I think that is abnormal . I will keep trying and update news.
Thanks a lot!

pic 1:

pic2:

You might try touching up the solder connections , preferably with some flux, either liquid or paste, until
they look smooth, and uniform and shiny. Be careful not to heat up the pad any longer than necessary,
(1 or 2 seconds should be enough).

It could be also an issue with the capacitors. I have not seen them on any of your pics, but you usually need two external 1uF ceramic caps (see page 6 of the 1705 manual).

Oliver

That's a good point. Do you have any 0.1uF or 1uf decoupling caps connected across your power to the display ?
(4.7uF to 10uF would be better)