Sending and Receiving Structures over UDP

So, I’m trying to build a little robot controller using the Ethernet shield and I’d like to take two structures and send and receive data using them.

struct received {
int pwm1;
int pwm2;
int pwm3;
int pwm4;
unsigned char DO0;
unsigned char DO1;
unsigned char DO2;
unsigned char DO3;
};

struct sent {
int analog0;
int analog1;
int analog2;
int analog3;
unsigned char DI0;
unsigned char DI1;
unsigned char DI2;
unsigned char DI3;
};

How do I convert them to and from a byte array to be send via UDP.

byte DataIn[28];
Udp.readPacket(DataIn,28, remoteIp, remotePort);
DataIn —> received

byte DataOut[28];
DataOut <— sent
Udp.sendPacket( DataOut, remoteIp, remotePort);

Thanks for your help in advance.

Something like this should do it:

Udp.sendPacket( (byte *) &sent, remoteIp, remotePort);

You don't need the intermediate array. However I see a couple of problems. One is that I don't count 28 bytes there. The second is that you don't want a zero-terminated string for hopefully obvious reasons.

You need the overload that takes a length, eg.

Udp.sendPacket( (byte *) &sent, sizeof sent, remoteIp, remotePort);

For reading, something like this:

Udp.readPacket((byte *) &received, sizeof received, remoteIp, remotePort);

So I gave it a go and the compiler now hates me. I don’t firmly understand how to properly address pointers so that’s probably my problem.

UDPSendReceiveString_rev2.cpp: In function ‘void loop()’:
UDPSendReceiveString_rev2:86: error: call of overloaded ‘readPacket(byte*, int, byte [4], unsigned int&)’ is ambiguous
C:\arduino-0022\libraries\Ethernet/Udp.h:55: note: candidates are: int UdpClass::readPacket(uint8_t*, uint16_t, uint8_t*, uint16_t*)
C:\arduino-0022\libraries\Ethernet/Udp.h:57: note: int UdpClass::readPacket(char*, uint16_t, uint8_t*, uint16_t&)

struct received {
int pwm1;
int pwm2;
int pwm3;
int pwm4;
unsigned char DIO0;
unsigned char DIO1;
unsigned char DIO2;
unsigned char DIO3;
};

struct sent {
int analog0;
int analog1;
int analog2;
int analog3;
unsigned char DI0;
unsigned char DI1;
unsigned char DI2;
unsigned char DI3;
};

struct received *dataIn;
struct send *dataOut;

void loop() {
// if there’s data available, read a packet
int packetSize = Udp.available(); // note that this includes the UDP header

if(packetSize)
{

packetSize = packetSize - 8; // subtract the 8 byte header
Udp.sendPacket( (byte *) &dataOut, 12, remoteIp, remotePort);
Udp.readPacket( (byte *) &dataIn, 12, remoteIp, remotePort);
}
}

kingofl337:
So I gave it a go and the compiler now hates me. I don’t firmly understand how to properly address pointers so that’s probably my problem.

It doesn’t hate you. It doesn’t have feelings. :wink:

Your problem in this case was the 4th argument (remotePort) which as you can see from the error message is expected to be a pointer. The amended version below compiles. I can’t say whether it works, but it compiles without errors.

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <Udp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008

byte mac[] = {  
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

byte remoteIp[] = { 
  192,168,1,177 };

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

unsigned int remotePort;

struct received {
  int pwm1;
  int pwm2;
  int pwm3;
  int pwm4;
  unsigned char DIO0;
  unsigned char DIO1;
  unsigned char DIO2;
  unsigned char DIO3;
};

struct sent {
  int analog0;
  int analog1;
  int analog2;
  int analog3;
  unsigned char DI0;
  unsigned char DI1;
  unsigned char DI2;
  unsigned char DI3;
};

struct received *dataIn;
struct send *dataOut;

void setup ()
{
  // start the Ethernet and UDP:
  Ethernet.begin(mac,remoteIp);
  Udp.begin(localPort);
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.available(); // note that this includes the UDP header

  if(packetSize)
  {
    packetSize = packetSize - 8;      // subtract the 8 byte header
    Udp.sendPacket( (byte *) &dataOut, 12, remoteIp, remotePort);
    Udp.readPacket( (byte *) &dataIn, 12, remoteIp, &remotePort);
  }
}

I’m not sure about this stuff:

  if(packetSize)
  {
    packetSize = packetSize - 8;      // subtract the 8 byte header
    Udp.sendPacket( (byte *) &dataOut, 12, remoteIp, remotePort);
    Udp.readPacket( (byte *) &dataIn, 12, remoteIp, &remotePort);
  }

What if packetSize happens to be 2? You subtract 8, giving -6.