Introduction: LCD COG for an Arduino Nano

This Instructable describes how to use a COG LCD with an Arduino Nano.

COG LCD displays are cheap but are slightly harder to interface. (COG stands for "Chip On Glass".) The one I'm using contains a UC1701 driver chip. It requires only 4 pins of the Arduino: SPI-clock, SPI-data, chip-select and command/data.

The UC1701 is controlled by the SPI bus and runs at 3.3V.

Here I decribe how to use it with an Arduino Nano. It should also work with an Arduino Mini or Uno - I'll try it soon.

This is my first Arduino project and I haven't written C in decades so if I'm making any obvious mistakes, please let me know.

Step 1: Building the Hardware

Buy a COG LCD that contains a UC1701 chip. It should be using the SPI bus rather than a parallel interface. It will have around 14 pins which will be labelled with names like those listed below. (You don't want a parallel interface with lots more pins labelled D0, D1, D2 ...)

The one I bought is: Or you can search eBay for "12864 LCD COG".

Choose one that has a fairly wide tail with pins spaced at 1.27mm - finer pins will be hard to solder. Make sure it has a a UC1701 chip. Notice how in the sixth picture on the ebay page, it says "CONNECTOR: COG/UC1701".

The display is transparent and it's hard to know which is the front and back. Study my pictures carefully. Notice where pins 1 and 14 are - they're marked on the tail.

The flexible tail is quite easy to solder but it requires an adapter so you can plug it into a breadboard. I bought: Or you can search eBay for "Adapter Smd SSOP28 DIP28".

The adapter takes a 28-pin SOP chip on one side or a 28-pin SSOP chip on the other side. An SOP chip has a pin spacing of 0.05" (1.27mm) which is the same as the tail of the LCD.

You will also need some header pins. Whenever I buy an Arduino or other module, it comes with more header pins than are needed so you probably already have some. Otherwise, search eBay for "2.54mm header pins".

Solder 14 of the header pins onto the adapter. Don't push them all the way through - it's nicer if the back of the adapter is flat. Put it flat on your bench so the pins can't be pushed too far into the holes. Make sure the pins are on the SOP side of the board (i.e. the bigger chip).

The pads of the tail are in a sort of window. Tin both sides of them with solder. Tin the pads of the adapter. Hold the tail of the adapter in place then touch each pad with the soldering iron (you'll need a fairly fine tip).

Tie some thread through the holes in the adapter to act as strain relief. (I used "transformer wire").

If you solder it on the wrong way round, don't try to unsolder the tail. Take the pins out one at a time and move them to the other side of the board. (Yes, I made that mistake and re-soldered the tail which is why it's a bit of a mess in the photo.)

Step 2: Connecting to the Arduino

This section explains how to connect to an Arduino Nano. It will be very similar for a Mini or Uno but I haven't tried it yet.

Study the circuit diagram.

An Arduino Nano that is connected to a USB port runs at 5V. The LCD runs at 3.3V. So you need to power the LCD from the 3V3 pin of the Nano and to reduce the voltage on each control pin from 5V to 3.3V.

The pinout of the LCD is:

  • 1 CS
  • 2 RST
  • 3 CD
  • 4
  • 5 CLK
  • 6 SDA
  • 7 3V3
  • 8 0V Gnd
  • 9 VB0+
  • 10 VB0-
  • 11
  • 12
  • 13
  • 14

CS is Chip-Select. It is pulled low to select (enable) the UC1701 chip. (CS might be called CS0 or En or similar.)

RST is Reset. It is pulled low to reset the chip. (RST might be called Reset.)

CD is command/data. It is pulled low when sending commands to the chip over SPI. It's high when sending data. (CD might be called A0.)

CLK and SDA are the SPI bus pins. (SDA might be called SPI-Data. CLK might be SCL or SPI-Clock.)

VB0+ and VB0- are used by the internal charge pump of the UC1701. The charge pump generates the odd voltages needed by the LCD. Connect a 100n capacitor between VB0+ and VB0-. The UC1701 documentation recommends 2uF but I couldn't see a difference with this particular LCD.

If your LCD has VB1+ and VB1- pins, also connect a 100n capacitor between them. (If your LCD has a VLCD pin, you can try connecting a 100n capacitor between VLCD and Gnd. It made no difference with my LCD.)

Connect the LCD to the Nano as follows:

  • 1 CS = D10 *
  • 2 RST = D6 *
  • 3 CD = D7 *
  • 5 CLK = D13 *
  • 6 SDA = D11 *
  • 7 3V3 = 3V3
  • 8 0V = Gnd

( "*" means use a potential divider to reduce the voltage. If the Arduino is running at 3V3 from an independent supply, you won't need the resistors.)

3.3V is output by the Nano and can provide sufficient current for the LCD. (The display draws around 250uA.)

5V is also output by the Nano and can be used to power the backlight. Limit the current to the backlight with a 100ohm resistor.

If you are running short of pins on the Nano, you can connect RST to 3V3 - then you can use D6 for something else. The U1701 can be reset in software by a command on the SPI. I've never had any trouble with that but if you are using your own circuit in a noisy environment, it may be better to use a hardware reset.

Step 3: Software

In theory, you can drive the UC1701 from the U8g2 library (or Ucglib or the other libraries available). I struggled for days to get it to work and failed. The U8g2 library is a monster because it can drive a huge variety of chips and it's very hard to follow the code. So I gave up and wrote my own smaller library. It takes up a lot less space in the Arduino (approx 3400 bytes plus fonts).

You can download my library from here (the Download button on this page). A sample sketch and a user guide are included. The web page describes how to import a library; go to the "Importing a .zip Library" section.

Initialise the LCD with

  • UC1701Begin();

UC1701Begin can take parameters to change the pins or to ignore the RST pin. The library only uses hardware SPI (a software SPI is not provided). The display can be flipped in the x and y axes. That's useful if you want to mount the LCD in a different orientation.

Several procedures have been duplicated from the U8g2 library:

  • DrawLine
  • DrawPixel
  • DrawHLine
  • DrawVLine
  • DrawBox
  • DrawFrame
  • DrawCircle
  • DrawDisc
  • DrawFilledEllipse
  • DrawEllipse
  • DrawTriangle
  • UC1701SetCursor
  • UC1701ClearDisplay

Some procedures are slightly different:

  • void DrawChar(uint8_t c, word Font);
  • void DrawString(char * s, word Font);
  • void DrawInt(int i, word Font);

String drawing procedures are passed the index of a Font. Fonts are declared in the flash memory of the Arduino so they are not occupying precious SRAM. Three fonts are provided (small, medium and large). They are only linked in and occupy flash memory if you use them (approx 500 to 2000 bytes each).

"Colour" is handled differently from the U8g2 library. When the LCD is cleared it has a dark background. If MakeMark (a global variable) is true, drawing is done in white. If MakeMark is false, drawing is done in dark.

Some procedures are unique to the UC1701:

SetInverted draws in black-on-white rather than white-on-black.

  • void SetInverted(bool inv);

The brightness and contrast of UC1701 are set by:

  • void SetContrast(uint8_t value); // suggested is 14
  • void SetResistor(uint8_t value); // suggested is 7

They work together in a rather unsatisfactory way.

SetEnabled powers down the LCD:

  • void SetEnabled(bool en);

The display takes 4uA when sleeping. You should also turn off the backlight - drive it from a pin of the Nano. After re-enabling, the UC1701 will have been reset; the display is cleared and the Contrast and Resistor will have been reset to their default values.

So, in conclusion, COG displays are cheap and a decent size. They're easy to connect to an Arduino.