Pages: 1 [2] 3 4   Go Down
Author Topic: Arduino WiFi Shield UDP Support  (Read 15873 times)
0 Members and 1 Guest are viewing this topic.
Hong Kong
Offline Offline
Newbie
*
Karma: 1
Posts: 2
bits and bytes
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi

Would also love to see proper UDP support for this official WiFi shield.
I also have a Linksprite WiShield 2.0 (Asynclabs compatible), UDP works fine there, but the library is a complete mess and not fun to work with.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm also sitting with a project where this would be immensely useful. I hope someone pieces it together soon!
Logged

United Kingdom
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi All,

Answering my own questions here in the hope to help others that read this thread.

I noticed that there is a dev_udp branch over at https://github.com/arduino/wifishield which I can confirm works very well with UDP. It will require that you update the firmware on your wifi shield and replace the library ( this includes a new example WifiUdpSendReceiveString ) in your arduino ide installation but nothing overly difficult.

Hope this helps,
Logged

Regards,

jfrmilner

Antwerp, Belgium
Offline Offline
Jr. Member
**
Karma: 2
Posts: 64
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Jfrmilner,

I'm glad someone is able to get this to work.
I have been trying like mad to get this to work with the udp_dev branch but had no luck. I'm fairly experienced with UDP on OSX and iOS and win but for some reason I can't get the bloody arduino to play nice...

could you please document your steps our take a look at the issue I posted here: https://github.com/arduino/wifishield/issues/28

I have no idea where I'm going wrong :-(

best,
tim.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I would also like to see this working, could be veeeery useful.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

jfrmilner,

would you please give us some more details please, i'm really stuck on this
Logged

Antwerp, Belgium
Offline Offline
Jr. Member
**
Karma: 2
Posts: 64
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hello All, I have been in contact with mlafauci on Github, who seems to be in charge of fixing the WifiShield firmware and library. He posted an update to the firmware and library that works with UDP!!!
Because I struggled so much with this thing I'm going to post a complete write-up of every little step needed to get an UDP example working.

Here goes:


Getting the WifiShield to work with UDP.

My setup:
Mac OSX 10.8.3
Arduino UNO
Arduino 1.0.4
WifiShield R3 with HDG104 chip and 32UC3

These are the step:

1. Download and put everything in it's right place.

* Download Arduino 1.0.4 from http://arduino.cc/en/Main/Software
* To be able to test without interfering with my existing and working Arduino libraries I renamed the freshly downloaded app to Arduino_104_UDP.app and then moved it into /Applications/
* Download the ZIP from https://github.com/mlafauci/Arduino/tree/wifishield-bugfix
* Copy files wifiHD.elf and wifiHD.hex from (I refer to their github URLs, but it's easier to copy them from the ZIP you just downloaded)
https://github.com/mlafauci/Arduino/tree/wifishield-bugfix/hardware/arduino/firmwares/wifishield/wifiHD/Release
to the right place inside your app bundle. That is: /Applications/Arduino_104_UDP.app/Contents/Resources/Java/hardware/arduino/firmwares/wifishield/
*  Open the file  /Applications/Arduino_104_UDP.app/Contents/Resources/Java/hardware/arduino/firmwares/wifishield/scripts/ArduinoWifiShield_upgrade.sh in a text editor and change line 3 from
Code:
WIFI_FW_PATH="/hardware/arduino/firmwares/wifi-shield/"
to
Code:
WIFI_FW_PATH="/hardware/arduino/firmwares/wifishield/"
* copy the library in to the Arduino app: copy https://github.com/mlafauci/Arduino/tree/wifishield-bugfix/libraries/WiFi
into
/Applications/Arduino_104_UDP.app/Contents/Resources/Java/libraries

2. Update the shield

* remove the WifiShield from the Arduino.
* connect the jumper.
* connect the WifiShield with the mini USB connector to your computer
* open Terminal.app and type

Code:
sudo sh /Applications/Arduino_104_UDP.app/Contents/Resources/Java/hardware/arduino/firmwares/wifishield/scripts/ArduinoWifiShield_upgrade.sh -a"/Applications/Arduino_104_UDP.app/Contents/Resources/Java" -f shield

it will ask for your password.
type it and press enter.
This will appear:

Code:
      Arduino WiFi Shield upgrade
=========================================
Instructions:

To access to the USB devices correctly, the dfu-programmer needs to have the root permissions.

You can upgrade the firmware of the antenna togheter with the shield firmware or only the shield firmware
if there aren't changes on the antenna firmware.

Use the '-h' parameter for help
=========================================

./avr-objcopy: '/Applications/Arduino_104_UDP.app/Contents/Resources/Java/hardware/arduino/firmwares/wifishield/wifi_dnld.elf': No such file
****Upgrade WiFi Shield firmware****

Validating...
261594 bytes used (103.01%)

Done. Remove the J3 jumper and press the RESET button on the shield.
Thank you!

* Remove the J3 jumper and press RESET.
* close terminal, you're done here.

3. Testing and keeping your fingers crossed.

*Open the Arduino_104_UDP.app and copy paste this code in a fresh sketch:
(do not forget to change the code for your network settings)


Code:
#include <SPI.h>
#include <WiFi.h>
#include <WiFiUdp.h>

int status = WL_IDLE_STATUS;
char ssid[] = "NETWORKNAME"; // your network SSID (name) Your network name here, case sensitive!
char pass[] = "PASSWORD";  // if your network doesn't use WPA or WEP, change the line below that says "status = WiFi.begin(ssid, pass);"
unsigned int localPort = 2390; // local port to listen on

char packetBuffer[255]; //buffer to hold incoming packet
char  ReplyBuffer[] = "acknowledged"; // a string to send back

WiFiUDP Udp;
int counter = 0;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  Serial.println("WifiUdpSendReceiveString");

  // 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...");
  Udp.begin(localPort);  
}

void loop() {

  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if(packetSize)
  {  
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remoteIp = Udp.remoteIP();
    Serial.print(remoteIp);
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer,255);
    if (len >0) packetBuffer[len]=0;
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
  else{
// this will show you that the sketch is actually running and not crashing
// remove this, it's useless.
    counter ++;
    if(counter%2000 == 0){
      Serial.println("no packet");
    }
  }
}


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");
}


* upload it to your Arduino UNO
* connect the wifiShield if you haven't yet.
* open the Serial Monitor to the Arduino, it will tell you the IP of your wifishield when it connects to the network.
* open a UDP program and make it send a UDP message to the IP you just got from your Arduino and the port 2390.
If you are into C++ you can quickly use this OpenFrameworks example: https://github.com/openframeworks/openFrameworks/tree/master/examples/addons/networkUdpSenderExample
if you are into Obj-C and Cocoa, there's the very nice CocoaAsyncSocket class with ready to compile UDP examples. (I use these for testing) https://github.com/robbiehanson/CocoaAsyncSocket
* See the Arduino receive your message in the Serial Monitor.
* smile.
« Last Edit: March 29, 2013, 09:32:39 am by timKnapen » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks a lot! tim and mlafauci both of you guys,

There is a one more thing to make it work out though,

IMPORTANT
1. do not use/download wrong files wifiHD.elf(50KB) and wifiHD.hex(2,002KB) directly from (https://github.com/mlafauci/Arduino/tree/wifishield-bugfix/hardware/arduino/firmwares/wifishield/wifiHD/Release)

2. Do download a whole Arduino-wifishield-bugfix.zip(230MB) file from (https://github.com/mlafauci/Arduino/tree/wifishield-bugfix), then use those firmware binary files; wifiHD.elf (708KB) and wifiHD.hex(703KB)

Somehow those two files are different within .zip and the github raw code. This is the reason for the parsing error is occurred, every time when I parse the .hex to compile on the AT32UC3A1512 chip, because I used wrong files.

Cheers, Arduino! Cheers, developers!
Logged

Antwerp, Belgium
Offline Offline
Jr. Member
**
Karma: 2
Posts: 64
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Jimunkim,

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.

But there are different ones in this folder: https://github.com/mlafauci/Arduino/tree/wifishield-bugfix/hardware/arduino/firmwares/wifishield/binary

maybe that explains the confusion?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ?

Code:
#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");
}
« Last Edit: April 15, 2013, 12:50:03 am by ohhopi » Logged

Antwerp, Belgium
Offline Offline
Jr. Member
**
Karma: 2
Posts: 64
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ohhopi,
I'd love to help you, but I can't test it myself right now. Do you have any compile errors? if so, can you post them?


buzlityr,
The upload script is really not so complicated, you should be able to recreate its behaviour on windows. Check it out here:
https://github.com/mlafauci/Arduino/blob/wifishield-bugfix/hardware/arduino/firmwares/wifishield/scripts/ArduinoWifiShield_upgrade.sh

it really only sets some paths and then does
Code:
./avr-objcopy --output-target=ihex $WIFI_FW_PATH/wifi_dnld.elf  $WIFI_FW_PATH/wifi_dnld.hex
  ./avr-objcopy --output-target=ihex $WIFI_FW_PATH/wifiHD.elf  $WIFI_FW_PATH/wifiHD.hex
and then
Code:
dfu-programmer at32uc3a1256 erase
  dfu-programmer at32uc3a1256 flash --suppress-bootloader-mem $WIFI_FW_PATH/wifiHD.hex
  dfu-programmer at32uc3a1256 start

I think it shouldn't be to difficult to recreate from the command line, right?

best,
tim.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ...) :/
Logged

Antwerp, Belgium
Offline Offline
Jr. Member
**
Karma: 2
Posts: 64
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi ohhopi,

I don't understand. Your code doesn't compile for me. I'm using this Time library: http://playground.arduino.cc/Code/time
Are you using a different one? Is the code you posted really the one you use??

I get these errors:
Code:
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

best,
tim.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley-sad
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....
Logged

Pages: 1 [2] 3 4   Go Up
Jump to: