//程式名稱:定時偵測環境資訊存記憶卡(未放記憶卡將無法正常工作) //功能說明:定時偵測光線將結果顯示在 LCD及序列埠視窗,利用按鈕開關切換寫入或不寫入 SD記憶卡 //光敏電阻=A0,土壤濕度感測器=A1,按鈕模組=2,溫濕度感測器DHT11=3 //時鐘模組DS1302腳位 RST=5,DAT=6,CLK=7 //液晶顯示模組的SDA、SCL接擴展版同名稱位置(SDA=A4,SCL=A5) //記憶卡Micro SD模組 CS=10,MOSI=11,MISO=12,SCK(CLK)=13
#include "DHT.h" // 溫濕度感測器DHT11,函式庫名稱:DHT sensor library,by Adafruit(要先安裝:[工具]/[管理程式庫]) #define DHTPIN 3 // 定義溫濕度感測器DHT11的接腳 #define DHTTYPE DHT11 // 定義溫濕度感測器的型號為DHT11 DHT dht(DHTPIN, DHTTYPE); //建立DHT物件名稱為dht
#include <ThreeWire.h> //使用內建函式庫控制I2C介面 #include <RtcDS1302.h> // 時鐘模組DS1302,函式庫名稱:Rtc by Makuna,by Michael C. Miller(要先安裝:[工具]/[管理程式庫]) ThreeWire myWire(6, 7, 5); // 設定時鐘模組腳位(DAT, CLK, RST) RtcDS1302<ThreeWire> Rtc(myWire);
#include <SPI.h> // 使用內建的函式庫SPI.h,控制ISPI介面 #include <SD.h> // 記憶卡使用內建的函式庫SD.h,控制SD記憶卡模組 #define SD_CS_PIN SS // CS腳位預設是SS腳位10,如果有多個SPI設備,要設定不同的腳位 File myFile; // 建立檔案物件名稱為myFile
#include <LiquidCrystal_PCF8574.h> // LCD液晶顯示模組,函式庫名稱:LiquidCrystal_PCF8574,by Matthias Hertel(要先安裝:[工具]/[管理程式庫]) LiquidCrystal_PCF8574 lcd(0x27); // LCD液晶顯示模組的 i2c位址設定為0x27或0x3F int BUTTON_PIN = 2; // 設定按鈕開關的腳位 boolean buttonState = false; // 設定按鈕開關的現在狀態為布林值0(false) int delayTime =5; //設定定時偵測要間隔幾秒,(請自行修改秒數) int timeCount =0; //配合間隔秒數使用計時迴圈,將迴圈次數的初始值設為0(不要修改)
void setup(){ Serial.begin(9600); // 設定與電腦序列埠監控視窗的速率相同 Rtc.Begin(); //時鐘模組開始執行 if (Rtc.GetDateTime() != RtcDateTime(__DATE__, __TIME__)){ //如果時鐘模組的時間與程式編譯當時的電腦時間不同,就更改時間模組的時間 Serial.println("RTC is older than compile time! (Updating DateTime)"); Rtc.SetDateTime(RtcDateTime(__DATE__, __TIME__)); } if (!SD.begin(SD_CS_PIN)) { // 判斷SD模組初始化是否成功 Serial.println("initialization failed!"); // 序列埠監控視窗顯示SD模組初始化失敗並結束離開 return; //結束直接跳離開此setup初始設定函式 } Serial.println("Micro SD initialization done."); // 序列埠監控視窗顯示初始化完成 dht.begin(); // 溫濕度感測器DHT11開始執行 lcd.begin(16, 2); // LCD初始化,寬度16字,高度2行 lcd.setBacklight(255); // 設定背景亮度為255 lcd.clear(); // 清除LCD顯示器的文字 pinMode(A0,INPUT); // 設定光敏電阻接在 A0(類比第0接腳)為輸入功能 }
void loop(){ RtcDateTime now = Rtc.GetDateTime(); // 建立時鐘物件名稱為now String t1="/", t2=":", t3=" "; // 設定時間的數字要合併顯示時中間的文字 "/",":"," " ,例如:年/月/日 時:分:秒 String timeNow=now.Year()+t1+now.Month()+t1+now.Day()+t3+now.Hour()+t2+now.Minute()+t2+now.Second(); //設定現在的時間變數為 timeNow存放時鐘模組的時間 Serial.println(timeNow); //將時間顯示在序列埠視窗 int h = dht.readHumidity(); //取得溫濕度感測器DHT11的濕度 int t = dht.readTemperature(); //取得溫濕度感測器DHT11的溫度C int moisture = analogRead(A1); //取得土壤濕度感測器數值 int light = analogRead(A0); //取得光敏電阻的亮度數值 String str1 = "DATA="; //設定字串變數 str1放文字 "DATA=" String str2 = ","; //設定字串變數 str2放文字 "," String str3 = " "; //設定字串變數 str3放5個空格 Serial.println(str1 + light + str2+h+str2+t+str2+moisture+str3); //序列埠視窗顯示偵測到的數值前後合併字串 lcd.setCursor(0, 0); //LCD定位在第0個字、第0列位置 lcd.print(str1 + light + str2+h+str2+t+str2+moisture); //LCD將偵測到的數值前後合併字串顯示出來 if (buttonState){ // 如果按鈕被按下狀態為 true 就開始將偵測結果寫入記憶卡 SD myFile = SD.open("test.txt", FILE_WRITE); // 開啟檔案 test.txt 設定為寫入模式,如果檔案不存在會自動建立(不可用中文檔名) if (myFile){ // 如果開啟檔案成功狀態為 true 就進行以下的寫入SD程式 myFile.println(timeNow); // 將現在時間變數存到 test.txt 檔案中 myFile.println(str1 + light + str2+h+str2+t+str2+moisture); // 將光線 light、濕度 h、溫度 t、土壤濕度 moisture存到 test.txt 檔案中 myFile.close(); // 關閉檔案 Serial.println("Writing to test.txt..."); // 序列埠監控視窗顯示文字 lcd.setCursor(0, 1); // LCD 定位到第0個字、第1列位置 lcd.print("Write to SD "); // LCD 顯示文字 } else { // 如果無法開啟檔案,就在序列埠及LCD顯示錯誤訊息 Serial.println("error opening test.txt"); lcd.setCursor(0, 1); lcd.print("Write error "); } } else { // 如果按鈕沒有被按下狀態為 False ,序列埠及LCD顯示停止寫入的訊息 Serial.println("Write stop "); lcd.setCursor(0, 1); //定位在 LCD 的第0個字、第1列位置 lcd.print("Write stop "); } timeCount = 0; //將計時迴圈次數的初始值設為0(不要修改) while(timeCount < delayTime * 10){ // 計時迴圈變數 timeCount每跑一圈為0.1秒,當未達到間隔秒數時繼續偵測按鈕開關是否被按下 if (!digitalRead(BUTTON_PIN)){ // 偵測按鈕被按下時讓按鈕狀態buttonState設定為相反 buttonState = !buttonState; // 按鈕狀態設定為相反 delay(500); // 等待 0.5秒預防按鈕多次反彈的不正常狀況 break; // 離開while迴圈 } timeCount++; // 計時迴圈變數加 1 delay(100); // 等待 0.1秒 } }
|