error: cannot convert 'String' to 'char*' when passing an argument to a function

I’m modifying a program that is a bit above my skill level and have run into a problem that I can’t work out how to fix. My guess is that I am trying to pass a string to a function but what it wants is a char of some kind. However I don’t know what a char* is or what to do about it.

The original code passes the AT command “AT+CMGR=1” to the function sendCommand(). This returns the SMS in position 1. What I want to do is cycle through positions 1 to 10 returning each SMS in turn. I figured I could use a for i = 1 to 10 loop and add i to the end of the command “AT+CMGR=” but I’m getting an error. Any thoughts of how to fix this or a better way of doing things is appreciated.

Complier error: cannot convert ‘String’ to ‘char*’ for argument ‘1’ to 'int sendCommand(char*, char*, unsigned int)'

Original code:

if(sendCommand("AT+CMGR=1", "+CMGR: ", 1000) == 1){
  //do something with the SMS
{

My code:

// declared before setup()
String command ="";                                                      //string to hold a command before sending it


//inside loop()
  for(int i = 1; i < 10; i++)                                              //cycle through the first 10 messages 
  {
  command = "AT+CMGR=";
  command.concat(i);
  if(sendCommand(command, "+CMGR: ", 1000) == 1)     //if (there is a message in position i) 
  {
    //do something with the SMS

The function sendCommand sends an AT command to the SMS module via a software serial port. The SMS module replies with "+CMGR: " followed by the message text.
Arguments: sendCommand( , , )
Returns: the message text. i.e. the message I sent to the module from my phone
Note: all comments are mine, they are not necessarily correct!

int sendCommand(char* ATcommand, char* expected_answer, unsigned int timeout){
 int answer=0;                                                                     //The expected answer has not been received (answer = 0) else (answer = 1)
 int responsePos=0;                                                             //position in the response array
 char response[100];                                                           //Array to store the response from the module
 unsigned long previous;                                                      //store the previous millis() for the timeout

 memset(response, '\0', 100);                                               // Clears array
 delay(100);
 while( SIM800.available() > 0) SIM800.read();                       // Clean the input buffer
 SIM800.println(ATcommand);                                                // Send the AT command to the SMS module

 responsePos = 0;		
 previous = millis();                                                               // the current time to measure timeout

 do{                                                                                     // this loop waits for the answer until the timeout expires
  // if there is data in the UART input buffer, read it and check for the answer                                  
  if(SIM800.available() != 0){                                                 //if data is availiabe   
   response[responsePos] = SIM800.read();                             //read the character[in array position responsePos] from the serial port
   responsePos++;                          //move to the next character
   if (strstr(response, expected_answer) != NULL)                     //check if the desired answer is in the response from the module
   {
    answer = 1;                                                                       //there was an answer and it matches the expected answer
   }
  }
 }while((answer == 0) && ((millis() - previous) < timeout));      //Waits for the answer with time out
 return answer;							                     //return the SMS text
}

And now you have found one of many reasons the String class is a frowned upon thing in the Arduino world. Not only does it waste memory, but it doesn't work with a lot of other code written for the more useful char arrays.

I think the String class has a toCharArray() method you can call, but the real answer is to ditch the Strings and learn how to use char arrays instead. The next problem you'll run into with them is that they tend to fragment memory and on a micro with 2K of RAM that can be a big deal if you use them too much.

Follow Delta-G's advice and also check out the family of str* functions (strcpy(), strcat(), strcmp(), plus the 'n' variants--strncpy()--plus others).

cannot convert 'String' to 'char*'

The below conversion snipit may have what you need.

char buffer[20];
readString.toCharArray(buffer, 20);
int nRead= atoi(buffer);
long nReadLong= atol(buffer);
unsigned long nReadHex= strtoul(buffer, NULL, 16);

Delta_G:
And now you have found one of many reasons the String class is a frowned upon thing in the Arduino world. Not only does it waste memory, but it doesn’t work with a lot of other code written for the more useful char arrays.

I think the String class has a toCharArray() method you can call, but the real answer is to ditch the Strings and learn how to use char arrays instead. The next problem you’ll run into with them is that they tend to fragment memory and on a micro with 2K of RAM that can be a big deal if you use them too much.

It sounds like I have a lot of learning to do!

I want this to run reliably for months or years, so would it be a better idea to just use the original code ten times over? I.E.

if(sendCommand("AT+CMGR=1", "+CMGR: ", 1000) == 1){
  //do something with the SMS
if(sendCommand("AT+CMGR=2", "+CMGR: ", 1000) == 1){
  //do something with the SMS
if(sendCommand("AT+CMGR=3", "+CMGR: ", 1000) == 1){
  //do something with the SMS
...

I assume the result would be ten copies of the code to “do something with the SMS” in memory which is a waste.

Alternatively I guess I could do this:

for(int i = 1; i < 10; i++) {
  if(i==1){  sendCommand("AT+CMGR=1", "+CMGR: ", 1000) };
  if(i==2){  sendCommand("AT+CMGR=2", "+CMGR: ", 1000) };
  if(i==3){  sendCommand("AT+CMGR=3", "+CMGR: ", 1000) };
}
//do something with the SMS... or call a function that processes the SMS

Sometimes it’s almost too easy:

char cmnd[10] = "AT+CMGR=1";

for (int i = 1; i<10; i++){
  cmnd[8] = '0' + i;  // convert number to ascii and replace in array
  if(sendCommand(cmnd , "+CMGR: ", 1000){
    // code here or whatever you're wanting to do with that string or SMS
  }
}

EDIT: That comment should say convert the DIGIT to ascii as it would not work for numbers larger than 9.

Brilliant. You're a genius!

Just so I understand, this is what I think you are doing:

create an array of 9 characters and one index character. Fill it with AT+CMGR=1 *char cmnd[10] = "AT+CMGR=1"; *

Take the ASCII character for zero. Add the value of i to it. So if i=2 we get the ASCII character for two. The compiler is smart enough to know that a char plus an int equals a char. = '0' + i;

Replace the 8th character of the array (1) with what we have just calculated (2) cmnd[8] =

And the result is AT+CMGR=2

Now because cmnd is an array of characters it can be passed to sendCommand() without any problems because it is expecting an array.

Thanks Delta_G and everyone else.