WiDi UDP library with touchOSC [Solved]

Hi everyone,

I'm using an Arduino WiFi Shield plugged on an Arduino Uno REV3 with receive values from an iPhone thanks to the touchOSC app. My current problem is that the Arduino cut the string received from the iPhone which is something like :

http://192.168.0.122/1/fader1 0.4175616515

But the library WiFi UDP cut the string just after "fader1" because there is a space and the value after is important to control a motor :~
Wath is the parameter that I must change in the library ? (maybe in the spi_drv.cpp ?)

Thanks, Benjamin

Wath is the parameter that I must change in the library ?

What makes you think you need to change a library? Where is your code?

Thanks for your reply !

The library is this one : https://github.com/arduino/Arduino/tree/master/libraries/WiFi

I think the datas are received and saved while there is no space

I think the datas are received and saved while there is no space

Well, I don't. So post your code to prove me wrong.

The Arduino code :

/*
  WiFi UDP Send and Receive String
 
 This sketch wait an UDP packet on localPort using a WiFi shield.
 When a packet is received an Acknowledge packet is sent to the client on port remotePort
 
 Circuit:
 * WiFi shield attached
 
 created 30 December 2012
 by dlf (Metodo2 srl)

 */

//la libraire WiFiUdp est dispo dans le repo github arduino ainsi que des examples
#include <SPI.h>
#include <WiFi.h>
#include <WiFiUdp.h>

int status = WL_IDLE_STATUS;
char ssid[] = "Ouai"; //  your network SSID (name) 
char pass[] = "123654789";    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;            // your network key Index number (needed only for WEP)

unsigned int localPort = 2390;      // local port to listen on


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

WiFiUDP Udp;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600); 
  pinMode(4, OUTPUT);
  
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  
  // check for the presence of the 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. 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...");
  // if you get a connection, report back via serial:
  Udp.begin(localPort);  
}

void loop() {
      int pwmVal;    // Integer that will hold our PWM values for later use

  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if(packetSize)
  {   
    //packetSize = packetSize - 8;      // subtract the 8 byte header
    Serial.print("Packet size: ");
    Serial.println(packetSize);

    // read the packet into packetBuffer and get the senders IP addr and port number
    Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
    Serial.println("Message: ");
    Serial.println(packetBuffer);
    //pwmVal = (packetBuffer[11])*100 + (packetBuffer[12])*10 + (packetBuffer[13]);
    //Serial.println(pwmVal);
    // 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();
    
    digitalWrite(4, LOW);
   }
}


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

 /*   void receive(byte[] data) 
    { // <-- default handler
    //void receive( byte[] data, String ip, int port ) {	// <-- extended handler

    for(int i=0; i < data.length; i++)
    Serial.print(char(data[i]));
    Serial.println();
    }*/

And what is displayed when I move fader1 :

Packet size: 20
Message:
/1/fader1/

That doesn't appear to be 20 characters.

Please try this:

    Serial.print("Message: [");
    Serial.print(packetBuffer);
    Serial.println("]");

so we can see where the packet really ends.

No surprise, this appear :

Packet size: 20
Message: [/1/fader1/]

No surprise, this appear :

That’s somewhat of a surprise, since 10 characters are printed, though the first message indicates 20.

So, let’s try printing all the characters:

    Serial.print("Message: [");
    for(int i=0; i<packetSize; i++)
    {
      Serial.print(packetBuffer[i]);
    }
    Serial.println("]");

I might be just adding noise, but it seems to me that you are trying to pass a value embedded within a URI. The space character is not a valid URI character. (Ever wonder about all those "%20"s in some URIs? That decodes to space.)

If you are able to change the data being sent to your Arduino, I'd suggest changing the format such that you would get something that looks like this:
http://192.168.0.122/1/fader1?setting=0.4175616515
or
http://192.168.0.122/1/controls?fader1=0.4175616515
or some other formulation of a properly formatted URI... I'm not familiar with the various ethernet libraries out there so I don't know if there exists a library that can parse that for you, or if you have to manually parse it. But it shouldn't be that hard once you have a handle on C string functions. (Seek to the question mark, read to a buffer until the equals, switch case on the buffer and take the value from right after the equals to EOL or semicolon. If not EOL repeat from read to a buffer.)

Edit: corrected spelling from "controlls" to "controls"

Thanks for your replies !

PaulS, I tried your code and get :

Packet size: 20
Message: [/1/fader1/,f¿ ä]
Packet size: 20
Message: [/1/fader1/,f¿K]
Packet size: 20
Message: [/1/fader1/,f¾Ô¢P]
Packet size: 20
Message: [/1/fader1/,f=3]
Packet size: 20
Message: [/1/fader1/,f>3@]
Packet size: 20
Message: [/1/fader1/,f?³]

Maybe it's the result of the interpretation of a value that doesn't exist ?...

Sembazuru, the iPhone the informations from touchOSC, an app existing, within which I only can change the interface, add and remove sliders, push buttons etc... But I haven't access to the code sent

The output you get is consistent. The text part, followed by an f, followed by some non-character data.

Processing has a library to deal with OSC messages. Perhaps you could port that to the Arduino. Or, maybe there already is one.

PaulS:
The output you get is consistent. The text part, followed by an f, followed by some non-character data.

Processing has a library to deal with OSC messages. Perhaps you could port that to the Arduino. Or, maybe there already is one.

I don't see what you mean. You suggest me to try with another library ?

You suggest me to try with another library ?

Yes. You are getting a packet now that you do not understand. Only part of the packet contains ASCII data. The rest contains binary data (slider values, etc.). You can either look at the OSC packet format, and write code to properly use the whole packet, or you can look for a library that already does it.

The Arduino WiFi Shield library is the only library which work with the WiFi Shield. So the only solution is to try with this library, but I didn’t found the transfer mechanism on it…

Thanks for all !

I don't know what you found with your searches, but check out this link:
http://blog.arduino.cc/category/protocol/osc/

Especially, look at the last paragraph of the page in italics. It references an Arduino OSC library. (I'm not sure if it is input or output though...)

I also found this:
http://cnmat.berkeley.edu/oscuino
One bullet point of note is

Send and receive messages over any transport layer that implements the Arduino’s Stream Class such as Serial, EthernetUdp, and more.

The Arduino WiFi Shield library is the only library which work with the WiFi Shield. So the only solution is to try with this library, but I didn't found the transfer mechanism on it...

The WiFi library establishes the connection between the Arduino and the PC.

The UDP library manages the transfer of packets. It doesn't give a rats ass what's in the packet.

You've got a packet that contains some data that you don't know how to process. Why not look for a library that does know? The one that Sembazuru mentions bears looking at.

First of all, thanks for your help !

PaulS:

The Arduino WiFi Shield library is the only library which work with the WiFi Shield. So the only solution is to try with this library, but I didn't found the transfer mechanism on it...

The WiFi library establishes the connection between the Arduino and the PC.

The UDP library manages the transfer of packets. It doesn't give a rats ass what's in the packet.

You've got a packet that contains some data that you don't know how to process. Why not look for a library that does know? The one that Sembazuru mentions bears looking at.

I agree with you, but the data is not received on the WiFi Shield and on the Ethernet Shield with the same protocol, and with the last Arduino library (which is the only one including Udp exploitation), all files are like "merged", they works together. That's why I'm not able to import an Ethernet library (modified) to work with the WiFi Shield, and on the link that Sembazuru sent (thanks to you) we can see here touchOSC | CNMAT that all files are build to work with Ethernet...

I'm starting to go round in circles because of I'm not familiar with exploitation and the modification of open transmission libraries. And don't find much support and examples for this Shield :frowning:

Logically, when the information is received it stop the recording when there is a space ? (if yes I don't find where in the Arduino library)
And then if the criterion of stop is changed to 2 spaces for example, it could be work, no ?

That's why I'm not able to import an Ethernet library (modified) to work with the WiFi Shield, and on the link that Sembazuru sent (thanks to you) we can see here touchOSC | CNMAT that all files are build to work with Ethernet...

OK. I see your problem. That is a shame that the touchosc library is bundled so tightly with the Ethernet library. It really should be possible to separate then, since, clearly, you are getting a packet, and it does contain data that seems reasonable given the source of the data.

Logically, when the information is received it stop the recording when there is a space ? (if yes I don't find where in the Arduino library)
And then if the criterion of stop is changed to 2 spaces for example, it could be work, no ?

No. It stops printing when it encounters a NULL in the string. The rest of the packet is binary data.

Ok, I just understood what the binary data are. It correspond to the ANSI language... Can I convert it to get a number ? And print it ?