Introduction: Use I2C_LCD to Debug Your Project

The serial monitor is a useful debugger for Arduino, it can print logs on the computer screen. so that, if you want to get running log of you project, you need to take a computer with you anywhere. Now, you can use I2C_LCD to get running logs anywhere, it will be more convenient.

Step 1: Prepare the Materials

We need a control here to show you how to print the log via a LCD. We choose Lotus here.

Seeeduino Lotus

Lotus is an ATmega328 Microcontroller development board. It is a combination of Seeeduino and Base Shield. It uses Atmel ATMEGA328P-MU and CH340. ATMEGA328P-MU is a high performance, low power 8-Bit AVR Microcontroller. CH340 is an USB bus converter chip that can realize an USB to serial interface. Seeeduino Lotus has 14 digital input/output (6 of which can output PWM) and 7 analog input/output, a micro USB connection, an ICSP header, 12 Grove connections, a reset button.


I2C_LCD is an easy-to-use display module, It can make display easier. Using it can reduce the difficulty of make, so that makers can focus on the core of the work.
We developed the Arduino library for I2C_LCD, user just need a few lines of the code can achieve complex graphics and text display features.


First connect I2C_LCD to the Grove port of Lotus.

Then you can download from here

How to install the library? please refer to the "How to use?" section of wiki page.


The following are extracted from:



Prints data to the I2C_LCD as human-readable ASCII text. This command can take many forms. Numbers are printed using an ASCII character for each digit. Floats are similarly printed as ASCII digits, defaulting to two decimal places. Bytes are sent as a single character. Characters and strings are sent as is.

For example:

LCD.print(78) gives "78"

LCD.print(1.23456) gives "1.23"

LCD.print('N') gives "N"

LCD.print("Hello world.") gives "Hello world."

An optional second parameter specifies the base (format) to use; permitted values are BIN (binary, or base 2), OCT (octal, or base 8), DEC (decimal, or base 10), HEX (hexadecimal, or base 16). For floating point numbers, this parameter specifies the number of decimal places to use.

For example:

LCD.print(78, BIN) gives "1001110"
LCD.print(78, OCT) gives "116"

LCD.print(78, DEC) gives "78"

LCD.print(78, HEX) gives "4E"

LCD.println(1.23456, 0) gives "1"

LCD.println(1.23456, 2) gives "1.23"

LCD.println(1.23456, 4) gives "1.2346"

You can pass flash-memory based strings to LCD.print() by wrapping them with F().

For example :

LCD.print(F(“Hello World”))

To send a single byte, use LCD.write().


LCD.print(val, format)


val: the value to print - any data type
format: specifies the number base (for integral data types) or number of decimal places (for floating point types)


size_t (long): print() returns the number of bytes written, though reading that number is optional


Different from Serial.print(), you need to set the position coordinates before print:

LCD.print("Hello world.") ;


Try to upload the below test code, then you will it's very easy and useful.

#include <Wire.h>
#include <I2C_LCD.h> //For detials of the function useage, please refer to "I2C_LCD User Manual". I2C_LCD LCD;

uint8_t I2C_LCD_ADDRESS = 0x51; //Device address setting, default: 0x51

void setup(void) { Wire.begin(); //I2C controler init. }

void loop(void) { LCD.CleanAll(WHITE); //Erase all. delay(1000); //Delay for 1s. //8*16 font size, auto new line, black character on white back ground. LCD.FontModeConf(Font_6x8, FM_ANL_AAA, BLACK_BAC); //Set the start coordinate. LCD.CharGotoXY(0, 0); //Print string on I2C_LCD at the start coordinate. LCD.print("Hello, World!"); //Set the start coordinate. LCD.CharGotoXY(0, 10); LCD.print(78); //gives "78" LCD.print('N'); //gives "N" LCD.print(1.23456); //gives "1.23" //Set the start coordinate. LCD.CharGotoXY(0, 20); LCD.print(78, BIN); //gives "1001110" LCD.print(' '); //gives " " LCD.print(78, OCT); //gives "116" LCD.print(' '); //gives " " LCD.print(78, DEC); //gives "78" LCD.print(' '); //gives " " LCD.print(78, HEX); //gives "4E" LCD.print(' '); //gives " " //Set the start coordinate. LCD.CharGotoXY(0, 30); LCD.println(1.23456, 0); //gives "1" LCD.println(1.23456, 2); //gives "1.23" LCD.println(1.23456, 4); //gives "1.2346" LCD.print("Debug with Arduino."); while(1); //Wait for ever. }


Raphango made it!(author)2015-08-12

Great!! Gotta try it!

Sanderv2 made it!(author)2015-08-08

Great complete overview of this technique! I use this technique regularly, especially when the usb serial is busy or if it just doesn't want to cooperate.
You are using an graphic LCD for this? I always use a non-I2C character LCD (I should buy a I2C backpack for it). The upside of using a character LCD is that it makes the code even simpler, for example writing on the first and second line becomes:

lcd.clear(); //Clear the entire screen

lcd.setCursor(0, 0); //We'll start writing in the top left

lcd.print("Hello first line");

lcd.setCursor(0, 1); //1 is the second line, as 0 is the first

lcd.print("Hello second line");
In my experience using a character LCD just makes it a tad easier to control.

Joney+S made it!(author)2015-08-09

Yes, it use graphic LCD. The are many fonts were already written to the MCU on borad when producing.
For details, please refer to

You already can use the I2C_LCD as you shown above.

About This Instructable



Bio: Howdy, we are application engineers in Seeedstudio. Sharing projects with maker community is awesome. Hope you like it XD
More by Seeed Studio:Diy Smart Home Assistant With Raspberry Pi and ReSpeaker Mic ArrayBuild Google Assistant on Raspberry Pi With ReSpeaker Mic ArrayDIY a Gesture Keyboard That Can Control the Media Player
Add instructable to: