สำหรับในโพสต์นี้ผมศึกษาเกี่ยวกับเรื่องของการเก็บข้อมูลบันทึกเข้าไปใน SD Card module โดยได้ประยุกต์โค้ดต่างๆที่ได้ศึกษามาให้ได้ตามความต้องการดังนี้
- ชื่อไฟล์ .txt เราสามารถตั้งชื่อไว้ใน SD Card ก่อนหรือไม่ต้องสร้างเลยก็ได้เพราะ เพราะระบบจะสร้างชื่อไฟล์และนามสกุลตามโค้ดที่เรากำหนดลงไป
- ช่วงที่ esp 8266 เริ่มทำงาน ถ้าไม่ได้ใส่ SD Card เข้าไป ตั้งแต่แรก ระบบจะไม่สามารถเขียนหรืออ่านข้อมูลจาก SD Card ได้ หลังจากใส่ SD Card เข้าไปแล้วให้กดปุ่ม Reset esp 8266 1 ครั้ง ระบบก็จะทำงานปกติ
- ในขณะที่ระบบทำงานปกติหากเราต้องการที่จะนำ SD Card ออกมาเพื่อที่จะนำไปดูข้อมูลในเครื่องคอมพิวเตอร์ ระบบจะทำการหยุดอ่านและเขียนข้อมูลใน SD Card ทันที
- หลังจากที่เราดูข้อมูลจาก SD Card ด้วยคอมพิวเตอร์เสร็จเรียบร้อยแล้ว ถ้าเราลบไฟล์นั้นออก เมื่อเสียบกลับเข้าไปใน SD Card module ระบบก็จะทำการ สร้างชื่อไฟล์และนามสกุลตามที่กำหนดลงในโค้ดใหม่และทำการเขียนข้อมูลลงไปใหม่ได้ หรือถ้าเราไม่ลบไฟล์นั้น ระบบจะทำการเขียนค่าต่อจากของเดิมอย่างต่อเนื่อง โดยไม่ต้องมากด Reset esp 8266 ทุกครั้ง
- ระบบตอนนี้ยังไม่ได้เชื่อมต่อ wi-fi Internet สาเหตุที่ใช้ esp 8266 ผมจะเผื่อเอาไว้สำหรับการเชื่อมต่อ WiFi Internet ไว้ก่อนเท่านั้นเอง
- Code ที่ใช้อยู่สามารถดูตัวอย่างได้จาก Library SD ของ esp 8266 ได้ ประกอบกับศึกษาจากเว็บไซต์ต่างๆซึ่งมีสิ่งที่เราต้องการอยู่แล้ว โปรเจคนี้เลยไม่มีอะไรที่หวือหวา เพียงแต่นำมาประยุกต์ให้ได้ตามสิ่งที่เราต้องการเท่านั้นเองครับ
#include <SPI.h>
#include <SD.h>
File myFile; // สร้างออฟเจก File สำหรับจัดการข้อมูล
const int chipSelect = D4;
//RTC Library
#include "Arduino.h"
#include "Wire.h"
#include "uRTCLib.h"
// uRTCLib rtc;
uRTCLib rtc(0x68);
int year_;
#include <DHT.h>
#define DHTTYPE DHT21
#define DHTPIN D3
DHT dht(DHTPIN, DHTTYPE);
int faild = 0;
int done = 0;
Sd2Card card;
void setup()
{
Serial.begin(115200);
dht.begin();
#ifdef ARDUINO_ARCH_ESP8266
Wire.begin(4, 5); // GPIO4 = D2 and GPIO5 = D1 on ESP8266
#else
Wire.begin();
#endif
//rtc.set(0, 17, 15, 3, 5, 3, 20);//ใช้เฉพาะตั้งเวลา ถ้าจะตั้งก็ เอา // ออก เมื่อตั้งได้ตรงแล้วก็เอา // ใส่กลับไปเหมือนเดิม
// RTCLib::set(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year)
Serial.println();
Serial.println("Initializing SD card...");
delay(300);
pinMode(SS, OUTPUT);//หรือขา CS จะกำหนดเป็นขาใดก็ได้ ในที่นี้กำหนดเป็นขา D4
if (!SD.begin(chipSelect)) {
Serial.println("initialization failed!");// ถ้าเริ่มทำงาน ถ้าไม่เสียบ SD Card ได้ แสดงข้อความ initialization failed
return;
}
Serial.println("initialization done."); // ถ้าเริ่มทำงาน SD Card ได้ แสดงข้อความ initialization done
// ปักหมุดชื่อว่า createNew ไว้หากสร้างไฟล์ไม่เสร็จ จะให้กลับมาที่จุดนี้ใหม่
createNew:
// เปิดไฟล์ ชื่อ test.txt ขึ้นมา เราจะสามารถเปิดได้ครั้งละ 1 ไฟล์เท่านั้น
// หากต้องการใช้งานหลายไฟล์ ทำได้โดยการปิดไฟล์หนึ่งไปก่อน แล้วเปิดอีกไฟล์ขึ้นมาทำงาน
// หากไม่มีไฟล์ที่ชื่อตามต้องการ จะเป็นการสร้างไฟล์ขึ้นมาใหม่
myFile = SD.open("PM_check.txt", FILE_WRITE);
// ปิดไฟล์ลงไปก่อน
myFile.close();
// ลองตรวจสอบดูว่ามีไฟล์อยู่หรือไม่ ถ้ามี Serial monitor บอกว่ามีไฟล์อยู่ ถ้าไม่มีให้แสดงว่าไม่มี
// เราเพิ่งสร้างไฟล์ใหม่ขึ้นมา ปกติต้องมีไฟล์ แต่หากไม่มีก็เขียนดค้ด goto กลับไฟสร้างไฟล์ใหม่อีกครั้ง
if (SD.exists("PM_check.txt")) {
Serial.println("File exists.");
} else {
Serial.println("File doesn't exists.");
goto createNew;
}
delay(3000);
// ปักหมุดชื่อ newWrite ไว้กรณีเขียนไฟล์ไม่สำเร็จ ให้กลับมาจุดนี้ใหม่
newWrite:
// ทำการเปิดไฟล์อีกครั้งแล้วทำการเขียนข้อความว่า testing SD Card..... ลงไปในไฟล์
myFile = SD.open("PM_check.txt", FILE_WRITE);
if (myFile) {
Serial.print("Writing to PM_check.txt...");
//myFile.println("รายงานการเก็บข้อมูล.....");
// ปิดไฟล์แล้วแสดงผล done
myFile.close();
Serial.println("done.");
} else {
// หากเปิดไฟล์ขึ้นมาไม่สำเร็จ แสดง error แล้วกลับไปที่ newWrite เพื่อลองทำใหม่
Serial.println("error opening file");
goto newWrite;
}
delay(3000);
}//void setup
void loop()
{
float h = dht.readHumidity();
float t = dht.readTemperature();
rtc.refresh();
year_ = rtc.year() + 2543; //+43 เพื่อให้ได้ปี พ.ศ. 63
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
//Serial.println("initialization failed. Things to check:");
Serial.println("* is a card inserted?");
//Serial.println("* is your wiring correct?");
//Serial.println("* did you change the chipSelect pin to match your shield or module?");
return;
} else {
myFile = SD.open("PM_check.txt", FILE_WRITE);
// ถ้าเปิดไฟล์สำเร็จ ให้เขียนข้อมูลเพิ่มลงไป
if (myFile) {
Serial.println("Writing to PM_check.txt...");
myFile.print(" Date: ");
myFile.print("\t"); // \t = เว้น 1 tab มีผลตอนวางลงใน Excel
if (rtc.day() < 10)
{
myFile.print("0");
myFile.print(rtc.day());
}
else myFile.print(rtc.day());
myFile.print('-');
if (rtc.month() < 10)
{
myFile.print("0");
myFile.print(rtc.month());
}
else myFile.print(rtc.month());
myFile.print('-');
myFile.print(year_);
myFile.print("\t"); // \t = เว้น 1 tab มีผลตอนวางลงใน Excel
myFile.print(" Time: ");
myFile.print("\t"); // \t = เว้น 1 tab มีผลตอนวางลงใน Excel
if (rtc.hour() < 10)
{
myFile.print("0");
myFile.print(rtc.hour());
}
else myFile.print(rtc.hour());
myFile.print(':');
if (rtc.minute() < 10)
{
myFile.print("0");
myFile.print(rtc.minute());
}
else myFile.print(rtc.minute());
myFile.print(':');
if (rtc.second() < 10)
{
myFile.print("0");
myFile.print(rtc.second());
}
else myFile.print(rtc.second());
myFile.print("\t"); // \t = เว้น 1 tab มีผลตอนวางลงใน Excel
myFile.print(" = ");
myFile.print("\t"); // \t = เว้น 1 tab มีผลตอนวางลงใน Excel
// บันทึกที่ต้องการ
myFile.print("Temp.= ");
myFile.print(t, 2);
myFile.print(" °C");
myFile.print("\t"); // \t = เว้น 1 tab
myFile.print("Humid.= ");
myFile.print(h, 2);
myFile.println(" %");
// ปิดไฟล์
myFile.close();
Serial.println("done.");
//Serial.println();
}
}
// หน่วงเวลา 2 วินาที
delay(2000);
}//void loop