BOSSZI Arduino LCD2004-DS3231-I2C-V1

LCD2004-DS3231-I2C-V1

0 Comments

LCD2004-DS3231-I2C-V1

LCD2004-DS3231-I2C-V1 เป็นบอร์ดที่ร่วม LCD2004 สำหรับการเชื่อมต่อ LCD แบบ I2C ที่สามารถปรับเปลี่ยน Contrast และ Brightness ของ LCD ทาง Software ได้และ ไอซีนาฬิกา DS3231 เข้าด้วยกัน

คุณสมบัติของบอร์ด LCD2004-DS3231-I2C-V1

  • Pin header สำหรับเชื่อมต่อกับบอร์ด Arduino uno และ Pin header 6 ขา สำหรับเชื่อมต่อกับบอร์ดชนิดอื่นโดยประกอบไปด้วย +24 V และ GND ของ 24 V สำหรับเลี้ยง Backlight แบบ Isolator I2C สำหรับเชื่อมต่อกับ อุปกรณ์บนบอร์ด และไฟเลี้ยง 5 V และ GND 5 V สำหรับเลี้ยง IC บนบอร์ด
  • ควบคุม Contrast และ Brightness ผ่าน Software โดยเชื่อมต่อแบบ I2C
  • รางถ่านสำหรับแบตเตอรี่ชนิด CR2032 สำหรับนาฬิกาของ DS3231
  • เก็บค่า Contrast และ Brightness สำหรับเรียกใช้เมื่อเริ่มทำงาน

การเชื่อมต่อ I2C ของบอร์ด

ADDRESS

  • Address ของ LCD – 0x20 สำหรับเขียนเพื่อแสดงข้อความบน LCD
  • Address ของ DS3231 – 0x68 สำหรับอ่าน/เขียน นาฬิกาบน IC DS3231
  • Address ของ Module Contrast And Brightness – 0x32 สำหรับควบคุม Contrast และ Brightness

การควบคุม Contrast และ Brightness ด้วย Module Contrast And Brightness ผ่านการเชื่อมต่อแบบ I2C

Address คำสั่งสำหรับ Module Contrast And Brightness

  • Address 0x0A สำหรับควบคุม Contrast รับค่าตั้งแต่ 0 – 255 (8 Bit)
  • Address 0xA0 สำหรับควบคุม Brightness รับค่าตั้งแต่ 0 – 255 (8 Bit)

ควบคุม Contrast และ Brightness ด้วย Library LCD2004_DS3231_I2C_Module

คำสั่ง

  • WireBrightness(Var) : Var = ตัวเลข 0 – 255 สำหรับควบคุม Brightness
  • WireContrast(Var) : Var = ตัวเลข 0 – 255 สำหรับควบคุม Contrast

การใช้งานการควบคุม Contrast และ Brightness โดยใช้ Library LCD2004_DS3231_I2C_Module

  1. include Library LCD2004_DS3231_I2C_Module.h สำหรับการอ่านและเขียน Brightness และ Contrast
  2. include Library Wire.h สำหรับการติดต่อสื่อสารแบบ I2C (Arduino IDE มี Library นี้มาให้)
  3. ใน Setup เขียนคำสั่ง Wire.begin() เพื่อเริ่มการสื่อสารแบบ I2C
  4. เขียนคำสั่ง WireBrightness หรือ WireContrst สำหรับปรับ Contrast และ Brightness

ตัวอย่างการใช้งานการควบคุม Contrast และ Brightness โดยใช้ Library LCD2004_DS3231_I2C_Module

#include <Wire.h> // Library I2C
#include <LCD2004_DS3231_I2C_Module.h> // Library ควบคุม Contrast และ Brightness
#include <LiquidCrystal_I2C.h> // Library จอ LCD
LiquidCrystal_I2C lcd(0x20, 20, 4); // 0x20 - Address LCD

void setup() {
  Wire.begin(); // เริ่มการสื่อสารแบบ I2C
  lcd.begin(); // เริ่มการทำงาน LCD
  WireBrightness(255); // เขียน Brightness ระหว่าง 0 -255
  WireContrast(90); // เขียน Contrast ระหว่าง 0 -255 lcd.backlight(); // เปิดไฟ Backlight
  lcd.print("LCD2004-DS3231-I2C"); // แสดง LCD2004-DS3231-I2C บน LCD
}

void loop() {
  // put your main code here, to run repeatedly:
}

เมื่อ Upload Code ด้านบนเข้า Arduino Uno และเชื่อมต่อกับบอร์ด LCD2004-DS3231-I2C หน้าจอ LCD จะแสดงข้อความ LCD2004-DS3231-I2C โดย Contrast และ Brightness ของจอจะขึ้นอยู่กับค่าที่เราเขียนเข้าไปในคำสั่ง WireBrightness และ WireContrast

ควบคุม Contrast และ Brightness ด้วย Library Wire.h

คำสั่ง

  • Wire.begin() : เริ่มการสื่อสารแบบ I2C
  • Wire.beginTransmission(Address) : เริ่มการติดต่อสื่อสารกับอุปกรณ์ตาม Address นั้นๆ
  • Wire.write(Var) : ส่งข้อมูลในค่า Var ไปยังอุปกรณ์ที่ระบุไว้ในคำสั่ง beginTransmission()
  • Wire.endTransmission() : จบการติดต่อสื่อสาร
  • delay(Var) : หยุดการทำงานเป็นเวลาตามค่า Var ในหน่วย milliSecond

การใช้งานการควบคุม Contrast และ Brightness โดยใช้ Library Wire.h

  1. include Library Wire.h สำหรับการติดต่อสื่อสารแบบ I2C
  2. ใน Setup เขียนคำสั่ง Wire.begin() เพื่อเริ่มการสื่อสารแบบ I2C
  3. เมื่อต้องการติดต่อสื่อสารกับ Module Contrast And Brightness เพื่อควบคุม Contrast หรือ Brightness เขียนคำสั่ง Wire.beginTransmission(0x32) เพื่อเริ่มการสื่อสารกับอุปกรณ์ 0x32 (หัวข้อ ADDRESS)
  4. เขียนคำสั่ง Wire.write(var) โดยค่าใน Var คือ Address คำสั่งของ Module Contrast And Brightness (หัวข้อ Address คำสั่งสำหรับ Module Contrast And Brightness)
  5. เมื่อระบุ Address คำสั่งของ Module Contrast And Brightness แล้ว เขียนคำสั่ง Wire.write(Var) อีกครั้งโดยค่าใน Var คือค่าที่เราต้องการตั้งให้กับ Address คำสั่งในข้อที่ 4 โดยทั้ง Contrast และ Brightness มีค่าตั้งแต่ 0 – 255 (8 Bit) โดยค่าของ Brightness จำแปรผันตรงกับค่าใน Var แต่ค่า Contrast จพแปรผกผันกับค่าใน Var
  6. เขียนคำสั่ง Wire.endTransmission() เพื่อจบการสื่อสารกับ Module Contrast And Brightness (0x32)

ตัวอย่างการใช้งานการควบคุม Contrast และ Brightness โดยใช้ Library Wire.h

#include <Wire.h> // Library การสื่อสารแบบ I2C
#include <LiquidCrystal_I2C.h> // Library LCD
LiquidCrystal_I2C lcd(0x20, 20, 4); // 0x20 - Address LCD

void setup() {
  Wire.begin(); // เริ่มการสื่อสารแบบ I2C
  lcd.begin(); // เริ่มการทำงาน LCD
  lcd.backlight(); // เปิดไฟ Backlight
  lcd.print("LCD2004-DS3231-I2C"); // แสดง LCD2004-DS3231-I2C บน
  LCD Write_To_Tiny(Add,Var); // Add : Address คำสั่ง Var : ค่าที่ต้องการตั้ง
}

void loop(){

}

 

เมื่อใส่ Address คำสั่งของ Module Contrast And Brightness เข้าไปใน Add และค่าที่ต้องการตั้งเข้าไปใน Var หน้าจอ LCD จะแสดง LCD2004-DS3231-I2C โดย Contrast และ brightness จะเป็นไปตามที่เราตั้ง

DS3231 แสดงค่าเวลาบน LCD โดยใช้ Library LCD2004_DS3231_I2C_Module

คำสั่ง

  • SetTime(Sec,Min,Hour,Day,Date,Month,Year); : ตั้งเวลาให้ DS3231
  • ReadTime(Sec,Min,Hour,Day,Date,Month,Year); : อ่านเวลาจาก DS3231

การใช้งาน DS3231 ร่วมกับ LCD โดยใช้ Library LCD2004_DS3231_I2C_Module

  1. include Library Wire.h และ LCD2004_DS3231_I2C_Module เข้าโปรแกรม
  2. ตั้งตัวแปร 7 ตัวสำหรับเก็บ วินาที,นาที,ชั่วโมง,วันของอาทิตย์,วันของเดือน,เดือน,ปี
  3. เขียนคำสั่ง SetTime สำหรับตั้งเวลา 1 ครั้งและ Upload โค้ดที่ไม่มีคำสั่งนี้อีกครั้ง ไม่เช่นนั้น DS3231 จะถูกตั้งเวลาทุกครั้งที่เปิด
  4. เขียนคำสั่ง ReadTime สำหรับรับค่าเวลาจาก DS3231

ตัวอย่าง การใช้งาน DS3231 ร่วมกับ LCD โดยใช้ Library LCD2004_DS3231_I2C_Module

#include <Wire.h> // Library การสื่อสารแบบ I2C
#include <LiquidCrystal_I2C.h> // Library LCD
#include <LCD2004_DS3231_I2C_Module.h>
LiquidCrystal_I2C lcd(0x20, 20, 4); // 0x20 - Address LCD
byte SecO,MinO,HouO,DayO,DatO,MonO,YeaO; // ตัวแปรเก็บค่าเวลา

void setup() {
  Wire.begin(); // เริ่มการสื่อสารแบบ I2C
  Serial.begin(9600);
  lcd.begin(); // เริ่มการทำงาน LCD
  lcd.backlight(); // เปิดไฟ Backlight
  lcd.print("LCD2004-DS3231-I2C"); // แสดง LCD2004-DS3231-I2C บน LCD
  //SetTime(Sec,Min,Hour,Day,Date,Month,Year); // ฟังชั่นภายใน Library LCD2004_DS3231_I2C_Module
  // ตั้งเวลาโดยเรียงตามลำดับ Sec,Minute,Hour,Day,Date,Month,Year
}

void loop() {
  ReadTime(SecO,MinO,HouO,DayO,DatO,MonO,YeaO); // ฟังชั่นภายใน Library LCD2004_DS3231_I2C_Module
  // อ่านค่าเวลาจาก DS3231 และ เก็บค่าเวลาลงในตัวแปร
  LCD_Time(); // แสดงเวลาที่ lcd
  delay(500);
}

void LCD_Time(){
  // ตั้งตำแหน่งที่ต้องการแสดงและแสดงค่าเวลาเป็นเลขฐาน 16 เนื่องจากค่าที่ DS3231 ส่งมาอยู่ในเลขฐาน 16 (ดูใน Datasheet DS3231)
  // ถ้าตั้งค่าชั่วโมงให้แสดงในรูป 1 - 12 AM/PM ค่าเวลาชั่วโมงจะเขียนอีกแบบหนึ่ง
  // ,HEX : แสดงค่าในฐาน 16 // (Var & 0xF0) >> 4 : แสดงเลขหลักสิบในฐาน 16 (แสดงแค่ Bit ที่ 4 - 7)
  // Var & 0x0F : แสดงเลขหลักหน่วยในฐาน 16 (แสดงแค่ Bit ที่ 0 - 3)
  // ตัวอย่าง HEX = 0x26
  // (0x26 & 0xF0) >> 4 = (0010110 & 11110000) >> 4 = 00100000 >> 4 = 00000010 = 2
  // 0x26 & 0x0F = 00100110 & 00001111 = 00000110 = 6
  lcd.setCursor(0,1); lcd.print((HouO & 0xF0) >> 4,HEX);
  lcd.print(HouO & 0x0F,HEX); lcd.print(":"); lcd.print((MinO & 0xF0) >> 4,HEX);
  lcd.print(MinO & 0x0F,HEX); lcd.print(":"); lcd.print((SecO & 0xF0) >> 4,HEX);
  lcd.print(SecO & 0x0F,HEX); lcd.print(" "); lcd.print((DatO & 0xF0) >> 4,HEX);
  lcd.print(DatO & 0x0F,HEX); lcd.print("/"); lcd.print((MonO & 0xF0) >> 4,HEX);
  lcd.print(MonO & 0x0F,HEX); lcd.print("/"); lcd.print((YeaO & 0xF0) >> 4,HEX);
  lcd.print(YeaO & 0x0F,HEX); lcd.setCursor(0,2); // ค่าวันใน DS3231 แสดงเป็นเลขฐาน 10 ค่าตั้งแต่ 1 - 7 โดย 1 = วันอาทิตย์
  if(DayO == 1){
    lcd.print("Sunday");
  }
  else if(DayO == 2){
    lcd.print("Monday");
  }
  else if(DayO == 3){
    lcd.print("Tuseday");
  }
  else if(DayO == 4 ){
    lcd.print("Wednesday");
  }
  else if(DayO == 5){
    lcd.print("Thurday");
  }
  else if(DayO == 6){
    lcd.print("Friday");
  }
  else if(DayO == 7){
  lcd.print("Saturday");
  }
}

 

DS3231 แสดงค่าเวลาบน LCD โดยใช้ Library Wire

คำสั่ง

  • Wire.begin() : เริ่มการสื่อสารแบบ I2C
  • Wire.beginTransmission(Address) : เริ่มการติดต่อสื่อสารกับอุปกรณ์ตาม Address นั้นๆ
  • Wire.write(Var) : ส่งข้อมูลในค่า Var ไปยังอุปกรณ์ที่ระบุไว้ในคำสั่ง beginTransmission()
  • Wire.endTransmission() : จบการติดต่อสื่อสาร
  • delay(Var) : หยุดการทำงานเป็นเวลาตามค่า Var ในหน่วย milliSecond

การใช้งาน DS3231 ร่วมกับ LCD โดยใช้ Library Wire

  1. include Library Wire.h และ LiquidCrystal_I2C เข้ามาในโปรแกรม
  2. เริ่มการติดต่อสื่อสารแบบ I2C และเริ่มการทำงาน LCD
  3. ดึงค่าเวลาจาก DS3231 มาเก็บไว้ในตัวแปรโดยจะทำการแปลงเลขจากฐาน 16 ที่ได้มาจาก DS3231 ที่เป็นฐาน 10 หรือไม่แปลงก็ได้
  4. คำค่าที่ได้แสดงบา LCD ถ้าเป็นเลขฐาน 16 ให้แสดงแบบ HEX ถ้าเป็นฐาน 10 เขียนอะไรเพิ่มเติม
  5. ถ้าแสดงชั่วโมงในรูปแบบ 1 – 12 AM/PM การแปลงเลขฐาน 16 เป็นฐาน 10 หรือแสดงในรูปฐาน 16 บน LCD จะต้องมีการ And 0x1F กับตัวแปรชั่วโมง และอ่าน Bit ที่ 5 ว่าเป็น AM หรือ PM ตาม Datasheet ของ DS3231
  6. การแสดงค่าวันจะเป็นตัวเลขฐานสิบ 1 – 7 โดยเลข 1 คือวันอาทิตย์ และเรียงวันมาตามลำดับ

ตัวอย่างการใช้งาน DS3231 ร่วมกับ LCD โดยใช้ Library Wire

#include <Wire.h>// Library การสื่อสารแบบ I2C
#include <LiquidCrystal_I2C.h>// Library LCD
LiquidCrystal_I2C lcd(0x20, 20, 4); // 0x20 - Address LCD byte SecO,MinO,HouO,DayO,DatO,MonO,YeaO;
// ตัวแปรเก็บค่าเวลา

void setup() {
  Wire.begin(); // เริ่มการสื่อสารแบบ I2C Serial.begin(9600);
  lcd.begin(); // เริ่มการทำงาน LCD
  lcd.backlight(); // เปิดไฟ Backlight
  lcd.print("LCD2004-DS3231-I2C"); // แสดง LCD2004-DS3231-I2C บน LCD
  //Write_To_DS(0,1,13,6,25,6,20); // ตั้งเวลาโดยเรียงตามลำดับ Sec,Minute,Hour,Day,Date,Month,Year
}

void loop() {
  Read_From_DS(SecO, MinO, HouO, DayO, DatO, MonO, YeaO); // อ่านค่าเวลาจาก DS3231 และ เก็บค่าเวลาลงในตัวแปร
  LCD_Time(); // แสดงเวลาที่ lcd
  delay(500);
}

void LCD_Time() {
  // ตั้งตำแหน่งที่ต้องการแสดงและแสดงค่าเวลาเป็นเลขฐาน 16 เนื่องจากค่าที่ DS3231 ส่งมาอยู่
  //ในเลขฐาน 16 (ดูใน Datasheet DS3231)
  // ถ้าตั้งค่าชั่วโมงให้แสดงในรูป 1 - 12 AM/PM ค่าเวลาชั่วโมงจะเขียนอีกแบบหนึ่ง
  // ,HEX : แสดงค่าในเลขฐาน 16 // (Var & 0xF0) >> 4 : แสดงเลขหลักสิบในฐาน 16 (แสดงแค่ Bit ที่ 4 - 7)
  // Var & 0x0F : แสดงเลขหลักหน่วยในฐาน 16 (แสดงแค่ Bit ที่ 0 - 3)
  // ตัวอย่าง HEX = 0x26
  // (0x26 & 0xF0) >> 4 = (0010110 & 11110000) >> 4 = 00100000 >> 4 = 00000010 = 2
  // 0x26 & 0x0F = 00100110 & 00001111 = 00000110 = 6
  lcd.setCursor(0, 1); lcd.print((HouO & 0xF0) >> 4, HEX); lcd.print(HouO & 0x0F, HEX);
  lcd.print(":"); lcd.print((MinO & 0xF0) >> 4, HEX); lcd.print(MinO & 0x0F, HEX);
  lcd.print(":"); lcd.print((SecO & 0xF0) >> 4, HEX); lcd.print(SecO & 0x0F, HEX);
  lcd.print(" "); lcd.print((DatO & 0xF0) >> 4, HEX); lcd.print(DatO & 0x0F, HEX);
  lcd.print("/"); lcd.print((MonO & 0xF0) >> 4, HEX); lcd.print(MonO & 0x0F, HEX);
  lcd.print("/"); lcd.print((YeaO & 0xF0) >> 4, HEX); lcd.print(YeaO & 0x0F, HEX);
  lcd.setCursor(0, 2); // ค่าวันใน DS3231 แสดงเป็นเลขฐาน 10 ค่าตั้งแต่ 1 - 7 โดย 1 = วันอาทิตย์
  if (DayO == 1) {
    lcd.print("Sunday");
  }
  else if (DayO == 2) {
    lcd.print("Monday");
  }
  else if (DayO == 3) {
    lcd.print("Tuseday");
  }
  else if (DayO == 4 ) {
    lcd.print("Wednesday");
  }
  else if (DayO == 5) {
    lcd.print("Thurday");
  }
  else if (DayO == 6) {
    lcd.print("Friday");
  }
  else if (DayO == 7) {
    lcd.print("Saturday");
  }
}

void Write_To_DS(byte Sec, byte Min, byte Hou, byte Day, byte Dat, byte Mon, byte Yea) {
  // ตั้งเวลา Wire.beginTransmission(0x68);
  // ติดต่อกับอุปกรณ์ 0x68 (DS3231) Wire.write(0);
  // 0 = ตำแหน่งที่ต้องการเขียน (ดูใน Datasheet DS3231)
  // DEC_To_HEX() : ฟังชั่นแปรงเลขฐาน 10 เป็นฐาน 16 เนื่องจาก DS3231 รับ/ส่งเป็นเลขฐาน 16
  // ส่งค่าเวลาที่ต้องการตั้ง
  Wire.write(DEC_To_HEX(Sec)); Wire.write(DEC_To_HEX(Min)); Wire.write(DEC_To_HEX(Hou));
  Wire.write(DEC_To_HEX(Day)); Wire.write(DEC_To_HEX(Dat)); Wire.write(DEC_To_HEX(Mon));
  Wire.write(DEC_To_HEX(Yea)); Wire.endTransmission(); // จบการติดต่อสื่อสาร delay(5);
}

void Read_From_DS(byte &Se, byte &Mi, byte &Ho, byte &Da, byte &Dt, byte &Mo, byte &Ye) {
  // อ่านค่าเวลา //โดย & คือการระบุ Address ของตัวแปร ให้ตัวแปรในฟังชั่นนี้มี Address ตรงกับค่าที่ส่งมา เมื่อตัวแปรในฟังชั่นนี้เปลี่ยนแปรง
  //ตัวแปรที่ส่งค่ามาก็จะเปลี่ยนไปด้วย
  Wire.beginTransmission(0x68); // ติดต่อกับอุปกรณ์ 0x68 (DS3231)
  Wire.write(0); // 0 = ตำแหน่งที่ต้องการอ่าน (ดูใน Datasheet DS3231)
  Wire.endTransmission(); // จบการติดต่อสื่อสาร Wire.requestFrom(0x68,7); // ขอข้อมูล 7 bit จาก DS3231
  // อ่านข้อมูลเก็บเข้าตัวแปร
  Se = Wire.read(); Mi = Wire.read(); Ho = Wire.read(); Da = Wire.read(); Dt = Wire.read();
  Mo = Wire.read(); Ye = Wire.read();
} byte DEC_To_HEX(byte var) { // แปรงเลขฐาน 10 เป็นฐาน 16 byte H1 = var/10, H2 = var%10;
  // แยกตัวเลขเป็นหลักหน่วยกับหลักสิบ H1 = (H1 << 4) | H2;
  // ขยับเลขหลัก 10 ไปทางซ้าย 4 bit และ Or กับเลขหลัก หน่วย return H1;
  // ส่งค่าคือฟังชั่น
  /* ตัวอย่าง Var = 23 H1 = var/10 = 23/10 : / = หายไม่เอาเศษ
    H1 = 2 = 0010 H2 = var%10 = 23/10 : % = หายเอาเศษ
    H2 = 3 = 0011 H1 = (H1 << 4) | H2 = (0010(เลข 2 ) << 4(ขยับ Bit ไปทางซ้าย 4 bit))
    | 0011(เลข 3) = 00100000(เลข 2 ที่ขยับ Bit ทางซ้าย 4 bit) | 0011(เลข 3) = 00100011
    ค่าที่ส่งออกคือ 00100011(ฐาน 10 = 35)(ฐาน 16 = 23) แปรงเป็นฐาน 16 00100011 = 0010 --> 2 0011 --> 3 = 23 ในฐาน 16 */
}

 

จากตัวอย่างด้านบนเป็นการแสดงค่าจาก DS3231 บน LCD โดยไม่มีการแปลงค่าจากฐาน 16 ที่รับมาจาก DS3231 เป็นฐาน 10 แต่ใช้การแสดงเลขฐาน 16 ด้วย ,HEX ต่อท้ายตัวแปรที่ต้องการแสดง ถ้าต้องการแสดงเวลาโดยไม่ใช้ ,HEX ต้องนำค่าที่รับจาก DS3231 ไปแปลงจากฐาน 16 ให้เป็นฐาน 10 เสียก่อน ยกเว้น Address 0x03 ของ DS3231 (Datasheet DS3231 / วัน) ที่ให้ค่าเป็น 1 – 7 ในฐานสิบโดยเลข 1 คือวันอาทิตย์ และเรียงลำดับตัวเลขตามวันจนถึงเลข 7 คือวันเสาร์ ฟังชั่น Write_To_DS(0,1,13,6,25,6,20); ที่ใส่ Comment ไว้ใน void Setup คือฟังชั่นในการส่งค่าให้กับ DS3231 เพื่อตั้งเวลา

หากไม่ใส่ถ่าน CR2032 บนบอร์ดไว้หรือแบตเตอรี่หมดเวลาที่ตั้งเอาไว้ใน DS3231 จะ Reset กลับไปเป็นค่าเริ่มต้น (00:00:00: 01/01/00)