Problems sending string variables with UDP

Hello,

I am pretty new to Arduino programming and am having difficulty sending sensor values as strings with UDP.

I want to end up sending “DP_Scale=n” (no quotes) with n being an analog input value between 0 and 1023.

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

int sensorPin = A0; 
int sensorValue = 0;

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {  
  0x90, 0xA2, 0xDA, 0x00, 0xA1, 0xAE };
IPAddress ip(192, 168, 0, 40);
unsigned int localPort = 8888;      // local port to listen on

IPAddress RemIP(192, 168, 0, 133);
unsigned int RemPort = 7124;      // local port to listen on

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char  ReplyBuffer[] = "DP_Scale=";       // a string to send back


// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;


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

void loop() {
   sensorValue = analogRead(sensorPin);
   Serial.print("DP_Scale=");
   Serial.print(sensorValue);
   Serial.println();
   Udp.beginPacket(RemIP, RemPort);
   Udp.write("DP_Scale=");
   Udp.write(sensorValue);
   Udp.endPacket();
   delay(400); 
}

This is doing what I need it to do and it looks correct in the serial monitor, but not in the PC app that I’m sending the UDP to.
In the Serial Monitor: DP_Scale=38
In the PC app: DP_Scale=&
The 38 is being interpreted as a decimal ASCII character and ends up as an ampersand.

I changed the sketch to this to test if I can send what I need to the PC.

void loop() {
   sensorValue = analogRead(sensorPin);
   Serial.print("DP_Scale=");
   Serial.print(sensorValue);
   Serial.println();
   Udp.beginPacket(RemIP, RemPort);
   Udp.write("DP_Scale=");
   Udp.write("38");
   Udp.endPacket();
   delay(400); 
}

With this I get DP_Scale=38 in the Serial Monitor and in the PC app, and the PC app responds appropriately.

I then tried this to send the sensor value as a string since that seemed to work when I sent “38” in the previous test

void loop() {
   sensorValue = analogRead(sensorPin);
  Serial.print("DP_Scale=");
   Serial.print(sensorValue);
   Serial.println();
   Udp.beginPacket(RemIP, RemPort);
   Udp.write("DP_Scale=");
   Udp.write(String (sensorValue));
   Udp.endPacket();
   delay(400); 
}

And

void loop() {
   sensorValue = analogRead(sensorPin);
   String sensorValstring = String(sensorValue);
   Serial.print("DP_Scale=");
   Serial.print(sensorValstring);
   Serial.println();
   Udp.beginPacket(RemIP, RemPort);
   Udp.write("DP_Scale=");
   Udp.write(sensorValstring);
   Udp.endPacket();
   delay(400); 
}

Both give the same following errors when trying to compile the sketch:

no matching function for call to 'EthernetUDP::write(String&)'
UDPSend.ino: In function 'void loop()':
UDPSend:55: error: no matching function for call to 'EthernetUDP::write(String)'
C:\Users\D\Downloads\apps\arduino-1.0.3-windows\arduino-1.0.3\libraries\Ethernet/EthernetUdp.h:70: note: candidates are: virtual size_t EthernetUDP::write(uint8_t)
C:\Users\D\Downloads\apps\arduino-1.0.3-windows\arduino-1.0.3\libraries\Ethernet/EthernetUdp.h:72: note: virtual size_t EthernetUDP::write(const uint8_t*, size_t)
C:\Users\D\Downloads\apps\arduino-1.0.3-windows\arduino-1.0.3\hardware\arduino\cores\arduino/Print.h:49: note: size_t Print::write(const char*)

I’m guessing that the errors are telling me exactly what is wrong with what I’m trying to do, but I’m not having a lot of luck figuring it out. Any help is appreciated.

Thanks

Change

   Udp.write(sensorValue);

to

   Udp.print(sensorValue);

and you get what you want.

I’m guessing that the errors are telling me exactly what is wrong with what I’m trying to do, but I’m not having a lot of luck figuring it out.

They are. They are telling you not to use the String class, at least until 1.0.4.

Look at the sprintf() function to populate a char array with integer values and text.

char msg[20];
sprintf(msg, "DP_Scale=%d", sensorValue);
UDP.write(msg);

pylon:
Change

   Udp.write(sensorValue);

to

   Udp.print(sensorValue);

and you get what you want.

That was my first thought, but the EthernetUDP reference page doesn't list a print() method, nor does the class seem to have one. I can't find where the base class (UDP) is defined, so I can't tell if it has a print() method. EthernetUDP does not.

1 Like

That was my first thought, but the EthernetUDP reference page doesn't list a print() method, nor does the class seem to have one. I can't find where the base class (UDP) is defined, so I can't tell if it has a print() method. EthernetUDP does not.

EthernetUDP is based on UDP, which is based on Stream, that on Print and that implements the print method.

UDP.h is found in the Arduino core library (hardware/arduino/cores/arduino/) as well as Stream.h and Print.h.

EthernetUDP is based on UDP, which is based on Stream, that on Print and that implements the print method.

UDP.h is found in the Arduino core library (hardware/arduino/cores/arduino/) as well as Stream.h and Print.h

Thanks. Then, the print() solution may be preferred to the sprintf() solution, depending on whether or not each print() and write() call causes a new UDP packet to be sent. If it does, the print() solution will cause two packets to be sent, while the sprintf() way will only cause one to be sent.

The print() method writes the bytes to a buffer, the packet is sent when the endPacket() method is called.

Udp.print worked perfectly. I’ll look into the sprintf() function as well. Thanks!