reading int_16 by UDP?

My telemetry project is going fine. My transmitter is sending three 16 bit variables via UDP.

My receive program is receiving the 6 bytes but the software fetches the bytes as characters but is is awfully BIG as well. The UDP receive is copied from the udpServer example in the UIPEthernet example library

It should(?) be simple to pull the variables out of the buffer 2 bytes at a time but everything I have tried creates a whole lot of compiler errors.

This is the mostly-working code:

/  /*
  * data expiry working
  * added serial2 data timeout
  * remove Display routines 12/01/2017
  * Reverse servo directions 12/01/2017
  */

#include <Wire.h>
#include <SPI.h>
#include <Servo.h>
#include <UIPEthernet.h>
EthernetUDP udp; 
// define Servos & Servo trim

Servo hdgservo;  // create servo object to control a servo
Servo depthservo ; 
Servo pitchservo ;


long inBuffer ; // serial input buffer
int depth ;
int posD = 0 ; // Depth Zero = 0
int posH = 90; // Heading 0 = 90
int posP = 90 ; // posP 0 = 90
int posDtrim = 0 ; // servo trim to match scale
int posHtrim = -10 ;
int posPtrim = 0 ;
int diveSwitch ; // surface/dive switch variable
int dataLED = 32 ; // good data led o/p
int temp = 0 ; //temporary variable
int size ;
int dataValidflag = 0 ; //good data flag

//Define soft variables
// Timing

int dataTimer = 15 ; // expiry time for data
int tick = 0 ; // 1 Second clock
unsigned long currentT = 0 ;
unsigned long lastT = 0 ;
unsigned long currentPressure ;
unsigned long surfacePressure ;
int timeOut ;
// Raw input data from telemetry

int (compass) ;
int pressure ;
int pitch ;
int lastcount ; // last serial byte counter

// Setup code

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  uint8_t mac[6] = {0x06,0x05,0x04,0x03,0x02,0x01};

  Ethernet.begin(mac,IPAddress(10,0,199,6));

  int success = udp.begin(5000);
 
  Serial.print("initialize: ");
  Serial.println(success ? "success" : "failed");
  
  hdgservo.attach(36);
  depthservo.attach(38);
  pitchservo.attach(40) ;

 pinMode (dataLED, OUTPUT) ;
 pinMode (diveSwitch, INPUT) ;
 

  Serial.println ("Setup complete") ;
}

void loop() {

  struct DOFDATA
{
  uint16_t compass;
  uint16_t pressure;
  uint16_t pitch;
} ;

  static byte counter = 0;
  static byte rxBuffer[sizeof(DOFDATA)];

  DOFDATA dd;
  //check for new udp-packet:
    int size = udp.parsePacket();

  if (size > 0) {
    Serial.print ("Size =");
    Serial.println (size) ;
      
    do
      {
        char* msg = (char*)malloc(size+1);
        int len = udp.read(msg,size+1);
        msg[len]=0;
        Serial.print("received: '");
        Serial.println(msg);
        free(msg);
      }
    while ((size = udp.available())>0);
    //finish reading this packet:
    udp.flush();
      Serial.println("'")   ;
 
    int success;
    do
      {
        Serial.print("remote ip: ");
        Serial.println(udp.remoteIP());
        Serial.print("remote port: ");
        Serial.println(udp.remotePort());
        //send new packet back to ip/port of client. This also
        //configures the current connection to ignore packets from
        //other clients!
        success = udp.beginPacket(udp.remoteIP(),udp.remotePort());
        Serial.print("beginPacket: ");
        Serial.println(success ? "success" : "failed");
    //beginPacket fails if remote ethaddr is unknown. In this case an
    //arp-request is send out first and beginPacket succeeds as soon
    //the arp-response is received.
      }
    while (!success);

    success = udp.println("hello world from arduino");

    Serial.print("bytes written: ");
    Serial.println(success);

    success = udp.endPacket();

    Serial.print("endPacket: ");
    Serial.println(success ? "success" : "failed");

    udp.stop();
    //restart with new connection to receive packets from other clients
    Serial.print("restart connection: ");
   Serial.println (udp.begin(5000) ? "success" : "failed");
  

    compass = (dd.compass);
    pressure = (dd.pressure) ;
    pitch = (dd.pitch) ;
    (dataTimer = 10) ; // set data timer
//    updateServos() ; // Update servos and registers
 
    // display the received data
   Serial.print("compass: "); Serial.println(compass);
   Serial.print("pressure @depth: "); Serial.println(pressure);
    Serial.print("pitch: "); Serial.println(pitch);
    Serial.println ("") ;
//    Serial.print ("dataValid flag ") ; Serial.println (dataValidflag) ;
    if (dataValidflag == 0) {
      updateServos() ;
    }
  }

// ************ 1 Second timer loop *************

  (currentT = (millis()/1000)) ;
  if (currentT > lastT) {
    
    (lastT = currentT ) ;
    tick++  ; 
    statusUpdate() ;
    }
 
  if (tick >= 7) {
   (tick = 0) ;
  }

  switch(tick) {

  case 1: {
    tick++ ;
//    updateServos() ; // Update servos and registers    
    break ;
  }

  case 5: {
    statusUpdate () ;
    tick++ ;
    break ;
  }
}

// FUNCTIONS


}
  
// ***************** Update servos

void updateServos () {
  
  if (compass>181) {
      posH = (map(compass, 181 , 359, 180 , 90)) ;
    }
    else {
      posH = (map(compass, 0, 180, 90, 0)) ; // write current heading to servo
    } 
    hdgservo.write(posH+posHtrim);

    (depth = ((currentPressure - surfacePressure)*0.401)) ;
    Serial.print ("Depth ") ; Serial.println (depth) ;
    posD = map(depth, 0, 300, 180, 0) ; // write current depth to servo
    depthservo.write(posD+posDtrim);
    
    posP = map(pitch, -20, 20, 135, 45) ; //map pitch for servo
    pitchservo.write(posP+posPtrim) ;

 //   Serial.print ("Surface Prssure ") ; Serial.println (surfacePressure) ;
//    Serial.print ("Current Prssure ") ; Serial.println (currentPressure) ;
//    Serial.print ("Differential Prssure ") ; Serial.println (pressure) ;
    
  return ;

// **************** Status Update
}

void statusUpdate () { 
  diveSwitch = digitalRead (30) ;
  
    if (diveSwitch == HIGH){
     
     (surfacePressure = currentPressure) ; // set Surface pressures
     (dataTimer = 10) ; // set data timer
      
      }
    if (dataTimer >= 1 ) {
    dataTimer -- ; // dec. data timer

    }
   
  if (dataTimer != 0) {   
  digitalWrite (dataLED, HIGH) ; // dataLED on

  }
    else {
  digitalWrite (dataLED, LOW) ; // dataLED on 

  }
  
  return ;
  }

// ********* Serial Timeout
// in 1 Second loop

Can somebody, ANYBODY point me to a SIMPLE way to read these 3 16-bit variables from the UDP bufffer!!??

Thanks

 (pressure = (event.pressure));

Is there a special on parentheses today at the Bracket Store?

What are the problems you're having?

Sure, brackets are cheap! Always good to have extras LOL!

Sorry, posted the wrong software and had to wait the 5 minutes to end my post.

The software I am using reads the buffer as characters, not integers, and I can't seem to fetch the bytes as 16 bit numbers.

Always good to have extras LOL!

No. Useless ones make you look clueless. That is not an impression you WANT to foster, is it?

The software I am using reads the buffer as characters, not integers, and I can't seem to fetch the bytes as 16 bit numbers.

Not likely. It is far more likely that the buffer's type is byte. You can take one byte, shift it 8 places to the left, and add another byte to get an int. With the proper casting, of course.

        int len = udp.read(msg,size+1);

Dynamic memory allocation for this purpose is just plain wrong. There is a fixed upper limit to the size of a UDP packet. You should be using an array of the proper, FIXED, size. The second argument to read is the size of the array. Why on earth are you lying to the function, and telling it it has more space than it really does, to write to?

Have you ACTUALLY looked at the documentation or source code for the read() method?

  virtual int read(unsigned char* buffer, size_t len);

Are you passing it an unsigned char (aka a byte) pointer? No, you are not. Why not?

I am new to Arduino and this is my first time - be gentle! :wink:

I tried this version to read the values from the buffer directly (non-relevant code deleted) but get all kinds of errors I can’t figure out:

  .......
  Serial.println ("Setup complete") ;
}

void loop() {

  struct DOFDATA
{
  uint16_t compass;
  uint16_t pressure;
  uint16_t pitch;
} ;

  static byte counter = 0;
  static byte rxBuffer[sizeof(DOFDATA)];

  DOFDATA dd;
  //check for new udp-packet:
    int size = udp.parsePacket();

  if (size =6) {
    Serial.print ("Size =");
    Serial.println (size) ;
      
    do
      {
        udp.read(compass, 2);
        udp.read(pressure, 2);
        udp.read(pitch, 2);  
        Serial.print("compass : '");
        Serial.println(compass);
        Serial.print("Pressure : '");
        Serial.println(pressure);
        Serial.print("Pitch : '");
        Serial.println(pitch);      
      }

    while ((size = udp.available())>0);
    //finish reading this packet:
    udp.flush();
      Serial.println("'")   ;
 
    int success;
    do
      {
        Serial.print("remote ip: ");
        Serial.println(udp.remoteIP());
        Serial.print("remote port: ");
        Serial.println(udp.remotePort());
        //send new packet back to ip/port of client. This also
        //configures the current connection to ignore packets from
        //other clients!
        success = udp.beginPacket(udp.remoteIP(),udp.remotePort());
        Serial.print("beginPacket: ");
        Serial.println(success ? "success" : "failed");
    //beginPacket fails if remote ethaddr is unknown. In this case an
    //arp-request is send out first and beginPacket succeeds as soon
    //the arp-response is received.
      }
    while (!success);

    success = udp.println("hello world from arduino");

    Serial.print("bytes written: ");
    Serial.println(success);

    success = udp.endPacket();

    Serial.print("endPacket: ");
    Serial.println(success ? "success" : "failed");

    udp.stop();
    //restart with new connection to receive packets from other clients
    Serial.print("restart connection: ");
   Serial.println (udp.begin(5000) ? "success" : "failed");
  

    compass = (dd.compass);
    pressure = (dd.pressure) ;
    pitch = (dd.pitch) ;
    (dataTimer = 10) ; // set data timer
//    updateServos() ; // Update servos and registers
 
    // display the received data
   Serial.print("compass: "); Serial.println(compass);
   Serial.print("pressure @depth: "); Serial.println(pressure);
    Serial.print("pitch: "); Serial.println(pitch);
    Serial.println ("") ;
//    Serial.print ("dataValid flag ") ; Serial.println (dataValidflag) ;
    if (dataValidflag == 0) {
      updateServos() ;
    }
  }

// ************ 1 Second timer loop *************

 ...............

Errors:

Arduino: 1.6.13 (Windows 7), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

WARNING: Category '' in library UIPEthernet is not valid. Setting to 'Uncategorized'
C:\Users\Dianne\Documents\Arduino\SS_3_0_1\SS_3_0_1.ino: In function 'void loop()':

SS_3_0_1:99: error: call of overloaded 'read(int&, int)' is ambiguous

         udp.read(compass, 2);

                            ^

C:\Users\Dianne\Documents\Arduino\SS_3_0_1\SS_3_0_1.ino:99:28: note: candidates are:

In file included from C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/Dhcp.h:7:0,

                 from C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPEthernet.h:30,

                 from C:\Users\Dianne\Documents\Arduino\SS_3_0_1\SS_3_0_1.ino:11:

C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPUdp.h:94:3: note: virtual int UIPUDP::read(unsigned char*, size_t) <near match>

   read(unsigned char* buffer, size_t len);

   ^

C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPUdp.h:94:3: note:   no known conversion for argument 1 from 'int' to 'unsigned char*'

C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPUdp.h:98:3: note: virtual int UIPUDP::read(char*, size_t) <near match>

   read(char* buffer, size_t len)

   ^

C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPUdp.h:98:3: note:   no known conversion for argument 1 from 'int' to 'char*'

SS_3_0_1:100: error: call of overloaded 'read(int&, int)' is ambiguous

         udp.read(pressure, 2);

                             ^

C:\Users\Dianne\Documents\Arduino\SS_3_0_1\SS_3_0_1.ino:100:29: note: candidates are:

In file included from C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/Dhcp.h:7:0,

                 from C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPEthernet.h:30,

                 from C:\Users\Dianne\Documents\Arduino\SS_3_0_1\SS_3_0_1.ino:11:

C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPUdp.h:94:3: note: virtual int UIPUDP::read(unsigned char*, size_t) <near match>

   read(unsigned char* buffer, size_t len);

   ^

C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPUdp.h:94:3: note:   no known conversion for argument 1 from 'int' to 'unsigned char*'

C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPUdp.h:98:3: note: virtual int UIPUDP::read(char*, size_t) <near match>

   read(char* buffer, size_t len)

   ^

C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPUdp.h:98:3: note:   no known conversion for argument 1 from 'int' to 'char*'

SS_3_0_1:101: error: call of overloaded 'read(int&, int)' is ambiguous

         udp.read(pitch, 2);  

                          ^

C:\Users\Dianne\Documents\Arduino\SS_3_0_1\SS_3_0_1.ino:101:26: note: candidates are:

In file included from C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/Dhcp.h:7:0,

                 from C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPEthernet.h:30,

                 from C:\Users\Dianne\Documents\Arduino\SS_3_0_1\SS_3_0_1.ino:11:

C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPUdp.h:94:3: note: virtual int UIPUDP::read(unsigned char*, size_t) <near match>

   read(unsigned char* buffer, size_t len);

   ^

C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPUdp.h:94:3: note:   no known conversion for argument 1 from 'int' to 'unsigned char*'

C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPUdp.h:98:3: note: virtual int UIPUDP::read(char*, size_t) <near match>

   read(char* buffer, size_t len)

   ^

C:\Users\Dianne\Documents\Arduino\libraries\arduino_uip-master/UIPUdp.h:98:3: note:   no known conversion for argument 1 from 'int' to 'char*'

exit status 1
call of overloaded 'read(int&, int)' is ambiguous

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

if (size =6)Oops.

AWOL: if (size =6)Oops.

Yea, OOPS!

Still can't get rid of the errors.....

Try this:

        udp.read((unsigned char*)compass, 2);
        udp.read((unsigned char*)pressure, 2);
        udp.read((unsigned char*)pitch, 2);

edit: Or this:

        udp.read((unsigned char*)&compass, 2);
        udp.read((unsigned char*)&pressure, 2);
        udp.read((unsigned char*)&pitch, 2);

The second alternative worked!!!

.................

void loop() {

  //check for new udp-packet:
    int size = udp.parsePacket();

  if (size == 6) {
    Serial.print ("Size =");
    Serial.println (size) ;
      
        udp.read((unsigned char*)&compass, 2);
        udp.read((unsigned char*)&pressure, 2);
        udp.read((unsigned char*)&pitch, 2);  
    size = 0 ;
        Serial.print("compass : ");
        Serial.println(compass);
        Serial.print("Pressure : ");
        Serial.println(pressure);
        Serial.print("Pitch : ");
        Serial.println(pitch);      
      }

    while ((size = udp.available())>0);
    //finish reading this packet:
      Serial.print (size);
      Serial.println("'")   ;

    udp.endPacket();

    Serial.print("endPacket: ");
    Serial.println(" ended");

    udp.stop();
    //restart with new connection to receive packets from other clients
    Serial.print("restart connection: ");
   Serial.println (udp.begin(5000) ? "success" : "failed");
  
//    updateServos() ; // Update servos and registers

    // display the received data
 //  Serial.print("compass: "); Serial.println(compass);
 //  Serial.print("pressure @depth: "); Serial.println(pressure);
//    Serial.print("pitch: "); Serial.println(pitch);
//    Serial.println ("") ;
//    Serial.print ("dataValid flag ") ; Serial.println (dataValidflag) ;
//    if (dataValidflag == 0) {
//      updateServos() ;



// ************ 1 Second timer loop *************

...............

but it prints "size = 0", "end packet: ended", and "restart connection: success" every time through the loop until the next incoming packet but when I comment out the print lines in the while loop, it doesn't work at all.

    while ((size = udp.available())>0);
    //finish reading this packet:
//      Serial.print (size);
//      Serial.println("'")   ;

    udp.endPacket();

//    Serial.print("endPacket: ");
//    Serial.println(" ended");

    udp.stop();
    //restart with new connection to receive packets from other clients
//    Serial.print("restart connection: ");
//   Serial.println (udp.begin(5000) ? "success" : "failed");

Obviously something needs to be cleaned up in preparation for the next receive but I haven't figured it out yet :(

Once you do the read from the udp, there will no longer be any bytes available.

Okay. I deleted all the other 'crap' after the read and it working now.

  //check for new udp-packet:
    int size = udp.parsePacket();

  if (size == 6) {
    Serial.print ("Size =");
    Serial.println (size) ;
      
        udp.read((unsigned char*)&compass, 2);
        udp.read((unsigned char*)&pressure, 2);
        udp.read((unsigned char*)&pitch, 2);  
    size = 0 ;
        Serial.print("compass : ");
        Serial.println(compass);
        Serial.print("Pressure : ");
        Serial.println(pressure);
        Serial.print("Pitch : ");
        Serial.println(pitch);      
      }

I don't understand what all the other stuff was about but my objective was to complete this one project, not to become an 'expert' in Arduino so ......

I owe you a coffee (if not a stiff drink LOL!)

Thanks man!