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
Systronix_20x4_lcd_brief_data.pdf
HD44780
LCD Interfacing using HD44780 Hitachi chipset compatible LCD.pdf
PCF8574
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/
LiquidCrystal | LiquidCrystal_I2C | Function LiquidCrystal library | Description |
x | x | LiquidCrystal() LiquidCrystal_I2C() | This function creates a variable of the type LiquidCrystal. The parameters of the function define the connection between the LCD display and the Arduino. You can use any of the Arduino digital pins to controll the display. The order of the parameters is the following: LiquidCrystal(RS, R/W, Enable, d0, d1, d2, d3, d4, d5, d6, d7) If R/W is connected to GND you do not use the parameter in the function: LiquidCrystal(RS, Enable, d0, d1, d2, d3, d4, d5, d6, d7) If you want to operate in the 4-bit mode the function changes: LiquidCrystal(RS, R/W, Enable, d4, d5, d6, d7) If you are using an LCD display with the I2C connection you do not define the connected pins because you do not connected to single pins but you define the HEX address and the display size: LiquidCrystal_I2C lcd(0x27, 20, 4); |
x | lcd.begin() | The lcd.begin(cols, rows) function has to be called to define the kind of LCD display with the number of columns and rows. The function has to be called in the void setup() part of your sketch. For the 16x2 display you write lcd.begin(16,2) and for the 20x4 lcd.begin(20,4). The example below defines the display as 20x4 display and display a text. | |
x | lcd.init() | Initialization of the I2C display. | |
x | x | lcd.clear() | The clear function clears any data on the LCD screen and positions the cursor in the upper-left corner. The following sketch first outputs the text and clears the display after a short delay. |
x | x | lcd.home() | This function places the cursor at the upper left corner of the screen. |
x | x | lcd.setCursor() | If you want to write text to your LCD display, you have to define the starting position of the character you want to print onto the LCD with function lcd.setCursor(col, row). Although you have to define the row the character should be displayed. The following example print the word DIYI0T on different positions onto the screen. |
x | x | lcd.write() | Use the function write to display the value of a variable. For example the sensor value of a temperature module like the following example. |
x | x | lcd.print() | This function displays different data types: char, byte, int, long, or string. A string has to be in between quotation marks („“). Numbers can be printed without the quotation marks. Numbers can also be printed in different number systems lcd.print(data, BASE) with BIN for binary (base 2), DEC for decimal (base 10), OCT for octal (base 8), HEX for hexadecimal (base 16). The following example prints the string „DIYI0T“ and 101 on the display. |
x | lcd.println() | This function displays also different data types: char, byte, int, long, or string like the function lcd.print() but lcd.println() prints always a newline to output stream. In the following example you see the difference between the function lcd.print() and lcd.println(). | |
x | x | lcd.cursor() / lcd.noCursor() | Displays or hide the LCD cursor as an underscore (line) at the position to which the next character will be written. The following example shows a sketch to make a blinking cursor similar to what you see in many text input fields. |
x | x | lcd.blink() / lcd.noBlink() | The blink and noBlink function shows or hides a block style cursor that blinks on and off. |
x | x | lcd.display() / lcd.noDisplay() | This function turn on and off any text or cursor on the display but does not delete the information from the memory. Therefore is is possible to turn the display on and off with this function like you see in the following example. |
x | x | lcd.scrollDisplayLeft() / lcd.scrollDisplayRight() | This function scrolls the contents of the display (text and cursor) a one position to the left or to the right. After 40 spaces the function will loops back to the first character. With this function in the loop part of your sketch you can build a scrolling text function. Scrolling text if you want to print more than 16 or 20 characters in one line, than the scrolling text function is very handy. First the substring with the maximum of characters per line is printed, moving the start column from the right to the left on the LCD screen. Than the first character is dropped and the next character is printed to the substring. This process repeats until the full string is displayed onto the screen. The following example shows a scrolling text on an 20x4 LCD display. |
x | x | lcd.autoscroll() / lcd.noAutoscroll() | The autoscroll function turn on or off the functionality that each character is shifted by one position. The function can be used like the scrollDisplayLeft / scrollDisplayRight function. The following example shows a scrolling text on an 20x4 LCD display. |
x | x | lcd. leftToRight() / lcd.rightToLeft() | The leftToRight and rightToLeft functions changes the direction for text written to the LCD. The default mode is from left to right which you do not have to define at the start of the sketch. The next example sketch shows you the difference between both functions for the string „DIYI0T“. |
x | x | lcd.createChar() | There is the possibility to create custom characters with the createChar function. How to create the custom characters is described in the following chapter of this article as well as an example. |
x | lcd.backlight() | The backlight function is usefull if you do not want to turn off the whole display (see lcd.display()) and therefore only switch on and off the backlight. But before you can use this function you have to define the backlight pin with the function setBacklightPin(pin, polarity). The following example shows a sketch to turn on and off the backlight. lcd.setBacklightPin(7, NEGATIVE); lcd.setBacklight(1); | |
x | lcd.moveCursorLeft() / lcd.moveCursorRight() | This function let you move the curser to the left and to the right. To use this function usefull you have to combine it with lcd.setCursor() because otherwise there is not cursor to move left or right. For our example we also use the function lcd.cursor() to make the cursor visible. | |
x | lcd.on() / lcd.off() | This function switches the LCD display on and off. It will switch on/off the LCD controller and the backlight. This method has the same effect of calling display/noDisplay and backlight/noBacklight. |
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 를 사용하거나 호환품들이라 아래 폰트를 기본 제공합니다.
11. 아...
인터넷에서 보지 말아야 할 것을 봐버렸습니다.
이렇게 이쁘게도 커스터마이징 할 수 있는거군요.
다음은, 커스텀 폰트를 가지고 놀아보겠습니다.
'Hardware' 카테고리의 다른 글
Hardware | 레트로 led 글자판 HPDL-1414 사용기 - 1 (0) | 2019.10.15 |
---|---|
Hardware | 공기질 측정용 MiCS-6814 센서를 사용해 보자 - 1 (26) | 2019.10.12 |
Hardware | Arduino 로 Gimbal 컨트롤 하기 (2) | 2019.10.07 |
Hardware | 재생토너 chip 교환기 - 2 (0) | 2019.10.04 |
Hardware | SMD 부품 납땜용 오븐 취득기 (0) | 2019.10.02 |