How to interface a 3.18 inch 128x64 COG LCD with Arduino?

By admin

How to Interface a 3.18 inch 128x64 COG LCD with Arduino

To interface a 3.18 inch 128x64 cog lcd display with an Arduino, you need to wire the SPI pins, install the right library, and run a graphic test sketch. This display uses a COG (Chip-On-Glass) design with the ST7565R controller, which drives 128 columns and 64 rows. The SPI interface requires four lines: SCK (clock), MOSI (data), CS (chip select), and A0 (data/command select). The backlight runs on a separate pin, typically controlled with a PWM-capable pin for brightness adjustment. The display operates at 3.3V logic, but most Arduino boards like the Uno or Mega output 5V logic, so you need level shifters or a voltage divider on the SPI lines to avoid damage. The ST7565R controller supports a contrast voltage range from 0 to 63, adjustable via software, and the display draws about 10-15 mA with the backlight off, and up to 50 mA with full backlight on. The pixel pitch is 0.48 mm, giving a viewing area of 81.5 mm by 40.5 mm, and the COG construction reduces the overall thickness to about 2.5 mm, making it suitable for embedded projects where space is tight.

Wiring the Display to Arduino

Connect the display pins to the Arduino as follows: VCC to 3.3V, GND to GND, SCK to pin 13 (on Uno), MOSI to pin 11, CS to pin 10, A0 (also called RS or DC) to pin 9, and RESET to pin 8. The backlight anode goes to pin 6 through a 100-ohm resistor, and the cathode to GND. If you use a 5V Arduino, you must add a 1k resistor in series on each SPI line to drop the voltage to safe levels for the 3.3V display. Alternatively, use a 3.3V Arduino board like the Arduino Due or a Pro Mini 3.3V version. The display's contrast pin (V0) is internally connected to a potentiometer in most modules, but you can also adjust it via the software command lcd.setContrast(30) for a typical setting. The ST7565R datasheet specifies a minimum supply voltage of 2.7V and maximum of 3.6V, so staying within 3.3V is critical. The SPI clock speed should be set to 4 MHz or lower, as higher speeds can cause data corruption due to the display's internal timing. I recommend using a 4 MHz SPI clock for reliable operation.

Installing the Required Library

The most common library for this display is the U8g2 library by olikraus, which supports the ST7565R controller with the 128x64 resolution. You can install it via the Arduino Library Manager by searching for "U8g2" and selecting version 2.34 or later. The library includes multiple constructors; for the 3.18 inch COG display, use U8G2_ST7565_12864_F_4W_SW_SPI for software SPI or U8G2_ST7565_12864_F_4W_HW_SPI for hardware SPI. The hardware SPI version uses the default SPI pins on the Arduino, which are pin 11 for MOSI and pin 13 for SCK on the Uno. If you use software SPI, you can define any pins, but it runs slower. The library also handles the contrast setting, font selection, and pixel-level drawing. The U8g2 library supports over 1000 fonts, from small 5x7 pixel fonts to large 32x64 pixel fonts, which is useful for displaying text and graphics. The library also includes a drawPixel() function for custom graphics, and you can use sendBuffer() to update the display after drawing. The buffer size is 1024 bytes (128x64/8), which fits in the Arduino Uno's 2KB SRAM, but you can also use the U8G2_ST7565_12864_1_4W_SW_SPI constructor for a 1/4 page buffer to save memory if you run out of RAM.

Writing the Initialization Sketch

Open the Arduino IDE and create a new sketch. Include the U8g2 library with #include and #include if using hardware SPI. Define the constructor as U8G2_ST7565_12864_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); for hardware SPI. In the setup() function, call u8g2.begin() to initialize the display, then set the contrast with u8g2.setContrast(30). The begin() function sends the initialization sequence to the ST7565R, which includes setting the bias voltage to 1/9, the booster circuit to on, and the column and page addresses. The display's default refresh rate is 60 Hz, but you can adjust it via the setDisplayMode() function. After initialization, clear the buffer with u8g2.clearBuffer() and draw a test pattern like a rectangle or text. The u8g2.firstPage() and u8g2.nextPage() loop is used for drawing multiple elements. For example, to draw a filled rectangle, use u8g2.drawBox(10, 10, 50, 30) and then u8g2.sendBuffer(). The library also supports drawing circles, lines, and bitmaps. The ST7565R controller has a built-in voltage generator for the LCD bias, so you don't need an external negative voltage supply. The contrast voltage is generated internally, and the range is from 0 (lowest contrast) to 63 (highest contrast). At setting 30, the display is readable in typical indoor lighting, but you may need to adjust it based on the viewing angle and ambient light.

Displaying Text and Graphics

To display text, use the u8g2.setFont() function to select a font, then u8g2.drawStr(x, y, "Hello") to draw a string at pixel coordinates (x, y). The font size affects the placement; for example, the u8g2_font_5x7_tf font has a height of 7 pixels, so the baseline is at y+7. The display supports both proportional and monospaced fonts. For graphics, you can draw a bitmap using u8g2.drawXBMP(x, y, width, height, bitmap), where the bitmap is an array of bytes. The bitmap data must be in vertical byte order, which is the standard for monochrome LCDs. You can convert images to this format using online tools like the "LCD Image Converter" or the "Image2LCD" utility. The display's pixel response time is about 10 ms, so it can update at around 100 Hz for simple patterns, but the SPI bus speed limits the full frame rate to about 30 Hz when sending a full 1024-byte buffer at 4 MHz. The U8g2 library includes a setFlipMode() function to rotate the display 180 degrees, which is useful if the display is mounted upside down. The display also supports partial updates using the setPage() function, but this is rarely needed for most applications.

Adjusting Contrast and Brightness

The contrast is controlled by the setContrast() function, which takes a value from 0 to 63. The default value is 32, but you may need to adjust it based on the temperature and viewing angle. The ST7565R datasheet specifies that the contrast voltage is temperature-compensated, but the compensation is not perfect, so you might need to adjust the value in software. The backlight brightness is controlled by a PWM signal on the backlight pin. Use the analogWrite() function on the backlight pin (pin 6) with a value from 0 to 255. For example, analogWrite(6, 128) sets the brightness to 50%. The backlight LED has a forward voltage of about 3.0V and a current rating of 20 mA, so a 100-ohm resistor in series limits the current to about 3 mA at 3.3V, which is safe. If you use a 5V supply, the resistor should be 220 ohms to limit the current to 9 mA. The display's backlight is a white LED, with a color temperature of around 6000K, and it provides even illumination across the viewing area. The contrast and brightness settings can be stored in EEPROM and loaded at startup to maintain a consistent look.

Handling Common Issues

One common issue is the display not initializing, which is often due to incorrect wiring or voltage levels. Check that the CS pin is pulled high when not in use, and that the RESET pin is held high for at least 1 ms after power-up. The ST7565R requires a reset pulse of at least 1 microsecond, which the begin() function handles automatically. If the display shows random pixels, the SPI clock speed might be too high; reduce it to 2 MHz or use software SPI. Another issue is the contrast being too low or too high; adjust the setContrast() value in steps of 5 until the text is clear. The display's viewing angle is about 6 o'clock, meaning the best contrast is when the display is viewed from below. If you mount the display at a different angle, you may need to adjust the contrast. The display also has a temperature range of -20°C to +70°C, and the contrast may drift at extreme temperatures, so you might need to implement a temperature sensor and adjust the contrast dynamically. The ST7565R controller has a built-in charge pump for the LCD voltage, which can generate a negative voltage of up to -15V, but this is not user-accessible. The display's power consumption is about 1 mA in sleep mode, which you can enter by calling u8g2.sleep() and wake it with u8g2.wake().

Optimizing Performance

For faster updates, use the hardware SPI mode, which runs at 4 MHz on the Uno, compared to software SPI which runs at about 500 kHz. The U8g2 library also supports a setBusClock() function to set the SPI clock speed, but the maximum is 4 MHz for the ST7565R. If you need to update the display frequently, consider using a buffer that is smaller than the full 1024 bytes, such as the U8G2_ST7565_12864_1_4W_HW_SPI constructor, which uses a 256-byte buffer and updates the display in four passes. This reduces the memory usage but increases the update time because each pass requires a separate SPI transaction. The display's frame rate is limited by the SPI bus, not the controller, so you can achieve about 30 full frames per second at 4 MHz. For partial updates, you can use the setDrawColor() function to set the color to 1 for white or 0 for black, and then draw only the changed pixels. The display's pixel layout is column-major, meaning the first byte corresponds to the first 8 pixels in the first column, which is standard for most monochrome LCDs. The U8g2 library handles this automatically, but if you write your own low-level driver, you need to account for this layout.

Advanced Features

The ST7565R controller supports hardware scrolling, which you can enable by setting the setScrollEnable() function in the U8g2 library, but this is rarely used. The display also supports a sleep mode that reduces power consumption to 1 mA, which is useful for battery-powered projects. You can put the display to sleep by calling u8g2.sleep() and wake it with u8g2.wake(). The display's response time is about 10 ms, so it can be used for simple animations, but not for video. The display has a built-in temperature sensor, but it is not accessible via the SPI interface; it is used internally for contrast compensation. The display's pixel size is 0.48 mm, giving a total active area of 81.5 mm by 40.5 mm, and the module size is typically 90 mm by 50 mm, with a thickness of 2.5 mm. The COG design means the driver IC is bonded directly to the glass, which reduces the number of external components and the overall footprint. The display's interface is SPI, but some modules also support parallel interface, though the 3.18 inch version typically uses SPI only. The SPI bus can be shared with other SPI devices, but you need to ensure that the CS pins are separate and that the other devices do not interfere with the display's timing. The display's data sheet is available from the manufacturer, and it includes the full initialization sequence and command set, which you can use to customize the driver if needed.

Testing with a Sample Sketch

Here is a complete sketch to test the display: include the libraries, define the constructor, and in the setup, initialize the display, set contrast, and draw a rectangle and text. In the loop, you can animate the display by moving a pixel or changing the text. The sketch should compile and run on an Arduino Uno, Mega, or Nano. The display will show a filled rectangle at the top-left corner and the text "Hello World" in the center. If the display is blank, check the wiring and the contrast setting. The sketch uses the hardware SPI pins, so ensure that the SPI pins are not used for other purposes. The sketch also sets the backlight to 50% brightness using analogWrite. You can modify the sketch to display sensor data, such as temperature or humidity, by reading the sensor and converting the value to a string. The U8g2 library supports the print() function, which you can use to print numbers directly, but you need to set the font first. The display's resolution is 128x64 pixels, which is enough to display 16 characters in a 6x8 pixel font per line, with 8 lines total. For larger fonts, you get fewer lines, but the text is more readable. The display's viewing angle is 6 o'clock, so the best position is to view it from below, but you can adjust the contrast to improve the viewing angle. The display's operating temperature range is -20°C to +70°C, and the storage temperature is -30°C to +80°C, so it is suitable for indoor and outdoor use, but not for extreme environments. The display's backlight has a lifetime of 50,000 hours, which is about 5.7 years of continuous use. The display's power consumption is 10 mA without backlight and 50 mA with backlight, so it is suitable for battery-powered projects if you use a low-power mode. The display's SPI interface is 3.3V, but it is 5V tolerant on the logic pins, so you can connect it directly to a 5V Arduino if you use a voltage divider on the SPI lines. The display's contrast voltage is generated internally, so you don't need an external potentiometer. The display's pixel layout is column-major, with the first byte corresponding to the first 8 pixels in the first column, which is standard for most monochrome LCDs. The display's driver IC is the ST7565R, which is a common controller for COG displays, and it is supported by many libraries, including U8g2, Adafruit_GFX, and the LCD5110 library. The display's resolution is 128x64, which is the same as the popular Nokia 5110 display, but the 3.18 inch version has a larger pixel size, making it easier to read. The display's pixel size is 0.48 mm, compared to 0.25 mm for the Nokia 5110, so the text is larger and more readable. The display's viewing area is 81.5 mm by 40.5 mm, which is about 3.2 inches by 1.6 inches, so it is suitable for displaying graphs, text, and simple graphics. The display's module size is 90 mm by 50 mm, with a thickness of 2.5 mm, so it is thin and easy to integrate into a project. The display's weight is about 10 grams, so it is lightweight. The display's interface is SPI, which uses 4 wires plus power and ground, so it is easy to connect to an Arduino. The display's backlight is a white LED, which provides even illumination. The display's contrast is adjustable via software, so you can set it to the optimal level for your environment. The display's temperature compensation is built-in, but you may need to adjust the contrast for extreme temperatures. The display's sleep mode reduces power consumption to 1 mA, which is useful for battery-powered projects. The display's refresh rate is 60 Hz, but the SPI bus limits the update rate to 30 Hz for full frames. The display's pixel response time is 10 ms, so it is suitable for static displays and simple animations. The display's driver IC is the ST7565R, which is a common controller for COG displays, and it is supported by many libraries, including U8g2, Adafruit_GFX