// TD-ARDUINO // gestion du temps #include #include #include #include #include WiFiUDP udp; WiFiUDP Udp; RTCZero rtc; #define MAGIC_NUMBER 0x7423 // arbitrary number to double check the saved SSID #define MaxNet 30 // max amount of network to be saved const char* home_ssid = SECRET_SSID; // your network SSID (name) const char* password = SECRET_PSWD; // your network password int PosToBeSaved = 0; // Variable used to navigate the array of networks int daily_amount_of_food = 12; // The amount of food per day needed to survive bool atHome = false; // Struct of variable to be saved in flash memory typedef struct { int magic; boolean valid[MaxNet]; char SSIDs[MaxNet][100]; int alive_days; int last_time_feeded; } Networks; FlashStorage(my_flash_store, Networks); Networks values; void setup() { Serial.begin(115200); delay(2000); rtc.begin(); // enable real time clock functionalities values = my_flash_store.read(); // Read values from flash memory if (values.magic == MAGIC_NUMBER) { // If token is correct print saved networks Serial.println("saved data:"); Serial.println(""); for (int a = 0; a < MaxNet; a++) { if (values.valid[a]) { Serial.println(values.SSIDs[a]); } else { PosToBeSaved = a; } } } } void loop() { if(!atHome) check_home(); // Temporarly save the number of networks int networks_already_saved = PosToBeSaved; getNetwork(); if (PosToBeSaved >= daily_amount_of_food) { Serial.println("Enough food for today"); } } void check_home() { int numSsid = WiFi.scanNetworks(); if (numSsid != -1) { for (int thisNet = 0; thisNet < numSsid; thisNet++) { delay(100); if (strncmp(WiFi.SSID(thisNet), home_ssid, 100) == 0) { Serial.println("Yay, I'm home \n"); atHome = true; connect_WiFi(); } } } } void connect_WiFi() { if (WiFi.status() != WL_CONNECTED) { while (WiFi.begin(home_ssid, password) != WL_CONNECTED) { delay(500); } Serial.println("WiFi connected \n"); GetCurrentTime(); printTime(); } } // Feed the Nerd with networks's SSID void getNetwork() { // scan for nearby networks: Serial.println("*Scan Networks*"); int numSsid = WiFi.scanNetworks(); delay(1000); if (numSsid == -1) { Serial.println("There are no WiFi networks here.."); } else { Serial.print("number of available networks: "); Serial.println(numSsid); // print the network number and name for each network found: for (int thisNet = 0; thisNet < numSsid; thisNet++) { Serial.print("SSID: "); Serial.println(WiFi.SSID(thisNet)); delay(500); char* net = WiFi.SSID(thisNet); bool canBeSaved = true; // check if the network has already been saved for (int a = 0; a < PosToBeSaved ; a++) { if (values.valid[a]) { if (strncmp(net, values.SSIDs[a], 100) == 0 || strnlen(net, 100) == 0) { Serial.println("Not saved"); canBeSaved = false; } } } // Store ssid name if (canBeSaved && PosToBeSaved < MaxNet) { if (strlen(net) + 1 < 100 && strlen(net) > 0) { // check if the SSID name fits 100 bytes memset(values.SSIDs[PosToBeSaved], 0, sizeof(values.SSIDs[PosToBeSaved])); // set all characters to zero memcpy(values.SSIDs[PosToBeSaved], net, strlen(net) + 1); // copy "net" to values.SSDs[thisNet] values.valid[PosToBeSaved] = true; values.last_time_feeded = rtc.getEpoch(); values.magic = MAGIC_NUMBER; my_flash_store.write(values); Serial.println(String(values.SSIDs[PosToBeSaved]) + " saved in position " + String(PosToBeSaved)); PosToBeSaved ++; } else { Serial.println(" network skipped"); } } } } } /************************************************* Start an UDP connection to get the time in unix, then set the real time clock (rtc) ************************************************/ unsigned int localPort = 2390; // local port to listen for UDP packets IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets const int GMT = 1 * 60 * 60; //change this to adapt it to your time zone hours*minutes*seconds unsigned long epoch; void GetCurrentTime() { int numberOfTries = 0, maxTries = 6; do { epoch = readLinuxEpochUsingNTP(); numberOfTries++; } while ((epoch == 0) || (numberOfTries > maxTries)); if (numberOfTries > maxTries) { Serial.print("NTP unreachable!!"); while (1); } else { Serial.print("Epoch received: "); Serial.println(epoch); rtc.setEpoch(epoch + GMT); Serial.println(); } } unsigned long readLinuxEpochUsingNTP() { Udp.begin(localPort); sendNTPpacket(timeServer); // send an NTP packet to a time server // wait to see if a reply is available delay(1000); if ( Udp.parsePacket() ) { Serial.println("NTP time received"); // We've received a packet, read the data from it Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer //the timestamp starts at byte 40 of the received packet and is four bytes, // or two words, long. First, esxtract the two words: unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); // combine the four bytes (two words) into a long integer // this is NTP time (seconds since Jan 1 1900): unsigned long secsSince1900 = highWord << 16 | lowWord; // now convert NTP time into everyday time: // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: const unsigned long seventyYears = 2208988800UL; // subtract seventy years: Udp.stop(); return (secsSince1900 - seventyYears); } else { Udp.stop(); return 0; } } // send an NTP request to the time server at the given address unsigned long 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(); } void printTime() { // Print date... Serial.print(rtc.getDay()); Serial.print(" / "); Serial.print(rtc.getMonth()); Serial.print(" / "); Serial.print(rtc.getYear()); Serial.print("\t"); // ...and time print2digits(rtc.getHours()); Serial.print(": "); print2digits(rtc.getMinutes()); Serial.print(": "); print2digits(rtc.getSeconds()); Serial.println(""); } void print2digits(int number) { if (number < 10) { Serial.print("0"); } Serial.print(number); }