/* * Udp NTP Client + Print time once a minute. */ #include #include #include #include //#include #include #include #include "arduino_secrets.h" int status = WL_IDLE_STATUS; //please enter your sensitive data in arduino_secrets.h char ssid[] = SECRET_SSID; // your network SSID (name) char pass[] = SECRET_PASS; // your network password (use for WPA) int keyIndex = 0; // your network key Index number (needed only for WEP) unsigned int localPort = 2390; // local port to listen for UDP packets IPAddress timeServer(129, 6, 15, 28); // time-a.nist.gov NTP server const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes byte packetBufferOut[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets byte packetBufferIn[NTP_PACKET_SIZE]; // buffer to hold incoming packets WiFiUDP Udp; // A UDP instance to let us transfer packets over UDP Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield(); String timeString; String dateString; int LCD_TIMEOUT = 2; int count = LCD_TIMEOUT; File myFile; boolean fileIO = false; int blink_led = 2; bool blink_state = false; void setup() { // Open serial communications Serial.begin(9600); Serial.print("Initializing SD card... "); // Check to see if an SD card is present if (!SD.begin(4)) { Serial.println("failed!"); fileIO = false; } else { // Is so, delete the timestamp file. Serial.println("successful!"); fileIO = true; if (SD.exists("timestmp.txt")) { SD.remove("timestmp.txt"); } } // check for the presence of the WIFI shield: if (WiFi.status() == WL_NO_SHIELD) { Serial.println("WiFi shield not present"); // don't continue: while (true); } // attempt to connect to WiFi network: while (status != WL_CONNECTED) { Serial.print("Attempting to connect to SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network. status = WiFi.begin(ssid, pass); delay(2000); // wait 2 seconds for connection or retry } Serial.println("Connected to wifi"); printWiFiStatus(); Serial.println("\nStarting UDP..."); Udp.begin(localPort); // set all bytes in the buffer to 0 memset(packetBufferOut, 0, NTP_PACKET_SIZE); // Initialize values needed to form NTP request // (see URL above for details on the packets) packetBufferOut[0] = 0b11100011; // LI, Version, Mode packetBufferOut[1] = 0; // Stratum, or type of clock packetBufferOut[2] = 6; // Polling Interval packetBufferOut[3] = 0xEC; // Peer Clock Precision // 8 bytes of zero for Root Delay & Root Dispersion packetBufferOut[12] = 49; packetBufferOut[13] = 0x4E; packetBufferOut[14] = 49; packetBufferOut[15] = 52; Serial.println("And the time in Texas is..."); // Initialize the LCD shield's display lcd.begin(16, 2); lcd.setCursor(0, 0); lcd.print("Texas time!"); // lcd.setBacklight(0x1); pinMode(blink_led, OUTPUT); } void loop() { // Check backlight if (count > 0){ count -= 1; } else { lcd.setBacklight(0x0); } // send an NTP packet to a time server, // wait a moment // and then see if a reply is available sendNTPpacket(timeServer); delay(1000); String dateTimeString = receiveNTPpacket(); if (dateTimeString != "") { // Print time and date to the LCD lcd.setCursor(0, 0); lcd.print(dateString); lcd.setCursor(0, 1); lcd.print(timeString); // Ditto, the serial port Serial.println(dateTimeString); // Once more for the file, if available... if (fileIO) { myFile = SD.open("timestmp.txt", FILE_WRITE); myFile.println(dateTimeString); myFile.close(); } } // Instead of a fixed delay, poll the buttons int i = 0; while(i < 59){ uint8_t buttons = lcd.readButtons(); if (buttons){ if(count==0){ count = LCD_TIMEOUT; lcd.setBacklight(0x1); } else { count = 0; lcd.setBacklight(0x0); } } if (!blink_state){ digitalWrite(blink_led, HIGH); blink_state = true; } else { digitalWrite(blink_led, LOW); blink_state = false; } i += 1; delay(1000); } } /* * Subroutines */ // The packet requesting a timestamp has already been initialized. // All that is left is to send it... unsigned long sendNTPpacket(IPAddress& address) { Udp.beginPacket(address, 123); //NTP requests are to port 123 Udp.write(packetBufferOut, NTP_PACKET_SIZE); Udp.endPacket(); } String receiveNTPpacket(){ if ( Udp.parsePacket() ) { // We've received a packet, read the data from it Udp.read(packetBufferIn, 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, extract the two words and combine the four bytes // into an unsigned long integer. unsigned long highWord = word(packetBufferIn[40], packetBufferIn[41]); unsigned long lowWord = word(packetBufferIn[42], packetBufferIn[43]); unsigned long secsSince1900 = highWord << 16 | lowWord; // Serial.print("Seconds since Jan 1 1900 = " ); // Serial.println(secsSince1900); // Subtract midnight 01/01/2018 (CST) in seconds NTP time (3723775200)so we can // calculate the number of days since new years, which allows us to easily // derive the date. The extra 3600 seconds (1 hr) is to compensate for DST. unsigned long epoch = secsSince1900 - 3723775200 + 3600; // calculate the number of days since new years... int days = (epoch/86400)+1; int years = 2018; // Turn days into the date that gets used while (true){ dateString = showDate(days, years); if (dateString != ""){ break; } else { days -= 365; // if 2019 or beyond, decrement the days by 1 year years += 1; // increment the year number and try again } } // fetch the timeString timeString = showTime(epoch); // merge strings return dateString + timeString; } else { Serial.println("Timeout"); return ""; } } void printWiFiStatus() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print your WiFi shield's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.print(rssi); Serial.println(" dBm"); } String showTime(unsigned long epoch){ // calculate the hour (86400 equals secs per day) String strTemp; int temp = (epoch % 86400L) / 3600; if (temp < 10){ strTemp = "0"; } strTemp = strTemp + temp + ":"; // calculate the minute (3600 equals secs per minute) temp = ((epoch % 3600) / 60); if (temp < 10){ strTemp = strTemp + "0"; } strTemp = strTemp + temp + ":"; // calculate the seconds temp = (epoch % 60); if ( temp < 10 ) { strTemp = strTemp + "0"; } strTemp = strTemp + temp; return strTemp; } String showDate(int days, int years){ bool leapyear = false; if (years % 4 == 0){ leapyear = true; } if (days <= 31){ // January if (days < 10) { return "0" + String(days) + ("/01/")+ years + (" "); } else { return String(days) + ("/01/")+ years + (" "); } } if (days <= 59){ // February if (days-31 < 10) { return "0" + String(days-31) + ("/02/")+ years + (" "); } else { return String(days-31) + ("/02/")+ years + (" "); } } if ((days == 60) && leapyear){ // February 29th (Leap Year) return String(days-31) + ("/02/")+ years + (" "); } // If we are in a leap year and after Feb 29th, decrement days // to corrrect the day count for the extra day. if (leapyear){ days -= 1; } if (days <= 90){ // March if (days-59 < 10) { return "0" + String(days-59) + ("/03/")+ years + (" "); } else { return String(days-59) + ("/03/")+ years + (" "); } } if (days <= 120){ // April if (days-90 < 10){ return "0" + String(days-90) + ("/04/")+ years + (" "); } else { return String(days-90) + ("/04/")+ years + (" "); } } if (days <= 151){ // May if (days-120 < 10) { return "0" + String(days-120) + ("/05/")+ years + (" "); } else { return String(days-120) + ("/05/")+ years + (" "); } } if (days <= 181){ // June if (days-151 < 10) { return "0" + String(days-151) + ("/06/")+ years + (" "); } else { return String(days-151) + ("/06/")+ years + (" "); } } if (days <= 212){ // July if (days-181 < 10) { return "0" + String(days-181) + ("/07/")+ years + (" "); } else { return String(days-181) + ("/07/")+ years + (" "); } } if (days <= 243){ // August if (days-212) { return "0" + String(days-212) + ("/08/")+ years + (" "); } else { return String(days-212) + ("/08/")+ years + (" "); } } if (days <= 273){ // September if (days-243) { return "0" + String(days-243) + ("/09/")+ years + (" "); } else { return String(days-243) + ("/09/")+ years + (" "); } } if (days <= 304){ // October if (days-273) { return "0" + String(days-273) + ("/10/")+ years + (" "); } else { return String(days-273) + ("/10/")+ years + (" "); } } if (days <= 334){ // November if (days-304) { return "0" + String(days-304) + ("/11/")+ years + (" "); } else { return String(days-304) + ("/11/")+ years + (" "); } } if (days <= 365){ // December if (days-334) { return "0" + String(days-334) + ("/12/")+ years + (" "); } else { return String(days-334) + ("/12/")+ years + (" "); } } else { return ""; } }