Go Down

Topic: Sending and Receiving Structures over UDP (Read 914 times) previous topic - next topic

kingofl337

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.

Nick Gammon

Something like this should do it:

Code: [Select]
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.

Code: [Select]
Udp.sendPacket( (byte *) &sent, sizeof sent, remoteIp, remotePort);


For reading, something like this:

Code: [Select]
Udp.readPacket((byte *) &received, sizeof received, remoteIp, remotePort);
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

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.

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*) <near match>
C:\arduino-0022\libraries\Ethernet/Udp.h:57: note:                 int UdpClass::readPacket(char*, uint16_t, uint8_t*, uint16_t&) <near match>


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




Nick Gammon


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. ;)

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.

Code: [Select]
#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:

Code: [Select]
  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.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Go Up