Go Down

Topic: Arduino Ethernet - some issues with UDP commuication (Read 2875 times) previous topic - next topic

_Matt_

Hello everybody, I'm using an Arduino Ethernet and I'm trying to learn something about it. I've recently played around with some example for the UDP communication and I've found out something which I can't understand.

This is my code:
Code: [Select]
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

#define localPort 7400                            
#define PACKET_SIZE 384

byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0xE5};      
IPAddress ip(192, 168, 1, 177);                    

EthernetUDP Udp;                                  

char packetBuffer[PACKET_SIZE];                    

void setup()                                      
{
 Serial.begin(9600);
 Ethernet.begin(mac, ip);
 Udp.begin(localPort);
}

void loop()
{
 int packetSize = Udp.parsePacket();              
 if (packetSize)                                  
 {
   Serial.print("The incoming packet is ");        
   Serial.print(packetSize);
   Serial.println(" bytes long");
   
   Serial.println("It contains the following characters:");
   Udp.read(packetBuffer, PACKET_SIZE);
   
   Serial.println(packetBuffer, PACKET_SIZE);
 }
}


Pretty easy, it seems a lot like the one in the tutorial but has less functions. Mine should print the size of the packet and its contents (that's exactly what it does).
The problems with the output are:
1) why if I send a string (I use MAX/MSP to do so) composed by the characters "abcde" (with no " obviously) the Arduino says that the string is 12 bytes long? That's not true , it should be 5 bytes long unless I'm missing something.
2) I'd like to send bytes/integer numbers instead of strings but I can't because when I do so (i.e. I send the number 255 with MAX) I obtain the following message: It contains the following characters: int

For the 2nd I probably need to create a new function into the EthernetUDP class but I have no idea about the first issue. Thanks for your help

PaulS

Code: [Select]
  int packetSize = Udp.parsePacket();               
  if (packetSize)                                   
  {
    Serial.print("The incoming packet is ");       
    Serial.print(packetSize);
    Serial.println(" bytes long");

packetSize isn't a boolean, and shouldn't be used like one. If you want to do something only when packetSize is greater than 0, make that explicit.

Quote
1) why if I send a string (I use MAX/MSP to do so) composed by the characters "abcde" (with no " obviously) the Arduino says that the string is 12 bytes long? That's not true , it should be 5 bytes long unless I'm missing something.

If you printed the string you receive properly, I think you'll see the issue.

Code: [Select]
    Serial.print("Packet contents: [");
    Serial.print(packetBuffer, PACKET_SIZE);
    Serial.println("]");

If there are extra characters between the [ and ], and I suspect that there will be, then Max is adding padding.

Quote
2) I'd like to send bytes/integer numbers instead of strings but I can't because when I do so (i.e. I send the number 255 with MAX) I obtain the following message: It contains the following characters: int

Certainly not an Arduino problem. Something is wrong in your Max code.

Quote
For the 2nd I probably need to create a new function into the EthernetUDP class

How you intent to make the sent value out of the string "int" I have no idea.
The art of getting good answers lies in asking good questions.

SurferTim

#2
Sep 20, 2012, 12:40 pm Last Edit: Sep 20, 2012, 02:09 pm by SurferTim Reason: 1
If you want to send non-string data, you should use the write function. This version of write is not documented in the reference, but is available in the library.
virtual size_t write(const uint8_t *buffer, size_t size);

This function will send zeros also. You will probably need to split integers into two bytes and reassemble them on the other end.

edit: I submitted a change a while back to get the write function better documented for the client and server code, and have added the udp write to that request this morning.
http://code.google.com/p/arduino/issues/detail?id=1034

_Matt_

Sorry guys I've been out for few days and I couldn't reply here. Anyway:


Code: [Select]
 int packetSize = Udp.parsePacket();              
 if (packetSize)                                  
 {
   Serial.print("The incoming packet is ");        
   Serial.print(packetSize);
   Serial.println(" bytes long");

packetSize isn't a boolean, and shouldn't be used like one. If you want to do something only when packetSize is greater than 0, make that explicit.

This is true, I didn't notice that "mistake" while copying the code prom the example.

I've used the Processing code here instead of MAX and the Arduino counts correctly the incoming bytes, it's weird how MAX is missing something. I need to check and see what's the problem there. However, I still need to understand how to receive bytes instead of char strings.

@SufferTim: I don't need to send non-string data, I need to READ non-string data on my Arduino. Anyway, the function you wrote down could be helpful. Thanks for your tips!

SurferTim

Reading should be easy. Take a look at the UdpNtpClient example in the IDE example section. It shows how to read bytes.

_Matt_

Yes it was pretty easy! Line #13, instead of
Code: [Select]
char packetBuffer[PACKET_SIZE]; the correct one is
Code: [Select]
byte packetBuffer[PACKET_SIZE];

Anyway, I still can't understand why there's a misunderstanding between MAX and the Arduino.
This is my "new" arduino code
Code: [Select]

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUPD.h>

#define localPort 7401   
#define BUFFER_SIZE 12   

byte mac[] = {0x90, 0xA2, 0xD3, 0xE0, 0x66}; 
IPAddress ip(192, 168, 1, 177);             

byte packetBuffer[BUFFER_SIZE];               

EthernetUDP Udp;                             

void setup()
{
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  Udp.begin(localPort);
}

void loop()
{   
  if (Udp.parsePacket() > 0)   
  {


    Udp.read(packetBuffer, BUFFER_SIZE);   
    for (int i = 0; i < BUFFER_SIZE; i++) 
    {
      Serial.print(packetBuffer[i]);
      if (i < 11)
        Serial.print(", ");
      else
        Serial.println(".");
    }   
  }
}


What I obtain is:
105, 110, 116, 0, 44, 105, 0, 0, 0, 0, 0, number. (number is what MAX sends)

The values before "number" never change

If I add the line - Serial.println(Udp.parsePacket()); - after line#23 I obtain:
0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.

I don't know if you're good with MAX (I am not, these are the very first sketch I make) but I will upload the "code"

Also this is pretty easy and I can't see mistakes or something.

Need help! Thanks

PaulS

Quote
If I add the line - Serial.println(Udp.parsePacket()); - after line#23 I obtain:

The parsePacket() function consumes data in the buffer. When you call it twice, the second time is has nothing to do.
The art of getting good answers lies in asking good questions.

Go Up