Converting a String to uint8_t

Hi,
I have been struggling with a problem.
I am attempting to write the following to SPI.
All is ok when I send this:
uint8_t data = "MD111111111111111111111111111111111#(40)";
However, what I need to do is have the string in a variable and send the string variable.
For instance:
String myString = "MD111111111111111111111111111111111#(40)";
uint8_t data = myString;

Can anyone point me in the right direction please

Use this:

An unsigned int 8 bit is a byte or unsigned char.

byte buf[31];
myString.StringToCharArray(buf,30);

Use this

Or not. There is no reason to have a String in the first place. Use a char array!

char *myData = "MD111111111111111111111111111111111#(40)";

Then, where you need to use data, use (uint8_t *)myData instead.

Edit: Get the cast right!

ecoguy:
...
However, what I need to do is have the string in a variable and send the string variable.
...

As we said from @Pauls, you can use string or String but String are very heavy.
I think that you confuse string (array of char) and String (object-class)

P.S. sorry for my English

Hi guys,
Thanks for the replies.
I am sorry, but I just cannot seem to get my head around this.

Would I need to do this:

Declare Variables:

byte buf[31];
String myString = "MD111111111111111111111111111111111#(40)";

In the code:

uint8_t data = myString.StringToCharArray(buf,30);

NOT with assignement :grin:

uint8_t data[30];
myString.StringToCharArray(data,30); // or myString.StringToCharArray(data,sizeof(data));

String is easy to abuse so why are you needing it in the first place? Possibly change to c-string as Paul suggested. Post your code.

Hi All,
I am still having problems.
Going back to basics - here is the original example sketch:

// rf22_reliable_datagram_client.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple addressed, reliable messaging client
// with the RF22ReliableDatagram class.
// It is designed to work with the other example rf22_reliable_datagram_server

#include <RF22ReliableDatagram.h>
#include <RF22.h>
#include <SPI.h>

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 255

// Singleton instance of the radio
RF22ReliableDatagram rf22(CLIENT_ADDRESS);

void setup() 
{
  Serial.begin(9600);
  if (!rf22.init())
    Serial.println("RF22 init failed");
  // Defaults after init are 434.0MHz, 0.05MHz AFC pull-in, modulation FSK_Rb2_4Fd36
}

uint8_t data[] = "Hello World!";
// Dont put this on the stack:
uint8_t buf[RF22_MAX_MESSAGE_LEN];

void loop()
{
  while (1)
  {
    Serial.println("Sending to rf22_datagram_server");
    
    // Send a message to rf22_server
    if (!rf22.sendtoWait(data, sizeof(data), SERVER_ADDRESS))
      Serial.println("sendtoWait failed");
    else
    {
      // Now wait for a reply from the server
 //     Serial.println(rf22.lastRssi(), HEX); // of the ACK
      uint8_t len = sizeof(buf);
      uint8_t from;   
      if (rf22.recvfromAckTimeout(buf, &len, 2000, &from))
      {
        Serial.print("got reply from : 0x");
        Serial.print(from, HEX);
        Serial.print(": ");
        Serial.println((char*)buf);
      }
      else
      {
        Serial.println("No reply, is rf22_datagram_server running?");
      }
    }
    delay(500);
  }
}

The “canned” message “Hello World!” I must be able to change to my own.

As an example, I have an RFID reader that I obtain data from, this data I need to transmit via the RFM22
So: The “Hello World!” message must be changed to the data I have from the RFID.

Slowly going bald - 1 hair at a time,

For you, the compiler analize the code line:
uint8_t data = "Hello World!";

Hello World!
123456789012

and allocate a variable (an array o vector) of name data and 12 elements of type uint8_t.

If you receive a msg from any other device and is a string (vector/array of char) you can send this vector instead "data" or copy from this vector to "data" array.
You can use memcpy() for example. And you must define uint8_t data[30] with a constant space that you know, 30 for example, so big to allow the other message to be copied into it.

void loop()
{
  while (1)
  {

Why are you running an infinite loop inside an infinite loop? It makes one think that you don't understand that loop() is an infinite loop.

Hi nid69ita,
Could you possibly give me a code snippet as to how I should approach this.
I am an absolute newbie and reading up on memcpy has me more confused than ever

I can try but I don't know RFID or RF22.
You can write small pice of code, one that read from RFID and second that write on RF22?

This is the send for RF22?
if (!rf22.sendtoWait(data, sizeof(data), SERVER_ADDRESS))

Yes, that is correct.

This sends to the RFM22:

if (!rf22.sendtoWait(data, sizeof(data), SERVER_ADDRESS))

This is the data that is sent:

uint8_t data[] = "Hello World";

I need to change/substitute the "Hello World" text with my own text string.
eg. "SW0000001D10"

For instance,
I have a string that I can type on the Arduino Serial Monitor that is:
"SW0000001D10"
This string must now be sent to the RFM22 with:
uint8_t data = "SW0000001D10"

This is what I am trying to accomplish

Now for me is not clear. You want send some chars to RFM22 (using rf22.sendtoWait). okay.
From where you receive the string? In last post you tell about serial monitor, previous post you tell about RFID ?!?

Do you have tried to send the string using this as constant (not receiving from serial or RFID) ?
(simply change "Hello World" with "SW0000001D10")

uint8_t data[] = "SW0000001D10";

and use

if (!rf22.sendtoWait(data, sizeof(data), SERVER_ADDRESS))

or fixed len (I count 12)

if (!rf22.sendtoWait(data, 12, SERVER_ADDRESS))

Thanks Igor,
Yes I have tried:
uint8_t data = "SW0000001D10";
and send with:
if (!rf22.sendtoWait(data, sizeof(data), SERVER_ADDRESS))

and it works perfectly.

In order to understand what I am doing and how this all works, I am, for now, using the Serial Monitor as the "Input" for the data I want to send with: uint8_t data =
I will later, once I understand this, change it to what is received from RFID port.

If I type "SW0000001D10" into Serial Monitor, I must use this to send to the RFM22: uint8_t data = "SW0000001D10";

If I type "SW9999999D10" into Serial Monitor, I must use this to send to the RFM22: uint8_t data = "SW9999999D10";

It is these strings that are not constant and will change.

So, whatever I type in the Serial Monitor, will be sent to the RFM22 with: uint8_t data = "XXX...XXX".
Where "XXX...XXX" is the data.

For receiving data from serial this is a good tutorial/reference:

The first code is useful. But it process message when found a newline char (\n) and I don't know if this char is send from RFID.

Something like this (base structure from Gammon):

const unsigned int MAX_INPUT = 50; // how much serial data we expect before a newline
char input_line [MAX_INPUT];
unsigned int input_pos = 0;
const byte MSG_LEN=12;   // SW0000001D10

void setup ()
{ Serial.begin(9600);
} // end of setup

void loop()
{ if (Serial.available () > 0) 
  { char inByte = Serial.read ();
    switch (inByte)
    { case '\n':   // discard carriage return
      case '\r':   // discard carriage return
        break;
      default:
        if (input_pos < (MAX_INPUT - 1))  // keep adding if not full ... allow for terminating null byte
        { input_line [input_pos++] = inByte;
        }
        if (input_pos >= MSG_LEN) 
        { input_line [input_pos] = 0;     // terminating null byte
          process_data (input_line);
          input_pos = 0;                  // reset buffer for next time
        }
        break;
      }  // end of switch
  }  // end of incoming data
  // do other stuff here like testing digital input (button presses) ...
} // end of loop

void process_data (char * data) // here to process incoming serial data after a terminator received
{ Serial.println (data); // for now just display it
  if (!rf22.sendtoWait(data, MSG_LEN , SERVER_ADDRESS))
  {
  }
}  // end of process_data

On function process_data() you need to send to RF22.
Is not a perfect code, only tried one time

Thanks Igor,
This is the complete code:

// rf22_reliable_datagram_client.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple addressed, reliable messaging client
// with the RF22ReliableDatagram class.
// It is designed to work with the other example rf22_reliable_datagram_server

#include <RF22ReliableDatagram.h>
#include <RF22.h>
#include <SPI.h>

#define CLIENT_ADDRESS 100
#define SERVER_ADDRESS 255

// Singleton instance of the radio
RF22ReliableDatagram rf22(CLIENT_ADDRESS);

const unsigned int MAX_INPUT = 50; // how much serial data we expect before a newline
char input_line [MAX_INPUT];
unsigned int input_pos = 0;
const byte MSG_LEN=12;   // SW0000001D10



void setup() 
{
  Serial.begin(9600);
  if (!rf22.init())
    Serial.println("RF22 init failed");
}

//uint8_t data[] = "0000001D00";
// Dont put this on the stack:
uint8_t buf[RF22_MAX_MESSAGE_LEN];

void loop(){
   if (Serial.available () > 0) 
  { char inByte = Serial.read ();
    switch (inByte)
    { case '\n':   // discard carriage return
      case '\r':   // discard carriage return
        break;
      default:
        if (input_pos < (MAX_INPUT - 1))  // keep adding if not full ... allow for terminating null byte
        { input_line [input_pos++] = inByte;
        }
        if (input_pos >= MSG_LEN) 
        { input_line [input_pos] = 0;     // terminating null byte
          process_data (input_line);
          input_pos = 0;                  // reset buffer for next time
        }
        break;
      }  // end of switch
  }  // end of incoming data
  // do other stuff here like testing digital input (button presses) ...
} // end of loop

void process_data (char * data) // here to process incoming serial data after a terminator received
{ 
  Serial.println (data); // for now just display it
//  if (!rf22.sendtoWait(data, MSG_LEN , SERVER_ADDRESS))
  {
  }
}  // end of process_data

When I run this, whatever I type in the Serial monitor IS displayed - works great.

If I uncomment this line:

if (!rf22.sendtoWait(data, MSG_LEN , SERVER_ADDRESS))

I get the following errors on compiling:

rf22_reliable_datagram_CPX_01.ino: In function 'void process_data(char*)':
rf22_reliable_datagram_CPX_01:60: error: invalid conversion from 'char*' to 'uint8_t*'
rf22_reliable_datagram_CPX_01:60: error: initializing argument 1 of 'boolean RF22ReliableDatagram::sendtoWait(uint8_t*, uint8_t, uint8_t)'

:frowning:

Try:

  1. declaring data as "unsigned char" instead "char"
    or
  2. force a cast to uint8_t*
if (!rf22.sendtoWait( (uint8_t *)data, MSG_LEN , SERVER_ADDRESS))

Thanks Igor,
This works:

2. force a cast to uint8_t*

if (!rf22.sendtoWait( (uint8_t *)data, MSG_LEN , SERVER_ADDRESS))

Many, many thanks.
I now understand how this works.

Just one question:
How do I append a newline '\n' to the end of data?