Reading String from Serial Port

Hi, I need some advices and suggestionS because I've been working this for days. :frowning:
I have string with 11 characters(a celphone number) to be specific, from serial port and I want arduino to get that string and insert it in the code below. After it'll be inserted, I'll open the serial monitor and a SMS will be sent to the celphone number(the 11 characters, the string). My problem is, the recovered string is not the string from the serial port. Error message i written below.

      char text[11];
      int  bufferIndex = 0;
      char Rx_data[50];
      unsigned char Rx_index = 0;
      int i = 0;
      char msg[160];
      int sig
      
      void setup(){
      Serial.begin(38400);
          initGSM();
           loop_Serial();
          send_msg(text, "Your sample has been tested. You may now get your result. Thank you.");
      }
      
      void loop_Serial()
      {
           if( Serial.available())
        {
    char ch = (char)Serial.read();
    if( ch == '\n')  // is this the terminating carriage return
    {
      text[ bufferIndex ] = 0; // terminate the string with a 0      
      bufferIndex = 0;  // reset the index ready for another string
      // do something with the string
      Serial.println(text);
    }
    else
      text[ bufferIndex++ ] = ch; // add the character into the buffer
 }
      }
      
      void loop() {
        //none
      }

      void send_msg(char *number, char *msg)
      {
        char at_cmgs_cmd[30] = {'\0'};
        char msg1[160] = {'\0'};
        char ctl_z = 0x1A;

        sprintf(msg1, "%s%c", msg, ctl_z);
        sprintf(at_cmgs_cmd, "AT+CMGS=\"%s\"\r\n",number);

        sendGSM(at_cmgs_cmd);
        delay(100);
        delay(100);
        delay(100);
        sendGSM(msg1);
        delay(100);
      }

      void sendGSM(char *string){
        Serial.write(string);
        delay(90);
      }

      void clearString(char *strArray) {
        int j;
        for (j = 100; j > 0; j--)
          strArray[j] = 0x00;
      }

      void send_cmd(char *at_cmd, char clr){
        char *stat = '\0';
        while(!stat){
          sendGSM(at_cmd);
          delay(90);
          readSerialString(Rx_data);

          stat = strstr(Rx_data, "OK");
        }
        if (clr){
          clearString(Rx_data);
          delay(200);
          stat = '\0';
        }
      }

      void initGSM(){

        send_cmd("AT\r\n",1);                       
      //  send_cmd("ATE0\r\n",1); // Turn off automatic echo of the GSM Module  

        send_cmd("AT+CMGF=1\r\n",1);            // Set message format to text mode
        //Sucess

        Serial.println("Success");

        delay(1000);
        delay(1000);
        delay(1000);
      }

      void readSerialString (char *strArray) {

        if(!Serial.available()) {
          return;
        }

        while(Serial.available()) {
          strArray[i] = Serial.read();
          i++;
        }
      }

ERROR MESSAGE------
AT
AT+CMGF=1
Success
AT+CMGS="S"
Your sample has been tested. Thank you.

Any advices and suggestions are highly appreciated :)))

a string is an array of char with 1 extra char witch is null and marks the end of the string so for an 11 digit number the array needs to be 12 long. You must ensure that the last char is a null.

Mark

Hi mark! yes, i ensure that the number of values that i sent is always 12 char including the '\n'. I think my problem is within the loop_Serial part. :frowning:

can you tell me why are you using below loop.

char *stat = '\0';
while(!stat){

Try this code.

      char text[12];
      int  bufferIndex = 0;
      char Rx_data[50];
      unsigned char Rx_index = 0;
      int i = 0;
      char msg[160];
      int sig;
      
      void setup(){
      Serial.begin(38400);
          initGSM();
           loop_Serial();
          send_msg(text, "Your sample has been tested. You may now get your result. Thank you.");
      }
      
      void loop_Serial()
      {
        char ch;
        while(ch != '@')
        {
           Serial.println("waiting for data..");          
           while(!(Serial.available()>0));
              char ch = (char)Serial.read();
              Serial.println(ch);
              
              if( ch == '@')  // is this the terminating carriage return
              {
                text[ bufferIndex ] = 0; // terminate the string with a 0      
                bufferIndex = 0;  // reset the index ready for another string
                // do something with the string
                Serial.println(text);
                return;
              }
              else
              text[ bufferIndex++ ] = ch; // add the character into the buffer
            }
        }

      
      void loop() {
        //none
      }

      void send_msg(char *number, char *msg)
      {
        char at_cmgs_cmd[30] = {'\0'};
        char msg1[160] = {'\0'};
        char ctl_z = 0x1A;

        sprintf(msg1, "%s%c", msg, ctl_z);
        sprintf(at_cmgs_cmd, "AT+CMGS=\"%s\"\r\n",number);

        sendGSM(at_cmgs_cmd);
        delay(100);
        delay(100);
        delay(100);
        sendGSM(msg1);
        delay(100);
      }

      void sendGSM(char *string){
        Serial.write(string);
        delay(90);
      }

      void clearString(char *strArray) {
        int j;
        for (j = 100; j > 0; j--)
          strArray[j] = 0x00;
      }

      void send_cmd(char *at_cmd, char clr){
        char *stat = '\0';
        while(!(*stat)){

          sendGSM(at_cmd);
          delay(90);
          readSerialString(Rx_data);

          stat = strstr(Rx_data, "OK");
        }
        if (clr){
          clearString(Rx_data);
          delay(200);
          stat = '\0';
        }
      }

      void initGSM(){

        send_cmd("AT\r\n",1);                       
      //  send_cmd("ATE0\r\n",1); // Turn off automatic echo of the GSM Module  

        send_cmd("AT+CMGF=1\r\n",1);            // Set message format to text mode
        //Sucess

        Serial.println("Success");

        delay(1000);
        delay(1000);
        delay(1000);
      }

      void readSerialString (char *strArray) {
        int ii = 0;
         while(Serial.available() >= 0) {
          strArray[ii] = Serial.read();
          ii++;
          if(ii ==  11)
            return;
        }

//        if(!Serial.available() = 0) {
//          return;
//        }

      }

Vmateo:
Hi mark! yes, i ensure that the number of values that i sent is always 12 char including the '\n'. I think my problem is within the loop_Serial part. :frowning:

No no... if you are receiving 12 characters including the '\n', and are storing 11 characters in text[], text[] needs to be 12 characters long in order to hold the NULL terminator.

However, that's not as important right now. Have a look at your loop_Serial() function. It does this...

check for at least one Serial byte available
if no bytes are available,  leave the function and return
if a byte is available 
   if it's a '\n'
      terminate the string
      set the index to 0
      print the buffer
  else
      add the character to the buffer and increment the index
leave the function.

Note that there is no loop here. You will either return immediately, or you will store one character in text[] and return.

your loop() function is empty, which is surprising, since you do want to loop, and the Arduino folks have kindly provided it for you. Naming a function as loop_whatever, does not create a loop.

Thanks everyone for replying :frowning: I'm so touched. I transffered loop_Serial to void loop() and now the buffer is empty. By the way I'm throwing string from matlab and here's my matlab code:

delete(instrfindall)
text=11;
s = serial('COM7', 'BaudRate', 38400);
fopen(s);
pause(0.1)
text=input('','s');
fprintf(s, '%s\n', text);
pause(0.1);
fscanf(s)
pause(0.1)
delete(instrfindall)
  void setup(){
   setupSerial();
   setupGSM();
  }
  
  void loop(){
    loopSerial();
    loopGSM();
  }

char buffer[12];
int  bufferIndex = 0;

void setupSerial(){
}

void loopSerial()
{
  if( Serial.available())
  {
    char ch = (char)Serial.read();
    delay(100);
    if( ch == '\n')  // is this the terminating carriage return
    {
      buffer[ bufferIndex ] = 0; // terminate the string with a 0      
      bufferIndex = 0;  // reset the index ready for another string
      // do something with the string
      Serial.println(buffer);
    }
    else
      buffer[ bufferIndex++ ] = ch; // add the character into the buffer
}
} 
 
char Rx_data[50];
unsigned char Rx_index = 0;
int i = 0;
char msg[160];
int sig;
 
void setupGSM() {
    Serial.begin(38400);

  initGSM();
  send_msg(buffer, "Your sample has been tested. You may now get your result. Thank you.");
}
 
void loopGSM() {
  //none
}
 
void send_msg(char *number, char *msg)
{
  char at_cmgs_cmd[30] = {'\0'};
  char msg1[160] = {'\0'};
  char ctl_z = 0x1A;
 
  sprintf(msg1, "%s%c", msg, ctl_z);
  sprintf(at_cmgs_cmd, "AT+CMGS=\"%s\"\r\n",number);
  
  sendGSM(at_cmgs_cmd);
  delay(100);
  delay(100);
  delay(100);
  sendGSM(msg1);
  delay(100);
}
 
void sendGSM(char *string){
  Serial.write(string);
  delay(90);
}
 
void clearString(char *strArray) {
  int j;
  for (j = 100; j > 0; j--)
    strArray[j] = 0x00;
}
 
void send_cmd(char *at_cmd, char clr){
  char *stat = '\0';
  while(!stat){
    sendGSM(at_cmd);
    delay(90);
    readSerialString(Rx_data);
    
    stat = strstr(Rx_data, "OK");
  }
  if (clr){
    clearString(Rx_data);
    delay(200);
    stat = '\0';
  }
}
 
void initGSM(){
  
  send_cmd("AT\r\n",1);						
//  send_cmd("ATE0\r\n",1); // Turn off automatic echo of the GSM Module	
	
  send_cmd("AT+CMGF=1\r\n",1);			// Set message format to text mode
  //Sucess
  
  Serial.println("Success");
  Serial.println(buffer);
	
  delay(1000);
  delay(1000);
  delay(1000);
}
 
void readSerialString (char *strArray) {
  
  if(!Serial.available()) {
    return;
  }
  
  while(Serial.available()) {
    strArray[i] = Serial.read();
    i++;
  }
}

I tried this code still don't work. It seems my serial buffer is empty.. :frowning:

You aren't doing anything in setupSerial()

Try this code. It's yours, but rearranged a bit. It does not call any GSM routines, nor does it send the message "your sample...", but what it does is to allow you to use the Serial Monitor to send a string to the Arduino, and to receive the characters back. You should now do the GSM stuff, but to the Serial port, so you can see what's happening. You can change the baud rate in Serial.begin when you want to go back to using Matlab.

char buffer[12];
int  bufferIndex = 0;

char Rx_data[50];
unsigned char Rx_index = 0;
int i = 0;
char msg[160];
int sig;

void setup(){
  Serial.begin(19200); // This MUST be in setup()
//  setupGSM();
}

void loop(){
  if( Serial.available())
  {
    char ch = (char)Serial.read();
    delay(100);
    if( ch == '\n')  // is this the terminating carriage return
    {
      buffer[ bufferIndex ] = 0; // terminate the string with a 0      
      bufferIndex = 0;  // reset the index ready for another string
      // do something with the string
      Serial.println(buffer);
    }
    else
      buffer[ bufferIndex++ ] = ch; // add the character into the buffer
  }
}

void setupGSM() {
  initGSM();
  send_msg(buffer, "Your sample has been tested. You may now get your result. Thank you.");
}

void loopGSM() {
  //none
}

void send_msg(char *number, char *msg)
{
  char at_cmgs_cmd[30] = {
    '\0'  };
  char msg1[160] = {
    '\0'  };
  char ctl_z = 0x1A;

  sprintf(msg1, "%s%c", msg, ctl_z);
  sprintf(at_cmgs_cmd, "AT+CMGS=\"%s\"\r\n",number);

  sendGSM(at_cmgs_cmd);
  delay(100);
  delay(100);
  delay(100);
  sendGSM(msg1);
  delay(100);
}

void sendGSM(char *string){
  Serial.write(string);
  delay(90);
}

void clearString(char *strArray) {
  int j;
  for (j = 100; j > 0; j--)
    strArray[j] = 0x00;
}

void send_cmd(char *at_cmd, char clr){
  char *stat = '\0';
  while(!stat){
    sendGSM(at_cmd);
    delay(90);
    readSerialString(Rx_data);

    stat = strstr(Rx_data, "OK");
  }
  if (clr){
    clearString(Rx_data);
    delay(200);
    stat = '\0';
  }
}

void initGSM(){

  send_cmd("AT\r\n",1);						
  //  send_cmd("ATE0\r\n",1); // Turn off automatic echo of the GSM Module	

  send_cmd("AT+CMGF=1\r\n",1);			// Set message format to text mode
  //Sucess

  Serial.println("Success");
  Serial.println(buffer);

  delay(1000);
  delay(1000);
  delay(1000);
}

void readSerialString (char *strArray) {

  if(!Serial.available()) {
    return;
  }

  while(Serial.available()) {
    strArray[i] = Serial.read();
    i++;
  }
}

To clarify one point. The code I posted in Reply #8 is to be run while connected to the PC, and not ro the GSM modem. To do this, upload the code to the Arduino, then run the Serial Moitor and set the baud rate to match the Serial.begin() baud rate. Set the line ending to "Newline". Type 11 characters into the box at the tope of the Serial Mnitor and hit RETURN (or click the SEND button). You will see your typed characters echoed back to you.

The reason you were not seeing any characters in your other code was because you did not wait for them to arrive.

Hi sir this is my code and I was able to type a string and was inserted in the GSM code and was able to send SMS to the string I entered. But I found another problem, I have to switch to USUART so that I can enter a number and then switch to UART so that the GSM cpde part will work. Is there a way so that I don't need to switch and switch? :slight_smile: Thanks everyone for the effort.!

String readString;
char charb[12];
char Rx_data[50];
unsigned char Rx_index = 0;
int i = 0;
char msg[160];
int sig;
 
 
void setup(){
    Serial.begin(38400);
}

void loop() {  

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      //do stuff
      Serial.println(readString); //prints string to serial port out
      readString.toCharArray(charb, 12);
      initGSM();
      send_msg(charb, "Your sample has been tested. You may now get your result. Thank you.");
      readString=""; //clears variable for new input      
     }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

void loopGSM() {
  //none
}
 
void send_msg(char *number, char *msg)
{
  char at_cmgs_cmd[30] = {'\0'};
  char msg1[160] = {'\0'};
  char ctl_z = 0x1A;
 
  sprintf(msg1, "%s%c", msg, ctl_z);
  sprintf(at_cmgs_cmd, "AT+CMGS=\"%s\"\r\n",number);
  
  sendGSM(at_cmgs_cmd);
  delay(100);
  delay(100);
  delay(100);
  sendGSM(msg1);
  delay(100);
}
 
void sendGSM(char *string){
  Serial.write(string);
  delay(90);
}
 
void clearString(char *strArray) {
  int j;
  for (j = 100; j > 0; j--)
    strArray[j] = 0x00;
}
 
void send_cmd(char *at_cmd, char clr){
  char *stat = '\0';
  while(!stat){
    sendGSM(at_cmd);
    delay(90);
    readSerialString(Rx_data);
    
    stat = strstr(Rx_data, "OK");
  }
  if (clr){
    clearString(Rx_data);
    delay(200);
    stat = '\0';
  }
}
 
void initGSM(){
  
  send_cmd("AT\r\n",1);						
//  send_cmd("ATE0\r\n",1); // Turn off automatic echo of the GSM Module	
	
  send_cmd("AT+CMGF=1\r\n",1);			// Set message format to text mode
  //Sucess
  
  Serial.println("Success");
	
  delay(1000);
  delay(1000);
  delay(1000);
}
 
void readSerialString (char *strArray) {
  
  if(!Serial.available()) {
    return;
  }
  
  while(Serial.available()) {
    strArray[i] = Serial.read();
    i++;
  }
}