Go Down

Topic: Sending and Receiving Structures over UDP (Read 1 time) previous topic - next topic

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

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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy