I've come back here as it seems logical to continue this discussion rather than starting a new thread as I think my current problem is related.
As you can see below I got everything to work as I wanted with my Ethernet Shield and then with my Ethernet Arduino.
Now I'm trying to apply the same principles to a much simpler project: a WiFi smoke detector and thermometer.
Where I am blocking is setting the time for the Arduino. It appears as though my original approach, which worked via Ethernet and Ethernet UDP, isn't going to work with WiFi. I am hoping that someone here is going to tell me that the following thread is dated and this (somehow) works now:
Before anyone asks, and in case it's just a matter of programming, here is an example of the code I am working on:
/*
WiFi Time Server Test
*/
// Libraries
#include <SPI.h>
#include <WiFi.h>
#include <EthernetUdp.h>
#include <Time.h>
// NTP time stamp from first 48 bytes of the message
const int iNTP_PACKET_SIZE = 48;
// Buffer to hold incoming / outgoing packets
byte byPacketBuffer[iNTP_PACKET_SIZE];
// Previous hour and minute counters
byte byPrevHr = 0;
byte byPrevMin = 0;
// UDP instance
EthernetUDP Udp;
////////////////////////////////////////////////////////
//
// GetNTPTime
//
// Get the time via NTP, adjust for Time Zone and return for synchronisation
//
unsigned long GetNTPTime() {
// Time Zone (Difference from GMT in seconds)
const long lTZ = 3600;
// Time Server fixed IP address (nist1-ny.ustiming.org)
IPAddress ipTimeServer(64, 90, 182, 55);
// Set an NTP packet to the NTP time server
sendNTPpacket(ipTimeServer);
delay(1000);
if (Udp.parsePacket()) {
// We've received a packet, read the data from it
Udp.read(byPacketBuffer, iNTP_PACKET_SIZE);
//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:
unsigned long highWord = word(byPacketBuffer[40], byPacketBuffer[41]);
unsigned long lowWord = word(byPacketBuffer[42], byPacketBuffer[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:
unsigned long epoch = secsSince1900 - seventyYears;
// Adjust for local time zone
epoch += lTZ;
// Return local time
return(epoch);
}
}
////////////////////////////////////////////////////////
//
// PrintTime
//
// Serial Print time (DD/MM/YYYY - HH:MM:SS)
//
void PrintTime() {
char cTime[22];
sprintf(cTime, "%02u/%02u/%4u - %02u:%02u:%02u", day(), month(), year(), hour(), minute(), second());
Serial.println(cTime);
}
////////////////////////////////////////////////////////
//
// sendNTPpacket
//
// Send an NTP request to the NTP time server at the IP address
//
//
unsigned long sendNTPpacket(IPAddress& address) {
// set all bytes in the buffer to 0
memset(byPacketBuffer, 0, iNTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
byPacketBuffer[0] = 0b11100011; // LI, Version, Mode
byPacketBuffer[1] = 0; // Stratum, or type of clock
byPacketBuffer[2] = 6; // Polling Interval
byPacketBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
byPacketBuffer[12] = 49;
byPacketBuffer[13] = 0x4E;
byPacketBuffer[14] = 49;
byPacketBuffer[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(byPacketBuffer, iNTP_PACKET_SIZE);
Udp.endPacket();
}
//////////////////////////////////////////////////////
//
// WiFiConnect
//
// Establish WiFi connection to network
//
byte WiFiConnect() {
byte byResult = false;
// WiFi Network & Password
char SSID[] = "SSIDHERE";
char WiFiPass[] = "PASSWORDHERE";
int iWiFiStatus = WL_IDLE_STATUS; // WiFi radio's status
byte byAttempt = 0; // Attempt counter
while (iWiFiStatus != WL_CONNECTED) {
if (byAttempt < 10) {
byAttempt++;
// Wait 3 seconds before trying
delay(3000);
Serial.print(F("Attempting to connect to WPA network: "));
Serial.print(SSID);
Serial.print(F("\nAttempt: "));
Serial.println(byAttempt);
// Attempt to connect to WPA network:
iWiFiStatus = WiFi.begin(SSID, WiFiPass);
if (iWiFiStatus != WL_CONNECTED) {
byResult = false;
Serial.println(F("Couldn't establish WiFi connection"));
}
// if connected :
else {
byResult = true;
Serial.println(F("WiFi connection established\n"));
}
}
else {
byResult = 2; // Too many attempts
}
}
return(byResult);
}
//////////////////////////////////////////////////////
//
// SETUP
//
void setup() {
// Setup serial monitor
Serial.begin(9600);
// Wait 3 seconds
delay(3000);
Serial.println(F("WiFi Time Test"));
Serial.println(F("Arduino - Derek Erb\n"));
// Connect to WiFi
WiFiConnect();
// Setup time
Serial.println(F("Waiting for sync...\n"));
setSyncProvider(GetNTPTime);
while(timeStatus() == timeNotSet); // Wait until time set by sync provider
// Display time
PrintTime();
// Save current hour and minute as previous hour and minute
byPrevHr = hour();
byPrevMin = minute();
}
//////////////////////////////////////////////////////
//
// LOOP
//
void loop() {
// Display new time at the start of every minute
if (byPrevMin != minute()) {
// Store current minute as new previous minute
byPrevMin = minute();
// Serial print time
PrintTime();
}
}
If not... then how does one go about setting the time (autonomously) in an Arduino with a WiFi shield???
Thanks!