|
//#define BLYNK_PRINT Serial
#include "Arduino.h"
#include <DHT.h>
#include <Wire.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <HTTPClient.h>
#include <BlynkSimpleEsp32.h>
//#include "settings.h"
//#include "secret.h"
#include <mDNS.h> // For OTA with ESP8266
#include <WiFiUdp.h> // For OTA
#include <ArduinoOTA.h>
#include <timer.h>
#define interruptPin1 34 //switch ฝั่ง on
#define interruptPin2 35 //switch ฝั่ง off
#define interruptFlow 36
#define startvalve 15 //หมุนเปิด V8
#define reverse 18 //D3 หมุนปิด V9
#define IncValve 12 //เพิ่มแรงดันวาวล์ V10
#define DHTPIN 27 //D2 อ่านค่าอุณหภูมิ V1=อุณหภูมิ V2=ความชื้น
//#define voltage 33 //D1 แจ้งเตือนแบตเสื่อม V3
#define DHTTYPE DHT22 //กำหนดชนิด DHT เป็นแบบ DHT22
DHT dht(DHTPIN, DHTTYPE); //SET ตัวแปร dht ให้อ่านค่าจาก sensor
#define PCF8591 (0x90 >> 1)
// กำหนด interval timer
#define INTERVAL_SWON 100
#define INTERVAL_SWOFF 110
#define INTERVAL_READTEMP 1000
#define INTERVAL_READADC 1000
#define DipSwitch2 25
#define DipSwitch3 26
unsigned long time_swon = 0;
unsigned long time_swoff = 0;
unsigned long time_readtemp = 0;
unsigned long time_readadc = 0;
int buttonState1 = 0; // variable for reading the pushbutton status
int buttonState2 = 0; // variable for reading the pushbutton status
//-----------------------------------
byte adcvalue0, adcvalue1, adcvalue2, adcvalue3; //0 วัดค่าแรงดันน้ำ 1 วันค่าอัตราการไหล 2 วัดความชื้นดิน 3 วัดระดับน้ำ
byte minvalve, maxvalve;
byte pressvalue;
int adc0,adc1,adc2,adc3;
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "IoT99"; //ชื่อ wifi
char pass[] = "iot0837286389"; //รหัสผ่าน wifi
//char auth[] = "nP4nCvNfPu-Ytn2RouTB6K3eZOH1C1e5"; //authen code ของ blink เขม
//char auth[] = "JRoohmOBLOZqd1V8jSWwOg96gNmon1VK"; //authen code ของ blink อ.วิสนุกร
char auth[] = "FIW5c0I9nYMO7mFlBrJJLDozA_-l8rBI"; //authen code ของ blink ภานุ
//char auth[] = "_lCq6ZHiOMnwhbDvHRjPsD-f69acnP9r"; //authen code ของ blink อุ้ม
String payload;
auto timer = timer_create_default(); // create a timer with default settings
String valvecommand = "";
String stopcommand = "";
boolean valveopen = false; //สถานะวาวล์เปิด = true ปิด = false
volatile int interruptCounter = 0;
int numberOfInterrupts = 0;
float calibrationFactor = 4.5;
volatile byte pulseCount;
float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
float Q; //Q m^3/s
float V; //V m/s
const float plo = 0.001; // kg/m^3
float Pressure; //q (BAR) q = ½ρ v²
float Diameter = 2.15/100; //A m //แก้ไขนาด รัศมีท่อ
float Area = 3.14159*Diameter*Diameter; //m²
unsigned long oldTime;
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR handleInterrupt() {
portENTER_CRITICAL_ISR(&mux);
interruptCounter++;
portEXIT_CRITICAL_ISR(&mux);
//Serial.println("interrupt");
}
BLYNK_WRITE(V8) //ถ้า Timer ของ Blink ทำงานให้สั่งปิดวาวล์
{
// You'll get HIGH/1 at startTime and LOW/0 at stopTime.
// this method will be triggered every day
// until you remove widget or stop project or
// clean stop/start fields of widget
Serial.print("Got a value: ");
Serial.println(param.asInt());
if(param.asInt() == 0)
{
digitalWrite(startvalve, LOW);
}
if(param.asInt() == 1)
{
valvecommand = "OFF";
digitalWrite(reverse,LOW);
digitalWrite(startvalve, HIGH);
//delay(1000);
}
}
BLYNK_WRITE(V9) //ถ้า Timer ของ Blink ทำงานให้สั่งเปิดวาวล์
{
// You'll get HIGH/1 at startTime and LOW/0 at stopTime.
// this method will be triggered every day
// until you remove widget or stop project or
// clean stop/start fields of widget
Serial.print("Got a value: ");
Serial.println(param.asInt());
if(param.asInt() == 0)
{
digitalWrite(reverse, LOW);
}
if(param.asInt() == 1)
{
valvecommand = "ON";
digitalWrite(startvalve, LOW);
digitalWrite(reverse, HIGH);
//delay(1000);
}
}
BLYNK_WRITE(V10) //ถ้าค่าน้อยสุดของเซนเซอร์ถูกกำหนดค่าใหม่
{
Serial.print("Got a value: ");
Serial.println(param.asInt());
if(param.asInt() > 0)
{
minvalve = param.asInt();
}
}
BLYNK_WRITE(V11) //ถ้าค่ามากสุดของเซนเซอร์ถูกกำหนดค่าใหม่
{
Serial.print("Got a value: ");
Serial.println(param.asInt());
if(param.asInt() > 0)
{
maxvalve = param.asInt();
}
}
BLYNK_WRITE(V12) //ถ้าค่ามากสุดของเซนเซอร์ถูกกำหนดค่าใหม่
{
Serial.print("Got a value: ");
Serial.println(param.asInt());
if(param.asInt() ==1 )
{
//open
digitalWrite(reverse, LOW);
digitalWrite(startvalve, HIGH);
delay(1000);
//read pressure sensor
digitalWrite(startvalve, LOW);
}
}
BLYNK_WRITE(V13) //ถ้าค่ามากสุดของเซนเซอร์ถูกกำหนดค่าใหม่
{
Serial.print("Got a value: ");
Serial.println(param.asInt());
if(param.asInt() ==1 )
{
//open
digitalWrite(startvalve, LOW);
digitalWrite(reverse, HIGH);
delay(1000);
//read pressure sensor
digitalWrite(reverse, LOW);
}
}
void ReadLimitSW() {
if (digitalRead(interruptPin1)==0) {
valveopen = true;
stopcommand = "YES";
}
if (digitalRead(interruptPin2)==0) {
valveopen = false;
stopcommand = "YES";
}
if ((digitalRead(interruptPin1)==1) && digitalRead(interruptPin2==1)) {
valveopen = true;
stopcommand = "";
}
}
void get_device_status(int device_id, String device_text,int Port)
{
HTTPClient http; //start a HTTPClinet as http
//####DO NOT USE THE SAME API as below
http.begin("http://sisatgame.ddns.net/iot/sound_status.php?device_id="+String(device_id)); //Enter your API
int httpCode = http.GET(); //pass a get request
if (httpCode > 0) { //Check the returning code
payload = http.getString(); // Store the value on varibale Payload for debugging
Serial.println(payload); //Print the payload for debugging otherwise comment both lines
http.end();
if (payload.toInt() > 0) {
}
}
}
void set_device_status(int device_id, String device_text,float Value) {
HTTPClient http; //start a HTTPClinet as http
//####DO NOT USE THE SAME API as below
http.begin("http://sisatgame.ddns.net/iot/update_device.php?device_id="+String(device_id)+"&device_value="+String(Value)); //Enter your API
int httpCode = http.GET(); //pass a get request
Serial.println("http://sisatgame.ddns.net/iot/update_device.php?device_id="+String(device_id)+"&device_value="+String(Value));
if (httpCode > 0) { //Check the returning code
Serial.println("UPDATE DATA COMPLETE");
}
}
void set_sound_status(int device_id, String device_text,int Value) {
HTTPClient http; //start a HTTPClinet as http
//####DO NOT USE THE SAME API as below
http.begin("http://sisatgame.ddns.net/iot/update_sound.php?device_id="+String(device_id)+"&device_value="+String(Value)); //Enter your API
//Serial.println("http://sisatgame.ddns.net/iot/update_sound.php?device_id="+String(device_id)+"&device_value=0");
int httpCode = http.GET(); //pass a get request
if (httpCode > 0) { //Check the returning code
Serial.println("UPDATE DATA COMPLETE");
}
}
void setup() {
// declare the ledPin as an OUTPUT:
pinMode(startvalve,OUTPUT); //กำหนด pin Smartvale เป็น output
pinMode(reverse,OUTPUT); //กำหนด pin กลับทิศทาง เป็น output
//pinMode(IncValve,OUTPUT); //กำหนด pin เพิ่มแรงดันวาวล์ เป็น output
digitalWrite(startvalve, LOW); //สั่ง ปิดวาวล์
digitalWrite(reverse, LOW); //สั่ง ปิดการกลับทิศทางหมุน
// pinMode(voltage,INPUT_PULLUP); //กำหนด swith แจ้งเตือนแบต เป็น input แบบ pull up
pinMode(interruptPin1, INPUT); //กำหนด Switch smart valve เป็น input แบบ pull up
pinMode(interruptPin2, INPUT); //กำหนด switch smart valve เป็น input แบบ pull up
pinMode(interruptFlow, INPUT_PULLUP);
pinMode(DipSwitch3, INPUT_PULLUP);
pinMode(DipSwitch2, INPUT_PULLUP);
ReadLimitSW(); //อ่านค่า limit switch ของวาวล์
//========================//
attachInterrupt(digitalPinToInterrupt(interruptFlow), handleInterrupt, FALLING); //กำหนด pin interrupt flow
dht.begin(); //สั่งให้ dht ทำการเปิด
Wire.begin();
Blynk.begin(auth, ssid, pass, "blynk.iot-cm.com", 8080);
Serial.begin(115200);
Blynk.virtualWrite(V10,20);
Blynk.virtualWrite(V11,100);
Blynk.virtualWrite(V12,50);
pulseCount = 0;
flowRate = 0.0;
flowMilliLitres = 0;
totalMilliLitres = 0;
oldTime = 0;
}
void loop() {
///////////////////// อินเตอร์รับ interrupt flowrate ////////////////////================================================
if(interruptCounter>0){
Serial.println("INT COUNTER "+String(interruptCounter));
if (interruptCounter>200) {
interruptCounter = 0;
}
portENTER_CRITICAL(&mux);
interruptCounter--;
pulseCount++;
portEXIT_CRITICAL(&mux);
numberOfInterrupts++;
// Serial.print("An interrupt has occurred. Total: ");
// Serial.println(numberOfInterrupts);
flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
// Note the time this processing pass was executed. Note that because we've
// disabled interrupts the millis() function won't actually be incrementing right
// at this point, but it will still return the value it was set to just before
// interrupts went away.
oldTime = millis();
// Divide the flow rate in litres/minute by 60 to determine how many litres have
// passed through the sensor in this 1 second interval, then multiply by 1000 to
// convert to millilitres.
flowMilliLitres = (flowRate / 60) * 1000;
Q = flowMilliLitres;
Blynk.virtualWrite(V4, Q);
// Add the millilitres passed in this second to the cumulative total
totalMilliLitres += flowMilliLitres;
unsigned int frac;
// // Print the flow rate for this second in litres / minute
// Serial.print("Flow rate: ");
// Serial.print(int(flowRate)); // Print the integer part of the variable
// Serial.print("."); // Print the decimal point
// // Determine the fractional part. The 10 multiplier gives us 1 decimal place.
// frac = (flowRate - int(flowRate)) * 10;
// Serial.print(frac, DEC) ; // Print the fractional part of the variable
// Serial.print("L/min");
// Print the number of litres flowed in this second
Serial.print(" Current Liquid Flowing: "); // Output separator
Serial.print(flowMilliLitres);
Serial.print("mL/Sec");
V = (Q / Area)/1000000;
//calculate q = ½ρ v² (SI units):
Pressure = (0.5*(plo)*V*V)/0.00001; //Bar)
Serial.print(" Pressure Liquid: ");
Serial.print(Pressure);
Serial.print("Bar");
Blynk.virtualWrite(V15,Pressure);
// Print the cumulative total of litres flowed since starting
Serial.print(" Output Liquid Quantity: "); // Output separator
Serial.print(totalMilliLitres);
Serial.println("mL");
// Reset the pulse counter so we can start incrementing again
pulseCount = 0;
}
//==================== timer check sw on ========================================
if(millis() > time_swon + INTERVAL_SWON){
time_swon = millis();
buttonState1 = digitalRead(interruptPin1);
buttonState2 = digitalRead(interruptPin2);
if (buttonState1==LOW) {
Serial.println("Limit Switch ON");
Blynk.virtualWrite(V20,HIGH);
}
if ((buttonState1==LOW) && (valvecommand=="ON")) {
digitalWrite(startvalve,LOW);
digitalWrite(reverse,LOW);
Blynk.virtualWrite(V8,LOW);
Blynk.virtualWrite(V9,LOW);
valvecommand = "";
}
}
//==================== timer check sw off ========================================
if(millis() > time_swoff + INTERVAL_SWOFF){
time_swoff = millis();
buttonState1 = digitalRead(interruptPin1);
buttonState2 = digitalRead(interruptPin2);
if (buttonState2==LOW) {
Serial.println("Limit Switch OFF");
Blynk.virtualWrite(V20,LOW);
}
if ((buttonState2==LOW) && (valvecommand=="OFF")) {
digitalWrite(startvalve,LOW);
digitalWrite(reverse,LOW);
Blynk.virtualWrite(V8,LOW);
Blynk.virtualWrite(V9,LOW);
valvecommand = "";
}
}
//==================== timer readtemp ========================================
if(millis() > time_readtemp + INTERVAL_READTEMP){
time_readtemp = millis();
ReadTemp();
}
//==================== timer read ADC ========================================
if(millis() > time_readadc + INTERVAL_READADC){
time_readadc = millis();
ReadADC();
}
//====================================================================
Blynk.run();
if (digitalRead(DipSwitch2)==0) {
valvecommand = "";
}
if (digitalRead(DipSwitch3)==0) {
minvalve = 10;
maxvalve = 30;
ReadLimitSW();
ConditionValve();
delay(1000);
}
}
void ConditionValve() {
ReadLimitSW();
Serial.print("Valve Command = ");
Serial.println(valvecommand);
buttonState1 = digitalRead(interruptPin1);
buttonState2 = digitalRead(interruptPin2);
if ((adcvalue3<minvalve) && (valvecommand=="")) {
if (buttonState2==LOW) {
valvecommand = "ON";
digitalWrite(startvalve, LOW);
digitalWrite(reverse, HIGH);
}
} else if ((adcvalue3>maxvalve) && (valvecommand=="")) {
if (buttonState1==LOW) {
valvecommand = "OFF";
digitalWrite(reverse,LOW);
digitalWrite(startvalve, HIGH);
}
}
}
void ReadValveStatus() {
if (valveopen) {
Serial.print("Valve status = OPEN ");
Serial.print("Stop Command = "+stopcommand+" ");
Serial.println("Command = "+valvecommand);
Blynk.virtualWrite(V17,1);
} else {
Serial.print("Valve status = OFF ");
Serial.print("Stop Command = "+stopcommand+" ");
Serial.println("Command = "+valvecommand);
Blynk.virtualWrite(V17,0);
}
buttonState1 = digitalRead(interruptPin1);
buttonState2 = digitalRead(interruptPin2);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState1 == LOW) {
// turn LED on:
Serial.println("S1");
} else if (buttonState2 == LOW) {
// turn LED off:
Serial.println("S2");
}
}
void ReadADC() {
Wire.beginTransmission(PCF8591);
Wire.write(0x04);
Wire.endTransmission();
Wire.requestFrom(PCF8591, 5);
adcvalue0=Wire.read();
adcvalue1=Wire.read();
adcvalue2=Wire.read();
adcvalue3=Wire.read();
adc2 = (adcvalue2 / 255) * 100;
adc3 = (adcvalue3 / 255) * 100;
Serial.print(adcvalue0);
Serial.print(" ,");
Serial.print(adcvalue1);
Serial.print(" ,");
Serial.print(adc2);
Serial.print(" ,");
Serial.print(adc3);
Serial.print(" ,");
Serial.println();
Blynk.virtualWrite(V3, adcvalue0); //แรงดันน้ำ
Blynk.virtualWrite(V5, adcvalue1); //แบตเตอรี่
Blynk.virtualWrite(V6, adcvalue2); //LDR
Blynk.virtualWrite(V7, adcvalue3); //ความชื้นดิน
}
void GainValve() {
digitalWrite(IncValve,HIGH);
Serial.println("Increase Valve Voltage");
}
void ReadTemp() {
float t12 = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f12 = dht.readTemperature(true);
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h12 = dht.readHumidity();
int Val = 0;
bool dht12Read = true;
// Check if any reads failed and exit early (to try again).
if (isnan(h12) || isnan(t12) || isnan(f12)) {
Serial.println("Failed to read from DHT12 sensor!");
dht12Read = false;
}
if (dht12Read){
// Compute heat index in Fahrenheit (the default)
float hif12 = dht.computeHeatIndex(f12, h12);
// Compute heat index in Celsius (isFahreheit = false)
float hic12 = dht.computeHeatIndex(t12, h12, false);
// Compute dew point in Fahrenheit (the default)
//float dpf12 = dht.dewPoint(f12, h12);
// Compute dew point in Celsius (isFahreheit = false)
//float dpc12 = dht.dewPoint(t12, h12, false);
Serial.print("DHT12=> Humidity: ");
Serial.print(h12);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t12);
Serial.println(" *C ");
Blynk.virtualWrite(V1, t12);
Blynk.virtualWrite(V2, h12);
}
}
|
|