2018年8月23日 星期四

arduino+DS3231時鐘+0.96OLED or I2C_LCD模組


參考文章
【自造學堂】如何用Arduino x RTC完成LCD時間顯示?
*0*RTC(即時時鐘)模組*0* 如何更新 DS3231 RTC 模組的時間與大型數字時鐘製作

需要安裝資料庫
for DS3231
(下載後解壓縮安裝)  DS3231_TEST

for 0.96OLED
(資料庫搜尋安裝)      Adafruit_GFX
(資料庫搜尋安裝)      Adafruit_SSD1306

for I2C LCD
(資料庫搜尋安裝)      LiquidCrystal_I2C

額外經驗
如何把1變成01(補0)
C語言Printf 自動補0
Topic: Leading zeros for seconds coding

之後要研究的
按鈕改時間設定
https://github.com/tehniq3/oled_096_128x64_i2c_RTC_animated-clock
http://ruten-proteus.blogspot.com/2017/08/ds3231-rtc-iiclcd-clock.html



程式碼-DS3231時鐘+0.96OLED
#include <DS3231.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//時鐘設定
DS3231 Clock;
bool Century=false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;
byte year, month, date, DoW, hour, minute, second;

//OLED設定
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

//螢幕設定,定義顯示高度跟寬度
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

char buffer [16];
char time [16];

void setup() {
  // Start the I2C interface
  Wire.begin();
  //第一次使用要設定以下時間,之後就可以不用設定了
  //Clock.setSecond(00);//Set the second
  //Clock.setMinute(25);//Set the minute
  //Clock.setHour(16); //Set the hour
  //Clock.setDoW(4); //Set the day of the week
  //Clock.setDate(23); //Set the date of the month
  //Clock.setMonth(8); //Set the month of the year
  //Clock.setYear(17); //Set the year (Last two digits of the year)
  // Start the serial interface
  Serial.begin(9600);

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
  display.clearDisplay();
}

void loop() {
  int sec,minute,hour,date,month,year,temperature;
  sec=Clock.getSecond();
  minute=Clock.getMinute();
  hour=Clock.getHour(h12, PM);
  date=Clock.getDate();
  month=Clock.getMonth(Century);
  year=Clock.getYear();

  temperature=Clock.getTemperature();

  sprintf(time,"20%02u-%02u-%02u",year,month,date); //設定印出01,02,而非1,2
  sprintf(buffer,"%02u:%02u:%02u",hour,minute,sec); //設定印出01,02,而非1,2

  Serial.print("20");
  Serial.print(year,DEC);
  Serial.print(time);
  Serial.print(' ');
  Serial.print(buffer);
  Serial.print('\n');
  Serial.print("Temperature=");
  Serial.print(temperature);
  Serial.print('\n');

  //英文字符显示
  display.setTextColor(WHITE);        //设置字体颜色白色
  display.setCursor(0,0);             //设置字体的起始位置
  display.setTextSize(1);             //设置字体大小
  display.print(time);
  display.setCursor(86,0);
  display.print(temperature);
  display.println("oC");
  display.setTextSize(2);             //设置字体大小
  display.print(buffer);
  delay(1000);
  display.display(); 
  display.clearDisplay();
}


程式碼-DS3231時鐘+I2C_LCD
#include <DS3231.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

DS3231 Clock;
bool Century=false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;
byte year, month, date, DoW, hour, minute, second;

//LED_Fundino紅色板子用
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
//LED_MH黑色板子用
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

//建立O型
byte OC[8] = {
  B01100,
  B10010,
  B01100,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000
};

//設定暫存
char buffer [16];
char time [16];

void setup() {
// Start the I2C interface
  Wire.begin();
  //第一次使用要設定以下時間,之後就可以不用設定了
  //Clock.setSecond(00);//Set the second
  //Clock.setMinute(25);//Set the minute
  //Clock.setHour(16); //Set the hour
  //Clock.setDoW(4); //Set the day of the week
  //Clock.setDate(23); //Set the date of the month
  //Clock.setMonth(8); //Set the month of the year
  //Clock.setYear(17); //Set the year (Last two digits of the year)
  // Start the serial interface
  Serial.begin(115200);

  // 初始化 LCD,一行 16 的字元,共 2 行,預設開啟背光
  lcd.begin(16, 2);

  //建立OC型
  lcd.createChar (1, OC);  // load OC to memory 1

  // 閃爍2次
  for(int i = 0; i < 1; i++) {
    lcd.backlight(); // 開啟背光
    delay(50);
    lcd.noBacklight(); // 關閉背光
    delay(50);
  }
  lcd.backlight();

  // 輸出初始化文字
  lcd.setCursor(0, 0); // 設定游標位置在第一行行首
  lcd.print("DCJH-Maker");
  delay(500);
  lcd.setCursor(0, 1); // 設定游標位置在第二行行首
  lcd.print("Hello,MAKER!");
  delay(1000);
  lcd.clear();
}

void loop() {
  int second,minute,hour,date,month,year,temperature;
  second=Clock.getSecond();
  minute=Clock.getMinute();
  hour=Clock.getHour(h12, PM);
  date=Clock.getDate();
  month=Clock.getMonth(Century);
  year=Clock.getYear();

  temperature=Clock.getTemperature();

  sprintf(time,"20%02u-%02u-%02u",year,month,date); //設定印出01,02,而非1,2
  sprintf(buffer,"%02u:%02u:%02u",hour,minute,second); //設定印出01,02,而非1,2

  Serial.print(time);
  Serial.print(' ');
  Serial.print(buffer);
  Serial.print('\n');
  Serial.print("Temperature=");
  Serial.print(temperature);
  Serial.print('\n');

  lcd.setCursor(0, 0); // 設定游標位置在第一行行首
  lcd.print(time);
  lcd.setCursor(12, 0);
  lcd.print(temperature);
  lcd.print(char(1));
  lcd.print("C");
  lcd.setCursor(0, 1); // 設定游標位置在第二行行首
  lcd.print(buffer);

  delay(1000);
}