[SOLVED] VirtualWire and const char * msg

In the transmitter example for VirtualWire, the message being sent is declared as const char *msg = “hello”;

But what do I do if I want be flexible in the message I am sending?
What if I want to send the word goodbye instead that comes as result of user input?

How do I declare the variables so that the code will compile?

The function that uses msg is vw_send((uint8_t *)msg, strlen(msg));

The code will compile. The function also accepts normal data in ram.

Using the const storage qualifier is a bit of defensive coding. Think about what the data definition for msg is doing: It is allocating just enough memory to hold the string "hello". If you tried to write a string larger than 5 characters, you run the risk of over-running the allocated memory space. By making it a const, it prevents you from changing the string at runtime.

If you need a char array to hold differing messages that might change at runtime, use a char array instead of a pointer. For example, if you know your largest message will take a max of 20 characters, then define the array as:

char msg[21];

You need the extra byte for the null string termination character. To make the message say "goodbye", then:

char msg[21];

strcpy(msg, "goodbye");

econjack:
You need the extra byte for the null string termination character. To make the message say “goodbye”, then:

char msg[21];

strcpy(msg, “goodbye”);

VirtualWire uses uint8_t, so I am getting a compiler error about invalid conversion from uint8_t* to char*

uint8_t msg[21]; is the declaration

You might need to add a cast (uint8_t *) in front of msg.

Koepel: You might need to add a cast (uint8_t *) in front of msg.

I already did.

uint8_t msg[21];

...

strcpy(msg, "goodbye");

...

vw_send((uint8_t *) msg, strlen(msg));

...
char msg[21];

...

strcpy(msg, "goodbye");

...

vw_send((uint8_t *) msg, strlen(msg));

...

cattledog: ``` char msg[21];

...

strcpy(msg, "goodbye");

...

vw_send((uint8_t *) msg, strlen(msg));

...

This works. THANK YOU.

Would you explain why that small change of declaring msg to be char vs. uint8_t made such a difference?

ieee488: This works. THANK YOU.

Would you explain why that small change of declaring msg to be char vs. uint8_t made such a difference?

I think this will also work:

uint8_t msg[21];

...

strcpy((char *)msg, "goodbye");

...

vw_send(msg, strlen(msg));

People were looking in the wrong place, thinking the problem was at the vw_send() line - which is rather sad; the smoking gun is:

I am getting a compiler error about invalid conversion from uint8_t* to char*

uint8_t msg[21]; is the declaration

It's saying the conversion from uint8_t to char was invalid. So something needs a char*, but you're giving it a uint8_t* . vw_send() wants a uint8_t* and that's what you're giving it - so that can't be it.

Would you explain why that small change of declaring msg to be char vs. uint8_t made such a difference?

I think that when the documentation for strcpy says that the destination needs to be a pointer to a character array it means what it says.

DrAzzy:
I think this will also work:

uint8_t msg[21];

strcpy((char *)msg, “goodbye”);

vw_send(msg, strlen(msg));

Unfortunately, that does not work.

error: invalid conversion from ‘uint8_t* {aka unsigned char*}’ to ‘const char*’ [-fpermissive]
vw_send((uint8_t *) myBuffer1, strlen(myBuffer1));

I will post the entire sketch.

#include <VirtualWire.h>


uint8_t msg[21];
//char msg[21];

    
void setup() 
{
    //vw_set_ptt_inverted(true);
    vw_setup(2000);
    vw_set_tx_pin(8);

}


void loop()
{
    
    strcpy((char *)msg, "goodbye");
    vw_send(msg, strlen(msg));
    vw_wait_tx();
    delay(200);    
}

Just curious: In post #2 I said to use:

char msg[21];

but you changed it to:

uint8_t msg[21];

after Koepel told you that a cast was necessary when it was passed to the function. Why the change?

ieee488, it is not a big deal, it is all the same.

A pointer to a uint8_t is a pointer to an unsigned character. The Arduino can also use 'byte', so (byte *) could also work. For an Arduino Uno, a "uint8_t" is the same as "unsigned char", but on 32-bit processors things are different. Using "uint8_t" is defined as a unsigned character of 8 bits. That is the same for every processor and every compiler and every code.

A pointer to a char is the same pointer, but it points to a signed character.

They are all the same pointers. To change it from a pointer to char or pointer to uint8_t is only to make the compiler happy.

Some functions accept a void pointer. Then the compiler will accept any pointer.

But what If I want to send data like sensor values ? For example I have a gps . What should I do so the gps data is being transfered from one arduino to another ?

Expl0siv3Man79: But what If I want to send data like sensor values ? For example I have a gps . What should I do so the gps data is being transfered from one arduino to another ?

I'd start with a new thread that hasn't been resurrected from more than a year ago and isn't marked solved.