#include "DHT.h"
#define DHTPIN 15     // what pin we're connected to
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
#define THINGSPEAK_API_KEY "1P4RY69D3YMP9R5W"
#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>
//-----------------------------
#include <ArduinoJson.h>
StaticJsonDocument<200>JsonDocument;
SoftwareSerialmyserial(10, 11);
//-------------------------
float voltage;
unsignedintfrac;
//---------------------
#define ONE_WIRE_BUS 5
OneWireoneWire(ONE_WIRE_BUS);
DallasTemperaturesensors(&oneWire);
floatCelcius = 0;
float Fahrenheit = 0;
//==========================================================================================================
bytesensorInterrupt = 0;  // 0 = digital pin 2
bytesensorPin       = 2;
// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
// litre/minute of flow.
floatcalibrationFactor = 5.5;  //==========================================================we change cal factor 4.5 to 5.5  if not work chnage again(4.5)
//========== 5.5 calibration factor is working efficent then 4.5 , 7.5 ,and 6.5
volatile byte pulseCount;
floatflowRate;
unsignedintflowMilliLitres;
unsigned long totalMilliLitres, tempTotal = -1;
unsigned long oldTime;
//-------------------------------------------------------
intpH_Value;
float Voltage;
//----------------------------------------------------------------------------------------------
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
myserial.begin(9600);
  //--------------------------------
pinMode(sensorPin, INPUT);
digitalWrite(sensorPin, HIGH);
pulseCount        = 0;
flowRate          = 0.0;
flowMilliLitres   = 0;
totalMilliLitres  = 0;  // ============================================================
oldTime           = 0;
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
sensors.begin();
  //------------------------------------------------
  /********************GSM Communication Starts********************/
if (myserial.available())
Serial.write(myserial.read());
myserial.println("AT");
delay(1000);
myserial.println("AT+SAPBR=3,1,\"Contype\",\"GPRS\"");
delay(1000);
ShowSerialData();
myserial.println("AT+SAPBR=3,1,\"APN\",\"www\"");//APN
delay(1000);
ShowSerialData();
myserial.println("AT+SAPBR=1,1");
delay(1000);
ShowSerialData();
myserial.println("AT+SAPBR=2,1");
delay(1000);
ShowSerialData();
  //---------------------------------
}
void loop() {
  // put your main code here, to run repeatedly:
inti;
for (i = 0; i< 20; i++)
  {
flow_meter();
  }
temperature();
turbidity();
delay(1000);
gsm();
}
voidflow_meter()
{
if ((millis() - oldTime) > 1000)   // Only process counters once per second
  {
    // Disable the interrupt while calculating flow rate and sending the value to
    // the host
detachInterrupt(sensorInterrupt);
    // Because this loop may not complete in exactly 1 second intervals we calculate
    // the number of milliseconds that have passed since the last execution and use
    // that to scale the output. We also apply the calibrationFactor to scale the output
    // based on the number of pulses per second per units of measure (litres/minute in
    // this case) coming from the sensor.
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;
    // Add the millilitres passed in this second to the cumulative total
totalMilliLitres += flowMilliLitres;
    // 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.println("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");
      // Print the cumulative total of litres flowed since starting
Serial.print("  Output Liquid Quantity: ");             // Output separator
Serial.print(totalMilliLitres);
Serial.println("mL");                */
if ( tempTotal != totalMilliLitres ) {
tempTotal = totalMilliLitres;
      //        displayVolumeOfWater(totalMilliLitres );
    }
    // Reset the pulse counter so we can start incrementing again
pulseCount = 0;
    // Enable the interrupt again now that we've finished sending output
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
  }
  //=========================================================================================================================
}
voidpulseCounter()
{
  // Increment the pulse counter
pulseCount++;
}
//-------------------------------------------------------------------------
void temperature()
{
sensors.requestTemperatures();
Celcius = sensors.getTempCByIndex(0);
  Fahrenheit = sensors.toFahrenheit(Celcius);
Serial.print(" C  ");
Serial.print(Celcius);
  // Serial.print(" F  ");
  // Serial.println(Fahrenheit);
delay(1000);
}
//------------------------------------------------------------
void turbidity()
{
intsensorValue = analogRead(A0);
voltage = sensorValue * (5.0 / 1024.0);
  // Serial.println ("Sensor Output (V):");
Serial.println (voltage);
  // Serial.println();
delay(1000);
}
//------------------------------------------------------------
voidgsm()
{
myserial.println("AT+HTTPINIT");
delay(1000);
ShowSerialData();
myserial.println("AT+HTTPPARA=\"CID\",1");
delay(1000);
ShowSerialData();
StaticJsonDocument<200>JsonDocument;
JsonObject& object = JsonDocument.createObject();
object.set("TE", Celcius);
object.set("TU", voltage);
object.set("WF", frac);
delay(1000);
object.printTo(Serial);
Serial.println(" ");
  String sendtoserver;
object.prettyPrintTo(sendtoserver);
delay(1000);
  //myserial.println("AT+HTTPPARA=\"URL\",\"https://api.thingspeak.com/update?api_key=\""); //Server address
myserial.println("AT+HTTPPARA=\"URL\",\"https://api.thingspeak.com/update?api_key=\""); //Server address
delay(1000);
ShowSerialData();
myserial.println("AT+HTTPPARA=\"CONTENT\",\"application/json\"");
delay(1000);
ShowSerialData();
myserial.println("AT+HTTPDATA=" + String(sendtoserver.length()) + ",100000");
Serial.println(sendtoserver);
delay(1000);
ShowSerialData();
myserial.println(sendtoserver);
delay(2000);
ShowSerialData;
myserial.println("AT+HTTPACTION=1");
delay(1000);
ShowSerialData();
myserial.println("AT+HTTPREAD");
delay(1000);
ShowSerialData();
myserial.println("AT+HTTPTERM");
delay(1000);
ShowSerialData;
}
voidShowSerialData()
{
while (myserial.available() != 0)
Serial.write(myserial.read());
delay(1000);
}