Hardware | LCD2004 를 arduino 로 컨트롤 해보기 - 1

|

1. 시작


흠흠흠~ 하면서 인터넷을 보던 중, arduino 로 컨트롤 하는 Liquid Crystal Display 를 보게 됩니다.

이게 흔히 말하는 LCD 이죠.


OLED 와 비교하여 부피도 크고, 명암 조절을 수동으로 해줘야 하는 등, 불편한 device 라고 생각하고 있던 중,

LCD 의 푸른색 색감을 보고 반해버렸습니다.


Display 부품을 늘이고 싶지 않았지만, 이제 구입할 때가 된것 같아 구입합니다.


* LCD2004+I2C 2004 20x4 2004A blue screen HD44780 Character LCD /w IIC/I2C Serial Interface Adapter Module For Arduino

https://www.aliexpress.com/item/32831845529.html



결코 싼 가격은 아니지만, 이왕 구입하는 김에 보편적으로 많이 사용하는 녹색과 색감에 반한 푸른색, 두 개를 삽니다.





2. 도착


한 2주만에 재품을 받았습니다.

무료 배송이 점점 없어지고 배송비 책정이 되면서 배송 기간이 점점 짧아지고 있는 듯 합니다.



푸른색, 녹색 두개가 와서 PCB 를 비교해 보니, 서로 동일한 듯 하나 살짝 다른 모습 입니다.



I2C 컨트롤러의 칩 한쪽은 마킹이 너무 얇아 fake 제품처럼 보입니다.

조금이라도 진품처럼 보이는 쪽은 파란색 버전 입니다.



납땜도 녹색보다는 파란색이 잘 되어 있습니다.



PCB 마킹도, 파란색은 동판에 미리 새겨져 있고, 녹색은 프린팅 되어 있네요.



뭐, 생산하다가 점점 원가절감 하면서 변화된 것 일 수도 있습니다.

보통 녹색을 많이 사용하니, 녹색이 원가절감이 더 된 것 일수도 있구요.





3. Pin


Pin 수는 16개로, 아래와 같은 사양을 가집니다.


-------------------------------------------------------------------
|  pin  |                        function                         |
-------------------------------------------------------------------
|  VSS  | connected to ground                                     |
-------------------------------------------------------------------
|  VDD  | connected to a +5V power supply                         |
-------------------------------------------------------------------
|   V0  | to adjust the contrast                                  |
-------------------------------------------------------------------
|   RS  | A register select pin that controls where in the LCD's  |
|       | memory you are writing data to. You can select either   |
|       | the data register, which holds what goes on the screen, |
|       | or an instruction register, which is where the LCD's    |
|       | controller looks for instructions on what to do next.   |
-------------------------------------------------------------------
|  R/W  | A Read/Write pin to select between reading and writing  |
|       | mode                                                    |
-------------------------------------------------------------------
|   E   | An enabling pin that reads the information when HIGH    |
|       | level(1) is received. The instructions are run when the |
|       | signal changes from HIGH level to LOW level.            |
-------------------------------------------------------------------
| D0-D7 | to read and write data                                  |
-------------------------------------------------------------------
|   A   | Pins that control the LCD backlight. Connect A to 3.3V. |
-------------------------------------------------------------------
|   K   | Pins that control the LCD backlight. Connect K to GND.  |
-------------------------------------------------------------------


대충 훑어 보면, back light 전원, 본체 전원, 명암 조절, data 통신과 컨트롤 라인 등이 있습니다.

제가 구매한 제품은 I2C 모듈인 "PCF8574" 컨트롤러가 달린 제품입니다.

그러니, 일일이 모두 연결할 필요 없이 I2C 를 통해, 단 4가닥 선으로 컨트롤 할 수 있습니다.


이 chip 의 생산은 Philips, TI, NXP 등에서 생산되고 있네요. PDF 사양서를 올려 놓습니다.


LCD2004

TC2004A-01.pdf

Systronix_20x4_lcd_brief_data.pdf

RK-10290_410.pdf

50586.pdf


HD44780

HD44780.pdf

LCD Interfacing using HD44780 Hitachi chipset compatible LCD.pdf


PCF8574

PCF8574_PCF8574A.pdf

PCF8574T.pdf

pcf8574.pdf





4. I2C


Arduino 와 연결은 I2C 이므로, 4가닥으로 처리됩니다.



Liquid Crystal I2C 라이브러리가 필요합니다.

일반 Liquid Crystal I2C 라이브러리를 설치해도 되나, 궂이... 궂이 PCF8574 용 라이브러리를 찾아서 설치해 봅니다.

(범용 Liquid Crystal I2C 라이브러리가 아님)



위의 라이브러리를 설치하면 아래처럼 sample code 를 사용할 수 있습니다.


File > Examples > LiquidCrystal_PCF8574 > LiquidCrystal_PCF8574_test



I2C 활용시에는 항상 address 를 확인해 봐야 합니다.

Arduino 와 I2C 로 연결 후, i2cdetect 소스를 돌려 봅니다.



0x27 로 잡혀 있네요.

참고로 다른 I2C 센서들과 연동 시에 address 충돌이 일어나면, 아래 사진의 A0, A1, A2 쇼트 조합으로 주소를 바꿀 수 있습니다.






5. I2C 소스


친절하게도 example 소스가 충분히 잘 만들어져 있는지라, 그냥 돌려 봅니다.


#include "LiquidCrystal_PCF8574.h"
#include "Wire.h"

LiquidCrystal_PCF8574 lcd(0x27); // set the LCD address to 0x27 for a 16 chars and 2 line display
int show = -1;

void setup() {
	int error;
	
	Serial.begin(115200);
	Serial.println("LCD...");
	
	// wait on Serial to be available on Leonardo
	while (!Serial)
		;
	Serial.println("Dose: check for LCD");
	
	// See http://playground.arduino.cc/Main/I2cScanner how to test for a I2C device.
	Wire.begin();
	Wire.beginTransmission(0x27);
	error = Wire.endTransmission();
	Serial.print("Error: ");
	Serial.print(error);
	
	if (error == 0) {
		Serial.println(": LCD found.");
		show = 0;
		lcd.begin(20, 4); // initialize the lcd
	} else {
		Serial.println(": LCD not found.");
	} // if
} // setup()

void loop() {
	if (show == 0) {
		lcd.setBacklight(255);
		lcd.home();
		lcd.clear();
		lcd.print("Hello LCD");
		delay(1000);
		
		lcd.setBacklight(0);
		delay(400);
		lcd.setBacklight(255);
	} else if (show == 1) {
		lcd.clear();
		lcd.print("Cursor On");
		lcd.cursor();
	} else if (show == 2) {
		lcd.clear();
		lcd.print("Cursor Blink");
		lcd.blink();
	} else if (show == 3) {
		lcd.clear();
		lcd.print("Cursor OFF");
		lcd.noBlink();
		lcd.noCursor();
	} else if (show == 4) {
		lcd.clear();
		lcd.print("Display Off");
		lcd.noDisplay();
	} else if (show == 5) {
		lcd.clear();
		lcd.print("Display On");
		lcd.display();
	} else if (show == 7) {
		lcd.clear();
		lcd.setCursor(0, 0);
		lcd.print("*** first line.");
		lcd.setCursor(0, 1);
		lcd.print("*** second line.");
		lcd.setCursor(0, 2);
		lcd.print("*** third line.");
		lcd.setCursor(0, 3);
		lcd.print("*** forth line.");
	} else if (show == 8) {
		lcd.scrollDisplayLeft();
	} else if (show == 9) {
		lcd.scrollDisplayLeft();
	} else if (show == 10) {
		lcd.scrollDisplayLeft();
	} else if (show == 11) {
		lcd.scrollDisplayRight();
	} else if (show == 12) {
		lcd.clear();
		lcd.print("write-");
	} else if (show > 12) {
		lcd.print(show - 13);
	} // if
	
	delay(1400);
	show = (show + 1) % 16;
} // loop()


Serial Monitor 에서 확인해 보니, 잘 인식 되었네요.



너무 쉽게 되어서 살짝 김이 빠지는 정상적인 결과.



동영상도 올려 봅니다. (동영상은 16x2 버전으로 돌린 결과. 수정된 위의 소스로 20x4 로 변경된 소스를 사용하면 4줄 다 사용.)






6. Direct 연결


여기서 끝내면 너무 재미 없는지라, 한땀한땀 직접 연결해 봅니다.

워낙 오래된 부품이라, 아래 arduino 정식 사이트에서 자세히 소개되어 있습니다.


* TUTORIALS > Examples from Libraries > LiquidCrystal > HelloWorld

https://www.arduino.cc/en/Tutorial/HelloWorld?from=Tutorial.LiquidCrystal


각 Pin 의 정보는 다음과 같습니다.



실제 arduino 와 연결은 다음과 같습니다.


--------------------------------
| LCD2004 |    Arduino Nano    |
--------------------------------
|   VSS   |         GND        |
|   VDD   |         5V         |
|   V0    | S of potentiometer |
|   RS    |         D12        |
|   R/W   |         GND        |
|   E     |         D11        |
|  D0-D3  |    no connected    |
|   D4    |         D5         |
|   D5    |         D4         |
|   D6    |         D3         |
|   D7    |         D2         |
|   A     |         3.3V       |
|   K     |         GND        |
--------------------------------


Diagram 으로도 그려 봤습니다. (Digital pin 은 실제와 살짝 틀림)






7. Potentiometer


여기서 필요한 것이 potentiometer 입니다. 가변 저항이죠.

다이얼을 돌려서 저항값을 변화시키는 부품이죠. 구입을 미뤄 오다가, 이번 기회에 사용하고자 구입 했습니다.


* 5 PCS/Lot Potentiometer Resistor 1K 10K 20K 50K 100K 500K Ohm 3 Pin Linear Taper Rotary Potentiometer for Arduino with Cap

https://www.aliexpress.com/item/32948875673.html



구입한 버전은 10K Ohm.



글의 문맥상 뜬금 없지만, 도착샷 입니다. 빠질 수 없죠.



요런 모양 입니다.




8. Direct 연결 구동


직접 연결하는 방법은 Arduino IDE 에서 기본 제공합니다.



소스는 다음과 같구요.

기본 16x2 버전으로 되어 있으니, 20x4 버전으로 살짝 수정해 줍니다.


/*
  LiquidCrystal Library - Hello World
 
 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.
 
 This sketch prints "Hello World!" to the LCD
 and shows the time.
 
  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * LCD VSS pin to ground
 * LCD VCC pin to 5V
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 22 Nov 2010
 by Tom Igoe
 
 This example code is in the public domain.
 
 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */
 
// include the library code:
#include "LiquidCrystal.h"
 
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 
void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(20, 4);
  // Print a message to the LCD.
  lcd.setCursor(0, 0);
  lcd.print(" Chocoball's Tech");
  lcd.setCursor(0, 2);
  lcd.print(" chocoball.tistory");
}
 
void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 3);
  // print the number of seconds since reset:
  lcd.print(millis() / 1000);
}


전부 연결하면 아래와 같습니다.



동영상도 올려 봅니다.



hello, world! 를 저의 블로그명으로 바꿔 봤습니다.



단순한 표시 방법과 오랜 기간 수정된 라이브러리 덕으로, 정말 스트레스 없이 구동 시켰습니다.




9. I2C 와 Direct 연결시 명령어 차이


I2C 를 통한 함수와, 직접 연결했을 시에 사용할 수 있는 명령어 구성이 살짝 다릅니다.

고맙게도 아래 사이트에서 잘 정리된 테이블이 있어서 여기에 올려 봅니다.


* LCD Display Tutorial for Arduino and ESP8266

https://diyi0t.com/lcd-display-tutorial-for-arduino-and-esp8266/






10. 커스텀 폰트


명령어 차이를 자세하게 올려준 사이트에서 폰트 커스텀에 대해서도 내용이 있어서 따라해 봤습니다.

이 때, 사용하는 LiquidCrystal_I2C 라이브러리는 범용을 사용하는 지라, 아래 라이브러리를 설치합니다.



소스는 아래와 같습니다. 폰트라기 보단 캐릭터 입니다.


#include "Wire.h"
#include "LiquidCrystal_I2C.h"

// Set the LCD address to 0x27 in PCF8574 by NXP and Set to 0x3F in PCF8574A by Ti
LiquidCrystal_I2C lcd(0x27, 20, 4);

byte customChar1[] = {
  B01110,
  B01110,
  B00100,
  B11111,
  B00100,
  B01110,
  B01010,
  B01010
};

byte customChar2[] = {
  B01110,
  B01110,
  B10101,
  B01110,
  B00100,
  B00100,
  B01010,
  B10001
};

void setup() {
  lcd.init();
  lcd.backlight();
}

void loop() {
  lcd.createChar(0, customChar1);
  lcd.home();
  lcd.write(0);
  delay(1000);
  lcd.createChar(0, customChar2);
  lcd.home();
  lcd.write(0);
  delay(1000);
}


Bitmap 을 이용해서 만들었고, 화면 refresh 를 통해서 움직이는 것 처럼 구성했네요.



동영상도 올려 봅니다.



참고로, 이 Liquid Crystal 은 Hitachi HD44780 를 사용하거나 호환품들이라 아래 폰트를 기본 제공합니다.


HD44780.pdf






11. 아...


인터넷에서 보지 말아야 할 것을 봐버렸습니다.



이렇게 이쁘게도 커스터마이징 할 수 있는거군요.

다음은, 커스텀 폰트를 가지고 놀아보겠습니다.


And