// Gas meter monitoring system using ESP-01, written by Heiner Ollendorf (arduolli), public domain #include #include #include #include #define REED_PIN 2 #define loopmaxcount 10 const char* ssid = "yourSSID"; const char* password = "yourPassword"; const char* server = "api.thingspeak.com"; String apiKey = "yourAPIKey"; const char* host = "IP.Adress.of.local.server"; // i.e. 192.xxx.xxx.xxx // NTP Servers: IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov // IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov // IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov const int timeZone = 1; // Central European Time WiFiUDP Udp; const int localPort = 8888; // local port to listen for UDP packets // Use WiFiClient class to create TCP connections WiFiClient client; const int Port = 9999; time_t getNtpTime(); void sendNTPpacket(IPAddress &address); unsigned long GasCounter = 0; // counter; 1 equals 0,01 m3 unsigned long timestamp[loopmaxcount]; // time stamp array for sending batches of #[loopmaxcount] to server // Instantiate a Bounce object Bounce debouncer = Bounce(); void setup() { Serial.begin(115200); delay(10); // prepare GPIO2 pinMode(REED_PIN, INPUT_PULLUP); // After setting up the reed-switch, setup the Bounce instance: debouncer.attach(REED_PIN); debouncer.interval(50); // interval in ms // update time Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); Serial.println("Starting UDP"); Udp.begin(localPort); Serial.print("Local port: "); Serial.println(Udp.localPort()); Serial.println("waiting for sync"); setSyncProvider(getNtpTime); WiFi.disconnect(); Serial.println(WiFi.status()); } void loop() { for (int x = 0; x < loopmaxcount; x++) { // accumulate batch of timestamps // Update the Bounce instance : debouncer.update(); // compare the reedState to its previous state if (debouncer.fell()) { ++GasCounter; Serial.println(GasCounter); timestamp[x] = now(); } else { x--; } yield(); } delay(50); // connect to WiFi Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); if (!client.connect(host, Port)) { Serial.println("connection failed"); return; } // This will send the data to the local server String s = ""; for (int x = 0; x < loopmaxcount; x++) { // send batch of timestamps server s += String(timestamp[x]) + "," + String(day(timestamp[x])) + "." + String(month(timestamp[x])) + "." + String(year(timestamp[x])) + "," + String(hour(timestamp[x])) + ":" + String(minute(timestamp[x])) + ":" + String(second(timestamp[x])) + "\n"; } client.print(s); delay(10); client.stop(); // start upload to thingspeak if (client.connect(server, 80)) { // "184.106.153.149" or api.thingspeak.com // String postStr = apiKey; String postStr = "&field1="; postStr += String(float(GasCounter) / 100); postStr += "&field2="; postStr += String(1); postStr += "\r\n\r\n"; client.print("POST /update HTTP/1.1\n"); client.print("Host: api.thingspeak.com\n"); client.print("Connection: close\n"); client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n"); client.print("Content-Type: application/x-www-form-urlencoded\n"); client.print("Content-Length: "); client.print(postStr.length()); client.print("\n\n"); client.print(postStr); Serial.println("% send to Thingspeak"); } client.stop(); // stop upload to thingspeak WiFi.disconnect(); Serial.println(WiFi.status()); } /*-------- NTP code ----------*/ const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets time_t getNtpTime() { while (Udp.parsePacket() > 0) ; // discard any previously received packets Serial.println("Transmit NTP Request"); sendNTPpacket(timeServer); uint32_t beginWait = millis(); while (millis() - beginWait < 1500) { int size = Udp.parsePacket(); if (size >= NTP_PACKET_SIZE) { Serial.println("Receive NTP Response"); Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer unsigned long secsSince1900; // convert four bytes starting at location 40 to a long integer secsSince1900 = (unsigned long)packetBuffer[40] << 24; secsSince1900 |= (unsigned long)packetBuffer[41] << 16; secsSince1900 |= (unsigned long)packetBuffer[42] << 8; secsSince1900 |= (unsigned long)packetBuffer[43]; return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR; } } Serial.println("No NTP Response :-("); return 0; // return 0 if unable to get the time } // send an NTP request to the time server at the given address void sendNTPpacket(IPAddress &address) { // set all bytes in the buffer to 0 memset(packetBuffer, 0, NTP_PACKET_SIZE); // Initialize values needed to form NTP request // (see URL above for details on the packets) packetBuffer[0] = 0b11100011; // LI, Version, Mode packetBuffer[1] = 0; // Stratum, or type of clock packetBuffer[2] = 6; // Polling Interval packetBuffer[3] = 0xEC; // Peer Clock Precision // 8 bytes of zero for Root Delay & Root Dispersion packetBuffer[12] = 49; packetBuffer[13] = 0x4E; packetBuffer[14] = 49; packetBuffer[15] = 52; // all NTP fields have been given values, now // you can send a packet requesting a timestamp: Udp.beginPacket(address, 123); //NTP requests are to port 123 Udp.write(packetBuffer, NTP_PACKET_SIZE); Udp.endPacket(); }