/*************************************************** This is an example for the Adafruit CC3000 Wifi Breakout & Shield Designed specifically to work with the Adafruit WiFi products: ----> https://www.adafruit.com/products/1469 Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried, Kevin Townsend and Phil Burgess for Adafruit Industries. BSD license, all text above must be included in any redistribution ****************************************************/ /* This example queries an NTP time server to get the current "UNIX time" (seconds since 1/1/1970, UTC (GMT)), then uses the Arduino's internal timer to keep relative time. The clock is re-synchronized roughly once per day. This minimizes NTP server misuse/abuse. The RTClib library (a separate download, and not used here) contains functions to convert UNIX time to other formats if needed. */ #include #include #include // These are the interrupt and control pins #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! // These can be any two pins #define ADAFRUIT_CC3000_VBAT 5 #define ADAFRUIT_CC3000_CS 10 // Use hardware SPI for the remaining pins // On an UNO, SCK = 13, MISO = 12, and MOSI = 11 Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIVIDER); // you can change this clock speed but DI #define WLAN_SSID "myNetwork" // cannot be longer than 32 characters! #define WLAN_PASS "myPassword" // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 #define WLAN_SECURITY WLAN_SEC_WPA2 Adafruit_CC3000_Client client; const unsigned long connectTimeout = 15L * 1000L, // Max time to wait for server connection responseTimeout = 15L * 1000L; // Max time to wait for data from server int countdown = 0; // loop() iterations until next time server query unsigned long lastPolledTime = 0L, // Last value retrieved from time server sketchTime = 0L; // CPU milliseconds since last server query void setup(void) { Serial.begin(115200); Serial.println(F("Hello, CC3000!\n")); displayDriverMode(); Serial.println(F("\nInitialising the CC3000 ...")); if (!cc3000.begin()) { Serial.println(F("Unable to initialise the CC3000! Check your wiring?")); for(;;); } uint16_t firmware = checkFirmwareVersion(); if (firmware < 0x113) { Serial.println(F("Wrong firmware version!")); for(;;); } displayMACAddress(); Serial.println(F("\nDeleting old connection profiles")); if (!cc3000.deleteProfiles()) { Serial.println(F("Failed!")); while(1); } /* Attempt to connect to an access point */ char *ssid = WLAN_SSID; /* Max 32 chars */ Serial.print(F("\nAttempting to connect to ")); Serial.println(ssid); /* NOTE: Secure connections are not available in 'Tiny' mode! */ if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) { Serial.println(F("Failed!")); while(1); } Serial.println(F("Connected!")); /* Wait for DHCP to complete */ Serial.println(F("Request DHCP")); while (!cc3000.checkDHCP()) { delay(100); // ToDo: Insert a DHCP timeout! } /* Display the IP address DNS, Gateway, etc. */ while (!displayConnectionDetails()) { delay(1000); } } // To reduce load on NTP servers, time is polled once per roughly 24 hour period. // Otherwise use millis() to estimate time since last query. Plenty accurate. void loop(void) { if(countdown == 0) { // Time's up? unsigned long t = getTime(); // Query time server if(t) { // Success? lastPolledTime = t; // Save time sketchTime = millis(); // Save sketch time of last valid time query countdown = 24*60*4-1; // Reset counter: 24 hours * 15-second intervals } } else { countdown--; // Don't poll; use math to figure current time } unsigned long currentTime = lastPolledTime + (millis() - sketchTime) / 1000; Serial.print(F("Current UNIX time: ")); Serial.print(currentTime); Serial.println(F(" (seconds since 1/1/1970 UTC)")); delay(15000L); // Pause 15 seconds } /**************************************************************************/ /*! @brief Displays the driver mode (tiny of normal), and the buffer size if tiny mode is not being used @note The buffer size and driver mode are defined in cc3000_common.h */ /**************************************************************************/ void displayDriverMode(void) { #ifdef CC3000_TINY_DRIVER Serial.println(F("CC3000 is configure in 'Tiny' mode")); #else Serial.print(F("RX Buffer : ")); Serial.print(CC3000_RX_BUFFER_SIZE); Serial.println(F(" bytes")); Serial.print(F("TX Buffer : ")); Serial.print(CC3000_TX_BUFFER_SIZE); Serial.println(F(" bytes")); #endif } /**************************************************************************/ /*! @brief Tries to read the CC3000's internal firmware patch ID */ /**************************************************************************/ uint16_t checkFirmwareVersion(void) { uint8_t major, minor; uint16_t version; #ifndef CC3000_TINY_DRIVER if(!cc3000.getFirmwareVersion(&major, &minor)) { Serial.println(F("Unable to retrieve the firmware version!\r\n")); version = 0; } else { Serial.print(F("Firmware V. : ")); Serial.print(major); Serial.print(F(".")); Serial.println(minor); version = major; version <<= 8; version |= minor; } #endif return version; } /**************************************************************************/ /*! @brief Tries to read the 6-byte MAC address of the CC3000 module */ /**************************************************************************/ void displayMACAddress(void) { uint8_t macAddress[6]; if(!cc3000.getMacAddress(macAddress)) { Serial.println(F("Unable to retrieve MAC Address!\r\n")); } else { Serial.print(F("MAC Address : ")); cc3000.printHex((byte*)&macAddress, 6); } } /**************************************************************************/ /*! @brief Tries to read the IP address and other connection details */ /**************************************************************************/ bool displayConnectionDetails(void) { uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv; if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)) { Serial.println(F("Unable to retrieve the IP Address!\r\n")); return false; } else { Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress); Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask); Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway); Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv); Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv); Serial.println(); return true; } } // Minimalist time server query; adapted from Adafruit Gutenbird sketch, // which in turn has roots in Arduino UdpNTPClient tutorial. unsigned long getTime(void) { uint8_t buf[48]; unsigned long ip, startTime, t = 0L; Serial.print(F("Locating time server...")); // Hostname to IP lookup; use NTP pool (rotates through servers) if(cc3000.getHostByName("pool.ntp.org", &ip)) { static const char PROGMEM timeReqA[] = { 227, 0, 6, 236 }, timeReqB[] = { 49, 78, 49, 52 }; Serial.println(F("\r\nAttempting connection...")); startTime = millis(); do { client = cc3000.connectUDP(ip, 123); } while((!client.connected()) && ((millis() - startTime) < connectTimeout)); if(client.connected()) { Serial.print(F("connected!\r\nIssuing request...")); // Assemble and issue request packet memset(buf, 0, sizeof(buf)); memcpy_P( buf , timeReqA, sizeof(timeReqA)); memcpy_P(&buf[12], timeReqB, sizeof(timeReqB)); client.write(buf, sizeof(buf)); Serial.print(F("\r\nAwaiting response...")); memset(buf, 0, sizeof(buf)); startTime = millis(); while((!client.available()) && ((millis() - startTime) < responseTimeout)); if(client.available()) { client.read(buf, sizeof(buf)); t = (((unsigned long)buf[40] << 24) | ((unsigned long)buf[41] << 16) | ((unsigned long)buf[42] << 8) | (unsigned long)buf[43]) - 2208988800UL; Serial.print(F("OK\r\n")); } client.close(); } } if(!t) Serial.println(F("error")); return t; }