#include "NoiseSensor.h" #include // For WiFi101 #include #include #include // ---> Fill in your WiFi name (SSID) and password here. <--- #define SECRET_SSID "CHANGEME" #define SECRET_PASSWORD "CHANGEME" // Keep these values like this unless you know what you're doing. const char server[] = "api.opensensemap.org"; const uint8_t tick_count = 60; const bool verbose = 1; // ---> Fill this in yourself. <--- // SenseBox IDs from the web interface in order 0, 1, 2, 3, 4. Master is ID 0! const char *sensebox_ids[] = {"CHANGEME", "", "CHANGEME", "CHANGEME", ""}; // Sensor IDs from the web interface in the same order as above. const char *sensor_ids[] = {"CHANGEME", "", "CHANGEME", "CHANGEME", ""}; // ================= WiFiClient client; uint32_t last_reading; WiFiUDP udp; static const char ntpServerName[] = "de.pool.ntp.org"; const int timeZone = 0; // Central European Time void setup() { sleep(2000); Serial.begin(115200); Serial.println("\nStarting wifi connection..."); // Retry WiFi connection until it succeeds. do { WiFi.begin(SECRET_SSID, SECRET_PASSWORD); uint32_t wifi_start_time = millis(); while (WiFi.status() != WL_CONNECTED) { senseBoxIO.statusRed(); delay(500); Serial.print("."); senseBoxIO.statusGreen(); if (millis() - wifi_start_time >= 5000) { Serial.println("Couldn't connect to Wifi. Try again."); WiFi.end(); break; } } } while (WiFi.status() != WL_CONNECTED); Serial.print("Connected to AP "); Serial.println(SECRET_SSID); udp.begin(8888); setSyncProvider(getNtpTime); setSyncInterval(300); // Let the sensors know we're ready and start measuring. if (!NoiseSensor.begin(tick_count)) { Serial.println("Something didn't work. Please restart the system."); while (1) { senseBoxIO.statusRed(); delay(100); senseBoxIO.statusNone(); delay(100); } } NoiseSensor.setIds(sensebox_ids, sensor_ids); sleep(1000); } void loop() { // Shows the openSenseMap's response. if (!verbose) { while (client.available()) { char c = client.read(); Serial.write(c); } } // This check is clumsy but will be replaced by a proper timer interrupt in the future. if (NoiseSensor.beaconReady()) { senseBoxIO.statusRed(); NoiseSensor.sendSyncBeacon(); senseBoxIO.statusGreen(); } // This check is clumsy but will be replaced by a proper timer interrupt in the future. if (millis() - last_reading >= 2000 && NoiseSensor.requestReady()) { senseBoxIO.statusRed(); Serial.println(); NoiseSensor.read(); // ---> Choose which sensor's data you want to upload by calling upload(device_id). upload(0, server); upload(2, server); upload(3, server); senseBoxIO.statusGreen(); // Record the last upload time to make sure we don't read and upload multiple times per second. last_reading = millis(); } } void upload(uint8_t device_id, const char* server) { Serial.println("Starting upload"); if (client.connected()) { client.stop(); sleep(500); } // If there's a successful connection: if (client.connectSSL(server, 443)) { String uploadbuf; String json = NoiseSensor.buildSenseBoxJSON(device_id); uint16_t content_length = json.length(); uploadbuf = NoiseSensor.buildHTTPHeader(device_id, server, content_length); client.println(uploadbuf); if (verbose) { Serial.println(uploadbuf); } client.println(); if (verbose) { Serial.println(); } // For some reason that nobody knows, client.print has an arbitrary input string limit. // Therefore, we need to split it at some arbitrary length and provide chunks. for (uint16_t idx = 0; idx < json.length(); idx += 1000) { client.print(json.substring(idx, idx + 1000)); if (verbose) { Serial.print(json.substring(idx, idx + 1000)); } } client.println(); if (verbose) { Serial.println(); } Serial.println("done!"); } else { // If we couldn't make a connection: Serial.println("connection failed. Restart System."); sleep(1000); } Serial.println("Upload done"); } void sleep(unsigned long ms) { // ms: duration unsigned long start = millis(); // start: timestamp for (;;) { unsigned long now = millis(); // now: timestamp unsigned long elapsed = now - start; // elapsed: duration if (elapsed >= ms) // comparing durations: OK return; } } 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() { IPAddress ntpServerIP;// = IPAddress(176, 9 , 42, 91); // NTP server's ip address while (udp.parsePacket() > 0) ; // discard any previously received packets WiFi.hostByName(ntpServerName, ntpServerIP); if (verbose) { Serial.println("Transmit NTP Request"); Serial.print(ntpServerName); Serial.print(": "); Serial.println(ntpServerIP); } sendNTPpacket(ntpServerIP); uint32_t beginWait = millis(); while (millis() - beginWait < 1500) { int size = udp.parsePacket(); if (size >= NTP_PACKET_SIZE) { if (verbose) { 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(); }