#define BLYNK_PRINT Serial #include #include #include #include #include "RTClib.h" // Libraries for SD card #include "FS.h" #include "SD.h" #include const int sensorPin = D3; // WeMos & NodeMCU D3 ///// set AUTH,WIFI char auth[] = "************"; char ssid[] = "************"; char pass[] = "************"; // The hall-effect flow sensor outputs approximately 4.5 pulses per second per litre/minute of flow. float calibrationFactor = 1;//4.5, 7.5 ,1 volatile byte pulseCount; float flowRate ; float flowLitres ; unsigned int flowMilliLitres ; unsigned long totalMilliLitres ; unsigned long delTime; unsigned long currentTime ; //เวลาปัจจุบัน unsigned long previousTime; //เวลาก่อนหน้า float totalLitres = 0.0; String dataMessage; char buffer1[26]; char buffer2[26]; const int SD_CS = D8; // เสียบช่อง D8 ถ้าจะเปลี่ยนช่องเปลี่ยนตรงนี้ด้วย RTC_DS3231 rtc; LiquidCrystal_I2C lcd(0x27,16,2); //BlynkTimer timer; SimpleTimer timer; void setup(){ Serial.begin(115200); Serial.println(); pinMode(sensorPin, INPUT_PULLUP); digitalWrite(sensorPin, HIGH); // lcd.begin(); lcd.init(); lcd.backlight(); pulseCount = 0; flowRate = 0.0; flowMilliLitres = 0; totalMilliLitres = 0; previousTime = 0; //////////////////////////////////////////////////////// /* if (! rtc.begin()) { Serial.println("Couldn't find RTC"); Serial.flush(); abort(); }*/ if (rtc.lostPower()) { Serial.println("RTC lost power, let's set the time!"); // When time needs to be set on a new device, or after a power loss, the // following line sets the RTC to the date & time this sketch was compiled //rtc.adjust(DateTime(__DATE__,__TIME__)); // This line sets the RTC with an explicit date & time, for example to set // January 21, 2014 at 3am you would call: //rtc.adjust(DateTime(2021, 5, 25, 0, 33, 0)); } lcd.setCursor(0, 0);lcd.print("Initial SD card "); // Initialize SD card if(!SD.begin(SD_CS)) { Serial.println("Card Mount Failed"); return; } File dataFile = SD.open("datalog.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.println("Date,Time,flowRate,totalLitres\r\n"); dataFile.close(); } lcd.setCursor(0, 0);lcd.print("Blynk Connecting"); Blynk.begin(auth, ssid, pass,"pkdb10.thddns.net",8334); delay(4000); lcd.clear(); // Configured to trigger on a FALLING state change (transition from HIGH state to LOW state) attachInterrupt(digitalPinToInterrupt(sensorPin), pulseCounter, FALLING); timer.setInterval(1000L, showFlow); } void showFlow() //average the flow over averageperiod { detachInterrupt(digitalPinToInterrupt(sensorPin)); currentTime = millis(); delTime = currentTime-previousTime; previousTime = currentTime; flowRate = ((1000.0 * pulseCount)/delTime) / calibrationFactor ; // L/min flowMilliLitres = (flowRate / 60.0) * 1000.0; // mL/s flowLitres = (flowRate / 60.0); // L/s totalMilliLitres += flowMilliLitres; // mL totalLitres += flowLitres; // L // Print the flow rate for this second in litres / minute Serial.print("Flow rate: "); Serial.print(flowRate, 1) ; // Print the fractional part of the variable Serial.print("L/min"); Serial.print(" Output Liquid Quantity: "); // Output separator Serial.print(totalLitres); Serial.println("L"); Blynk.virtualWrite(V1, flowRate); Blynk.virtualWrite(V2, totalLitres); ////////////Get date/time///////////// DateTime now = rtc.now(); sprintf(buffer1,"%02u-%02u-%04u",now.day(),now.month(),now.year()); sprintf(buffer2,"%02u:%02u:%02u",now.hour(),now.minute(),now.second()); // Serial.print(buffer1);Serial.println(buffer2); ////////////// dataMessage = String(buffer1)+ "," + String(buffer2) + "," + String(flowRate) + "," + String(totalLitres) + "\r\n"; Serial.print("Save data: "); Serial.println(dataMessage); // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. File dataFile = SD.open("datalog.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.println(dataMessage); dataFile.close(); // print to the serial port too: Serial.println(dataMessage); } // if the file isn't open, pop up an error: else { Serial.println("error opening datalog.txt"); } ///////////////print to LCD///////////// lcd.setCursor(0, 0);lcd.print("Q="); lcd.setCursor(3, 0);lcd.print(flowRate); lcd.setCursor(7, 0);lcd.print(" "); lcd.setCursor(8, 0);lcd.print("L/min"); lcd.setCursor(11, 1);lcd.print(now.hour(),DEC); lcd.setCursor(13, 1);lcd.print(":"); lcd.setCursor(14, 1);lcd.print(now.minute(),DEC); lcd.setCursor(0, 1);lcd.print("V="); lcd.setCursor(3, 1);lcd.print(totalLitres); lcd.setCursor(7, 1);lcd.print(" "); lcd.setCursor(8, 1);lcd.print("L"); pulseCount = 0; attachInterrupt(digitalPinToInterrupt(sensorPin), pulseCounter, FALLING); } ////////////////////////////////////// ICACHE_RAM_ATTR void pulseCounter(){ // Increment the pulse counter pulseCount++; } void loop(){ Blynk.run(); timer.run(); }