Transmitting string over UDP datagram

Hi experts here,
I must transmit a string over UDP datagram

That code will not work with UDPBuffer being a string.
It expects an array of char.

    udp.beginPacket(IPAdress, SendPort); 
    udp.write(UDPBuffer,sizeof(UDPBuffer);
    udp.endPacket();

Since my content need to be values written as ASCII strings, I wonder how to code it.
Currently I wanted to first populate a string, then to copy that string to the array of char.

    UDPBufferPrepare = "#01M"+String(dB)+">";
    strncpy(UDPBuffer, UDPBufferPrepare.c_str(UDPPacketSize);

but I got that error upon compiling:
exit status 1
no matching function for call to 'String::c_str(int&)'

Has anyone got a clue?
Does a way exist to send the string directly?
Else, how to copy the string to the array?

Thank you.

string.c_str() doe not take a parameter as the error message states, try

UDPBufferPrepare.c_str()

horace:
string.c_str() doe not take a parameter as the error message states, try

UDPBufferPrepare.c_str()

That was not successful:

error: invalid conversion from 'byte* {aka unsigned char*}' to 'char*' [-fpermissive]

strncpy(UDPBuffer, UDPBufferPrepare.c_str());

error: too few arguments to function 'char* strncpy(char*, const char*, size_t)'

There's no reason to use the String class for this, or to build up any other RAM buffer. The library allows writing to the Ethernet device's buffer (through the Socket routines), so you don't need one. Instead of this:

    UDPBufferPrepare = "#01M"+String(dB)+">";
    strncpy(UDPBuffer, UDPBufferPrepare.c_str() );

    udp.beginPacket(IPAdress, SendPort); 
    udp.write(UDPBuffer,sizeof(UDPBuffer);
    udp.endPacket();

... you can just send the pieces:

    udp.beginPacket(IPAdress, SendPort); 

    udp.print( F("#01M") );
    udp.print( db );
    udp.print( '>' );

    udp.endPacket();

The pieces are accumulated in the W5100 device until you call endPacket. Then one UDP packet will be sent.

The udp variable is derived from the Arduino Print class (via Stream), so all of your favorite printing methods can be used.

I assume that the receiver watches for the '>' character as an end marker to the packet.

If you would rather use a RAM buffer to save 2 SPI transactions, you could build it this way:

   char *ptr = (char *) &UDPBuffer[0];
    strcpy_P( ptr, PSTR("#01M") ); // copy in constant part of string
    ptr = &ptr[ strlen(ptr) ];     // advance pointer to end of copied string

    itoa( db, ptr, 10 );           // assumes db is an int
    ptr = &ptr[ strlen(ptr) ];     // advance pointer past db digits

    *ptr++ = '>';    // append one char (writes over terminating NUL)
    *ptr++ = '\0';   // append NUL terminator

    udp.beginPacket(IPAdress, SendPort); 
    udp.write( UDPBuffer, strlen( (char *) UDPBuffer ) ); // does not send NUL character.  Add 1 if you want to.
    udp.endPacket();

-dev:
There's no reason to use the String class for this, or to build up any other RAM buffer. The library allows writing to the Ethernet device's buffer (through the Socket routines), so you don't need one.

    udp.beginPacket(IPAdress, SendPort); 

udp.print( F("#01M") );
    udp.print( db );
    udp.print( '>' );

udp.endPacket();



The pieces are accumulated in the W5100 device until you call `endPacket`. Then one UDP packet will be sent.

The `udp` variable is derived from the Arduino `Print` class (via `Stream`), so all of your favorite printing methods can be used.

I assume that the receiver watches for the '>' character as an end marker to the packet.

Thank you and stupid me! Of course, I should have read the manual.
It was silly to use udp.write(), when udp.print() is the far better choice. So easy!
It even works in one line: udp.print("#01M"+String(dB)+">");

It even works in one line: udp.print("#01M"+String(dB)+">");

:-/

Have you seen the many, many comments about using the String class? If you haven't, [url=http://here's a summary of some reasons. Be sure to read The Evils of Arduino Strings. So... Don't use String™... unless you like weird behaviour, random crashes and hangs. Using String is even worse when combined with larger libraries, like Ethernet.

You should also use the F macro to prevent double-quoted strings from being copied to RAM. The F macro allows them to be used directly from FLASH (e.g., for printing or concatenating in Reply#4).

Lest you doubt, here are 4 test programs for you to try:

#define udp Serial

int db = 1430;

void setup()
{
  udp.begin( 9600 );

  udp.print( F("#01M") );
  udp.print( db );
  udp.print( '>' );
}

void loop() {}
#define udp Serial

uint8_t UDPBuffer[40];
int db = 1430;

void setup()
{
  char *ptr = (char *) &UDPBuffer[0];
  strcpy_P( ptr, PSTR("#01M") ); // copy in constant part of string
  ptr = &ptr[ strlen(ptr) ];     // advance pointer to end of copied string

  itoa( db, ptr, 10 );           // assumes db is an int
  ptr = &ptr[ strlen(ptr) ];     // advance pointer past db digits

  *ptr++ = '>';    // append one char (writes over terminating NUL)
  *ptr++ = '\0';   // append NUL terminator

  udp.begin( 9600 );
  udp.write( UDPBuffer, strlen((char *) UDPBuffer) );
}

void loop() {}
#define udp Serial

int db = 1430;

void setup()
{
  udp.begin( 9600 );

  udp.print("#01M"+String(db)+">");
}

void loop() {}

And if you really want to put it all on one line, you can use the Streaming library. This essentially uses the << operator to "Stream" the pieces out.

#include <Streaming.h>

#define udp Serial

int db = 1430;

void setup()
{
  udp.begin( 9600 );

  udp << F("#01M") << db << '>';
}

void loop() {}

Now the juicy part... program sizes:

| ** Method ** | **| Program ** | **| RAM ** |
| - | - | - |
| Print pieces | | 2168 | | 184 |
| RAM buffer | | 1908 | | 224 |
| String | | 3900 | | 269 (222 + 10 + 37 heap) |
| Streaming | | 2178 | | 184 |

Your choice, of course. :wink:

Cheers,
/dev

-dev:
:-/

Have you seen the many, many comments about using the String class? If you haven't, [url=http://here's a summary of some reasons. Be sure to read The Evils of Arduino Strings. So... Don't use String™... unless you like weird behaviour, random crashes and hangs. Using String is even worse when combined with larger libraries, like Ethernet.

I did not know that. Thank you for the clue.