在第一章Topic 1內﹐我們學習了在Arduino IDE內使用Serial Monitor來查看Arduino的訊息,但在現實的應用中,一個獨立的系統多會有自帶的顯示器,務求在不需要外在電腦/電子儀器幫忙也可以看到參數/作出調整,像計數機、手錶、數碼相機...等。而今章介紹的Liquid Crystal Display /液晶顯示器,簡稱LCD,是MCU應用中常見用作顯示文字資料的零件。
在工房內常見的版本是LCD1602,1602代表的是LCD的顯示範圍是(X軸) 16格x (Y軸) 2行。
如果直接使用LCD1602連接上Arduino,如左上方所視,除了正負極還需要另外接上11條線。為了簡化連接,有廠商為LCD版加上了I2C的轉換板,只要使用2條綫(SDA,SCL)加上正負極就可以把訊號由Arduino板傳到LCD上了。工房內常用的也是加上了I2C的版本
需注意的是,Arduino UNO的SDA,SCL是A4,A5腳、而Leonardo的SDA,SCL是在2,3號腳
由於IS Shield是根據 UNO板設計,所以IS Shield上面的"SCL,SDA"實際上是A4,A5腳位,故用Leonardo板並不能用IS Shield上面的"SCL,SDA"通訊,今次的練習也將使用UNO主板
做練習前請把LCD上的GND,VCC,SDA,SCL連到IS Shield板上的G,V,SDA,SCL腳。
如之前做的Servo控制練習,今次的LCD控制器練習也是需要使用到額外的Library輔助。
1. 先在這裏下載Library的Zip檔,得到LiquidCrystal_I2C的zip檔
2. 在Arduino IDE內Sketch>Include Library>Add.ZIP Library...找到剛下載的Zip檔
3. 選擇到LiquidCrystal_I2C的zip檔後,按Open完成安裝
如果成功安裝的話,會跳出下面的訊息
如本身已經安裝了該Library的話,則會彈出以下訊息
https://playground.arduino.cc/Main/I2cScanner/
Arduino 官網提供可以自動查找零件的I2C地址程式,把以下的程式直接上傳,然後打開Serial Monitor查看即可
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
while (!Serial); // Leonardo: wait for serial monitor
Serial.println("\nI2C Scanner");
}
void loop()
{
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4)
{
Serial.print("Unknown error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000); // wait 5 seconds for next scan
}
下面的例子使用LiquidCrystal_I2C,除了開頭引用2個library外,整體LCD相關的語法和Serial.xxx的語法相似。
第3行的部份是設定LCD的地址。有些LCD板的是0x27或者是0x3F。如果0x27不行就換成0x3F試試。
#include <Wire.h> //引用library
#include <LiquidCrystal_I2C.h> //引用library
LiquidCrystal_I2C lcd(0x__, 16, 2); //0x27 or 0x3F
void setup(){
lcd.begin(); //相當於Serial.begin
lcd.backlight();
}
void loop(){
lcd.setCursor(0, 0);
lcd.print("Hello, world!"); //相當於Serial.print
lcd.setCursor(0, 1);
lcd.print("I <3 IS");
}
上面的程式中,lcd.setCursor(0, 0);這句是設定接下來顯示的文字要在哪個座標,左上角為0,0,X向左增大,Y向下增大
#include <Wire.h> //引用library
#include <LiquidCrystal_I2C.h> //引用library
LiquidCrystal_I2C lcd(0x__, 16, 2); //設定lcd的I2C 地址,有可能是0x27 或者 0x3F
void setup(){
lcd.begin();
lcd.backlight();
}
void loop(){
lcd.setCursor(0, 0);
lcd.print("Red button state");
lcd.setCursor(0, 1);
lcd.print(digitalRead(_)); //需要讀取的腳位是?
}
#include <Wire.h> //引用library
#include <LiquidCrystal_I2C.h> //引用library
LiquidCrystal_I2C lcd(0x__, 16, 2);
void setup(){
lcd.begin();
lcd.backlight();
}
void loop(){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("A1 resistance is");
lcd.setCursor(0, 1);
lcd.print(____________); //要顯示什麼內容?
delay(500);
}
要用可變電阻時記得加上Jumper在A1
我們可以用Serial.available()及Serial.read()來收集我們在Serial Monitor中輸入的文字,以便在程式開始運行後仍可以輸入不同數值
void setup() {
Serial.begin(9600);
}
void loop() {
if(Serial.available()){
char text_X = Serial.read(); //設定一個字符變數記下我們輸入的內容
Serial.print(" text:");
Serial.print(text_X);
}
}
以上方的程式為基礎,設定一個變數以int格式記錄字符,就能把字符變成ASCII碼的格式了。
另外在Serial.print的後方加入(xxx,BIN)則可以把字串變成2進制;也可以換成HEX/16進制、OCT/8進制
void setup() {
Serial.begin(9600);
}
void loop() {
if(Serial.available()){
char text_X = Serial.read();
int number_X = text_X; //把文字的轉成ASCII
Serial.print(" text:");
Serial.print(text_X);
____________(" ASCII:");
____________(number_X);
____________(" ");
______________(number_X,BIN); //變成2進位
}
}
以2a的程式為基礎、結合1a的程式,把Serial monitor輸入的文字轉變成ASCII碼在LCD上顯示出來
#include <Wire.h>//引用library
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x__, 16, 2); //0x27 or 0x3F
void setup() {
lcd.begin();
lcd.backlight();
Serial.begin(9600);
}
void loop() {
if(Serial.available()){
char text_X = Serial.read();
int number_X = text_X; //把文字的轉成ASCII
Serial.print(" text:");
Serial.print(text_X);
____________(" ASCII:");
____________(number_X);
____________(" ");
______________(number_X,BIN); //變成2進位
lcd.setCursor(0, 0);
lcd.print(________);
lcd.setCursor(5, 0);
lcd.print("ASCII: ");
lcd.print(________);
lcd.setCursor(0,1);
lcd.print(________,BIN); //變成2進位
}
}
使用上方的程式輔助,完成工作紙上字符的ASCII轉換。