---
###### tag:`Arduino` `LCD1602` `Control`
---
# Arduino 電路實驗 並列式驅動 LCD
[TOC]
系級:資工三乙
座號:16
姓名:王君翔
指導老師:林宏益
* 本次實驗使用[模擬器](https://tinkercad.com)進行操作 (Do this experiment with [Emulator](https://tinkercad.com).)
---
## 實驗壹 自建字型與左右移動
### 1.實驗目的 Purpose
透過實作程式碼,了解如何建立自型字體,以及控制LCD呈現文字左右移動之效果。
Learn how to create my own character and display the texts with shifting effect on the LCD.
---
### 2.實驗原理 Principle
撰寫程式碼控制LCD之文字
Control texts on the LCD by coding.
---
### 3.實驗材料 Materials
| 名稱<br>Name | 數量<br>Quantity | 備註<br>Memo |
| -------- | -------- | -------- |
| Arduino Uno R3 | 1 | 附USB線<br>With USB Cable|
| 麵包板<br>Breadboard | 1 | |
| 杜邦線<br>Dupont Line | 10 | 公對公<br>Male To Male |
| LCD1602 | 1 | |
---
### 4.實驗步驟 Steps
1. 依照電路圖連接電路 (Connect the circuit according to the circuit diagram.)

Δ電路圖 (Circuit Diagram)
2. 將以下程式完成後,透過USB線上傳至Uno板。(After completing the code block below, upload the file to Arduino Uno R3 with USB cable.)
``` C=
#include <LiquidCrystal.h>
LiquidCrystal LCD(12,11,10,5,4,3,2);
byte shell[2][8] = {
{
0b00000011,
0b00000100,
0b00000011,
0b00000110,
0b00000101,
0b00000101,
0b00000110,
0b00000011
},
{
0b00011110,
0b00000011,
0b00011101,
0b00010101,
0b00001101,
0b00011101,
0b00000011,
0b00011110
}
};//my own characters
// Init
void setup() {
LCD.begin(16,2);
LCD.clear();
LCD.createChar(0, shell[0]); // load the character array
LCD.createChar(1, shell[1]); // load the character array
}
// main
void loop() {
LCD.home(); // move cursor to the up-left side
LCD.print("The shell of ");
LCD.setCursor(1,1); // move cursor to the bottom-left side
LCD.print("permafrost.");
LCD.setCursor(12,1); // move cursor to the bottom-right side
LCD.write(byte(0)); // display left shell
LCD.setCursor(13,1); // move to the next position
LCD.write(byte(1)); // display right shell
for (int i=0; i<8; i++){ // left shift from the middle
LCD.scrollDisplayLeft(); // shifting
delay(200);
}
for (int i=0; i<15; i+=2){ // counter
for (int j=0; j<(15-i); j++){ // right shift
LCD.scrollDisplayRight(); // shifting
delay(200);
}
for (int j=0; j<(15-i-1); j++){ // left shift
LCD.scrollDisplayLeft(); // shifting
delay(200);
}
}
LCD.clear(); // clear the texts
delay(1000);
}
```
3. 進行模擬並紀錄實驗結果。 (Start the simulation and record the results)
---
### 5.實驗結果 Result

Δ接線完成圖 (Finished Circuit)

Δ右移 (Right shifting)

Δ左移 (Left shifting)
文字正常顯示,且移動方式符合預期結果。
As expected, the way texts on the LCD moved and displayed is correct.
[電路連結](https://www.tinkercad.com/things/23uKEiIcikI?sharecode=niQ7WXjL04x2C7E5vk1OFYRzq3PBFM233MrLRuuEhmE)
---
### 6.實驗討論 Discussion
#### 問題 (Question)
加上對比度調整電路,觀察字型對比度變化。
Add circuit which can adjust contrast of LCD, observe the differences between before and after.
#### 答案 (Solution)
##### 答案一 OPA (Solution 1)
透過可變電阻控制輸入電壓,使用OPA放大器,以反相放大之方式,將電壓增益控制在0 ~ -1之間。
之後再將輸出訊號反相,輸出至LCD之VO(contrast)。
Adjust input voltage with potentiometer, use see-saw circuit, control the voltage gain between 0 and -1.
Input the output signal from the OPA to invertor, then input the signal to VO.
###### 使用材料 Materials
| 名稱<br>Name | 數量<br>Quantity | 備註<br>Memo |
| -------- | -------- | -------- |
| 可變電阻<br>potentiometer | 1 | 2kΩ|
| 741 Operational Amplifier | 2 | |
| 電阻<br>Resistor | 1 | 3kΩ |
| 電阻<br>Resistor | 3 | 10kΩ |
| 電源供應器<br>Power Supply | 2 | |
###### 結果 Result

Δ接線完成圖 (Finished Circuit)

Δ亮 (bright)

Δ暗 (dark)
[電路連結](https://www.tinkercad.com/things/9TqrGLdiOWs?sharecode=TYDKZXokS9E0XM-axB_Qw_X6KvEB5Rys8T9H5jfeww0)
##### 答案二 Code (Solution 2):
透過程式碼讀取電位器之電位,在轉換之後輸出至VO(contrast)。
在不透過多執行緒之情況下,只能不斷呼叫函式讀取輸入。
Read the voltage by code blocks, then convert the voltage.
After converting, output voltage to V0 by analogWrite.
Without using multiple threads, I have to constantly call the function to adjust brightness.
###### 使用材料 Materials
| 名稱<br>Name | 數量<br>Quantity | 備註<br>Memo |
| -------- | -------- | -------- |
| 可變電阻<br>potentiometer | 1 | 2kΩ|
###### 完整程式碼 code
```c=
#include <LiquidCrystal.h>
LiquidCrystal LCD(12,11,10,5,4,3,2);
byte shell[2][8] = {
{
0b00000011,
0b00000100,
0b00000011,
0b00000110,
0b00000101,
0b00000101,
0b00000110,
0b00000011
},
{
0b00011110,
0b00000011,
0b00011101,
0b00010101,
0b00001101,
0b00011101,
0b00000011,
0b00011110
}
};//my own characters
void setConcrast();
int volIn = A0, volOut = 9, vol;
// Init
void setup() {
pinMode(volIn, INPUT);
pinMode(volOut, OUTPUT);
LCD.begin(16,2);
LCD.clear();
LCD.createChar(0, shell[0]);
LCD.createChar(1, shell[1]);
}
// main
void loop() {
setConcrast();
LCD.home();
LCD.print("The shell of ");
LCD.setCursor(1,1);
setConcrast();
LCD.print("permafrost.");
LCD.setCursor(12,1);
LCD.write(byte(0));
setConcrast();
LCD.setCursor(13,1);
LCD.write(byte(1));
setConcrast();
for (int i=0; i<8; i++){
setConcrast();
LCD.scrollDisplayLeft();
delay(200);
}
for (int i=0; i<15; i+=2){
for (int j=0; j<(15-i); j++){
setConcrast();
LCD.scrollDisplayRight();
delay(200);
}
for (int j=0; j<(15-i-1); j++){
setConcrast();
LCD.scrollDisplayLeft();
delay(200);
}
}
LCD.clear();
delay(1000);
}
void setConcrast(){
vol = analogRead(volIn);
analogWrite(volOut, vol/10);
}
```
###### 結果 Result

Δ接線完成圖 (Finished Circuit)

Δ亮 (bright)

Δ暗 (dark)
[電路連結](https://www.tinkercad.com/things/33IBfePv6C5?sharecode=G7aat-V2U-S1y88xVeY6sBGkFAs4ibinQVu4fjw5qNs)
----
## 實驗貳 PC傳控LCD
### 1.實驗目的 Purpose
透過實作程式碼,了解如何將串列傳輸視窗及LCD結合應用。
Lrean how to combine serial monitor with LCD by coding.
---
### 2.實驗原理 Principle
透過程式碼控制LCD即進行互動
Interact with user and control LCD by coding.
---
### 3.實驗材料 Materials
| 名稱<br>Name | 數量<br>Quantity | 備註<br>Memo |
| -------- | -------- | -------- |
| Arduino Uno R3 | 1 | 附USB線<br>With USB Cable|
| 麵包板<br>Breadboard | 1 | |
| 杜邦線<br>Dupont Line | 10 | 公對公<br>Male To Male |
| LCD1602 | 1 | |
---
### 4.實驗步驟 Steps
1. 依照電路圖連接電路 (Connect the circuit according to the circuit diagram.)

Δ電路圖 (Circuit Diagram)
2. 將以下程式完成後,透過USB線上傳至Uno板。(After completing the code block below, upload the file to Arduino Uno R3 with USB cable.)
``` C=
#include <LiquidCrystal.h>
LiquidCrystal LCD(12,11,10,5,4,3,2);
char sel;
// Init
void setup() {
LCD.begin(16,2);
Serial.begin(9600);
LCD.clear();
LCD.print("(1)High, (2)Low");
}
// Main
void loop() {
LCD.setCursor(0,1);
LCD.print("Select => ");
if (Serial.available()) {
delay(50);
while (Serial.available()) {
sel = Serial.read();
LCD.setCursor(0,1);
if (sel == 49) {
LCD.print("High power");
delay(5000);
}else if (sel == 50){
LCD.print("Low power");
delay(3000);
}else {
LCD.print("Retry please ");
delay(2000);
LCD.setCursor(0,1);
for(int i = 0; i < 16; i++)
LCD.print(' ');
}
}
}
}
```
3. 進行模擬並紀錄實驗結果。 (Start the simulation and record the results)
---
### 5.實驗結果 Result

Δ接線完成圖 (Finished Circuit)

Δ輸入1 (Input 1)

Δ輸入2 (Input 2)

Δ其他輸入 (Other inputs)
文字正常顯示符合預期結果。
As expected, the way texts on the LCD displayed is correct.
[電路連結](https://www.tinkercad.com/things/dRHFMlQUXST?sharecode=vn5Iu9-xDLbM3Vf_afbCVmRMj1237vG1WlmqA3k-HrE)
---
### 6.實驗討論 Discussion
#### 問題 (Question)
以I2C進行實作
Finish this experiment with LCD1602(I2C).
#### 答案 (Solution)
程式碼(code):
```c++=
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define Addr 0x27
LiquidCrystal_I2C LCD(Addr, 16, 2);
void setup() {
LCD.begin(16, 2);
LCD.backlight();
LCD.clear();
LCD.print("(1)High, (2)Low");
Serial.begin(9600);
}
void loop() {
LCD.setCursor(0, 1);
LCD.print("Select => ");
if(Serial.available()){
delay(50);
while(Serial.available()){
char sel = Serial.read();
LCD.setCursor(0, 1);
if(sel == 49){
LCD.print("High power");
delay(5000);
}else if(sel == 50){
LCD.print("Low power ");
delay(3000);
}else{
LCD.print("Retry please");
delay(2000);
LCD.setCursor(0, 1);
for(int i = 0; i < 0x10; i++)
LCD.print(' ');
}
}
}
}
```
電路圖:

運作同非I2C版本
Work same as non-I2C version.
* 以[Wokwi](https://wokwi.com)進行模擬
* [點我查看電路](https://wokwi.com/projects/332609807595864658)
---
## 實驗心得 Reflection
這次的實驗十分有趣,雖然花了一些時間在思考電路上,但我認為這個付出是值得的,希望以後也有類似的實習。
The experiments I did this time have lots of fun, I thought it was worth a shot to do them though I did spend some time on designing circuits. I hope we will have more experiments like these.
---
## 參考文獻 Documents
* 艾迪諾 2017 Arduino全能微處理機實習-強效解析第四版第三章 全華圖書股份有限公司