So I take it you also got the shield to work now. That's good news!
Why do you think the files on github are different from the ones compiled into the ZIP? I think they are not. If you download the RAW version from the github page and compare then to the ones in the ZIP, you will find they are exactly the same. I just tested them both with FileMerge.
Anyone know how you would to the Update Shield step on Windows? I guess runas is supposed to be the equivalent of sudo, but it still needs an executable.
Hello there and I have to say i'm sooo happy this post was created and that UDP support is coming for the WiFi Shield but i'm not here only to thank timKnapen, I think I might need your help
Yes i need to sync my Arduino Uno to NTP servers so I can use the Time library, however I'm stuck with this test code that fails to do it's job. Do you guys see what is wrong ?
#include <SPI.h>
#include <WiFI.h>
#include <WiFiUdp.h>
#include <Time.h>
int status = WL_IDLE_STATUS;
char ssid[] = "SSID"; // your network SSID (name) Your network name here, case sensitive!
char pass[] = "pass"; // if your network doesn't use WPA or WEP, change the line below that says "status = WiFi.begin(ssid, pass);"
/* ******** NTP Server Settings ******** */
/* us.pool.ntp.org NTP server
(Set to your time server of choice) */
IPAddress timeServer(64, 90, 182, 55);
/* Set this to the offset (in seconds) to your local time
This example is GMT + 2 */
const long timeZoneOffset = 7200L;
/* Syncs to NTP server every 15 seconds for testing,
set to 1 hour or more to be reasonable */
unsigned int ntpSyncTime = 15;
/* ALTER THESE VARIABLES AT YOUR OWN RISK */
// local port to listen for UDP packets
unsigned int localPort = 8888;
// NTP time stamp is in the first 48 bytes of the message
const int NTP_PACKET_SIZE= 48;
// Buffer to hold incoming and outgoing packets
byte packetBuffer[NTP_PACKET_SIZE];
// A UDP instance to let us send and receive packets over UDP
WiFiUDP Udp;
// Keeps track of how long ago we updated the NTP server
unsigned long ntpLastUpdate = 0;
// Check last time clock displayed (Not in Production)
time_t prevDisplay = 0;
void setup() {
Serial.begin(9600);
// make a little light show on the WifiShield
pinMode(9, OUTPUT);
for(int i = 0; i < 50; i++){
digitalWrite(9, HIGH);
delay(i);
digitalWrite(9, LOW);
delay(i);
}
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue:
while(true);
}
Serial.println("Wifi Shield present");
// 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. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to wifi");
printWifiStatus();
Serial.println("\nStarting connection to server...");
//Try to get the date and time
int trys=0;
while(!getTimeAndDate() && trys<10) {
trys++;
}
}
// Do not alter this function, it is used by the system
int getTimeAndDate() {
int flag=0;
Udp.begin(localPort);
sendNTPpacket(timeServer);
delay(1000);
if (Udp.parsePacket()){
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
unsigned long highWord, lowWord, epoch;
highWord = word(packetBuffer[40], packetBuffer[41]);
lowWord = word(packetBuffer[42], packetBuffer[43]);
epoch = highWord << 16 | lowWord;
epoch = epoch - 2208988800 + timeZoneOffset;
flag=1;
setTime(epoch);
ntpLastUpdate = now();
}
return flag;
}
// Do not alter this function, it is used by the system
unsigned long sendNTPpacket(IPAddzress& address)
{
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011;
packetBuffer[1] = 0;
packetBuffer[2] = 6;
packetBuffer[3] = 0xEC;
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
Udp.beginPacket(address, 123);
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
}
// Clock display of the time and date (Basic)
void clockDisplay(){
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
}
// Utility function for clock display: prints preceding colon and leading 0
void printDigits(int digits){
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
// This is where all the magic happens...
void loop() {
// Update the time via NTP server as often as the time you set at the top
if(now()-ntpLastUpdate > ntpSyncTime) {
int trys=0;
while(!getTimeAndDate() && trys<10){
trys++;
}
if(trys<10){
Serial.println("ntp server update success");
}
else{
Serial.println("ntp server update failed");
}
}
// Display the time if it has changed by more than a second.
if( now() != prevDisplay){
prevDisplay = now();
clockDisplay();
}
}
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");
}
TimKnapen, I do not get any compilation errors ( lucky me ) but the program always prints "NTP server update failed" so I don't really know what's wrong ( the packets I'm sending, the way I'm sending them ...)
I don't understand. Your code doesn't compile for me. I'm using this Time library: Arduino Playground - HomePage
Are you using a different one? Is the code you posted really the one you use??
I get these errors:
sketch_apr15a.ino:93: warning: this decimal constant is unsigned only in ISO C90
sketch_apr15a:9: error: 'IPAddzress' was not declared in this scope
sketch_apr15a:9: error: 'address' was not declared in this scope
sketch_apr15a.ino: In function 'int getTimeAndDate()':
sketch_apr15a:85: error: 'sendNTPpacket' cannot be used as a function
sketch_apr15a.ino: At global scope:
sketch_apr15a:102: error: redefinition of 'long unsigned int sendNTPpacket'
sketch_apr15a:9: error: 'long unsigned int sendNTPpacket' previously defined here
sketch_apr15a:102: error: 'IPAddzress' was not declared in this scope
sketch_apr15a:102: error: 'address' was not declared in this scope
Hi Tim and thanks for your awesome work, I've just received my wifi shield today and I'm quite disappointed to find out that all the work done (based on UDP) it's not working
Thanks God I've found this thread.
Just a quick question: has the UDP packet some kind of size limit?
I've followed your instructions, but I'm still not receiving the data I'm expecting....
We live in a finite world, so I assume everything has its limits
The thing with UDP is that it doesn't guarantee packages being delivered in the right order or at all. It's just very fast. Here's some interesting stuff about it: networking - UDP vs TCP, how much faster is it? - Stack Overflow
Ok, I've setup a network for my test and now I have the IP address assigned.
Just to be clear: my setup is composed by an Arduino reading 4 sensor and sending their values via UDP packets to a Node.js server. Everything was working fine with my Ethernet shield of course
I had 3 global variables declared:
IPAddress receiverIP(192, 168, 2, 34); // IP of udp packets receiver
unsigned int receiverPort = 9100; // port to listen on my PC
EthernetUDP Udp;
In my setup I was initializing the EthernetUDP object:
Udp.begin(9100);
...and then I my loop I was reading my sensors and sending them like this:
byte valueInBytes[8] = {lowByte(firstSensorValue), highByte(firstSensorValue),
lowByte(secondSensorValue), highByte(secondSensorValue),
lowByte(thirdSensorValue), highByte(thirdSensorValue),
lowByte(forthSensorValue), highByte(forthSensorValue)
}; //convert it to byte array
Udp.beginPacket(receiverIP, receiverPort); //start udp packet
Udp.write(valueInBytes, 8); //write sensor data to udp packet
Udp.endPacket(); // end packet
Now, I'm a n00b and the setup it's getting quite complex for me, but since I switch to your library I don't know how to adapt my code to have everything working.
Any help would be appreciated
just strip your sketch from all the calls to ethernetUDP and replace it with the appropriate parts of WifiUDP calls in the example I posted above in this thread.
so
EthernetUDP Udp;
becomes
WiFiUDP Udp;
etc...
and if something doesn't work, post your complete code then we can take a look at it and quickly see any mistakes.
I would also suggest to always compile with verbose output. You can switch verbose output on in Arduino > Preferences
About my code: actually I don't have any error, it compiles and run without any issue, but the problem is that the server on the listening machine isn't receiving anything....
Is the initialization of your class correct? Is it right I'm initializing it like this:
Udp.begin(receiverPort);
...using receiverPort as argument?
Is the composition of the UDP message correct?
Thank you again
virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
so it's expecting you to pass the port the Arduino should listen on, not the one to send to. But since you are not listening on the Arduino and the local and remote port can be the same, this shouldn't be a problem.
The construction of your UDP message
Udp.beginPacket(receiverIP, receiverPort); //start udp packet
Udp.write(valueInBytes, 8); //write sensor data to udp packet
Udp.endPacket(); // end packet
looks right to me.
It's difficult to debug these kind of things from a distance. What I would do in such a case is try with the simplest setup that works and then change the code until it breaks. Step by step, compiling and testing with every change. At a certain point it will stop working.
So I would suggest you start with my example, start changing things and see how far you can get.
I would start by checking these:
do you really want delay(10000); // 10sec delay?
is the receiving computer really at IP 192.168.1.212 ? and is it listening at port 9100 ?
more really obvious mistakes that are easy to overlook
The first thing that looks strange is that I've tried to connect to different routers/networks, and my Arduino always Seruial.prints this networks info:
Attempting to connect to WPA SSID: phwifi
You're connected to the networkSSID: phwifi
BSSID: 0:0:0:0:0:0
signal strength (RSSI):0
Encryption Type:0
IP Address: 192.168.2.6
where the IP obviosly changes, but the other info are always zero.....
Just a wild guess: is it possible the receiving ip should be something like 192.168.2.something... instead of the 192.168.1.212 you were using? usually when you are on the same network, the range of IPs is limited so only the last byte is different.
I have no idea why you get this weird output like
signal strength (RSSI): 0
Encryption Type: 0
did you correctly upgrade the WifiShield firmware? Are you using the correct library?
The ip class has changed from the previously code because I'm trying different networks, sorry about the confusion
About the firmware upgrade, I'm pretty sure I did follow your instructions
I was just reading this interesting post and trying to understand if there are any differences:
I also read that page when I was still trying with the old buggy firmware.
You can ignore everything on that page except the part about updating ports. That's the only thing I didn't document in my post I think.