简体   繁体   中英

how can I display/save the value of what return an AT command

Good day all! I am working on a project with Arduino UNO and a SIM908. I am trying to understand the AT command. When I enter

Serial.print("AT")
Serial.println("AT+CGPSSTATUS?");

Serial retuen a value and I would like to save that value into a buffer

char buffer[size]

I do not want to have other string than the return value of an AT command.

I also red that document SIM908 AT Command Manual_V1.01

At the page 13, you can read (NB. < CR>< LF> : I added a space after the first < , other there are not display)

The "AT" or "at" prefix must be set at the beginning of each Command line. To terminate a Command line enter < CR>. Commands are usually followed by a response that includes. "< CR>< LF>< CR>< LF>" Throughout this document, only the responses are presented, < CR>< LF> are omitted intentionally

Then, I am asking how I can "extract" the response between < CR>< LF> and < CR>< LF>

Looking at this exemple (let me know if I am wrong), how can I detect the < CR>< LF>

void setup()
    {
char buffer[200];
    Serial.println("AT+CGPSSTATUS?");
    }
    void loop()
    {    
          if (Serial.available())
           {
// HERE I SHOULD CHECK IF CR ANF LF
             Serial.write(Serial.read());
// AND SAVE IT IN buffer. IS'T NOT?
           }
        }  

    }

Do you see what I means? How could you help me to store in a buffer, only the return value of an AT command?

Many thank for your help

Here a piece of code to detect and remove CR+LF (Attention: if A CR is read but it's not followed by a LF, it is removed as well):

   if (Serial.peek()==13) {      // check if CR (without reading)
       Serial.read();            // read and ignore 
       if (Serial.peek()==10)    // then check if LF (without reading)
          Serial.read(); 
       } 

To read the rest of the response from Serial you could use:

buffer[Serial.readBytesUntil(13, buffer, 199)]=0; // readbytes returns the number of bytes read  

You then have to discard the ending CRLF (same as above).

Edit

There are several issues with the code that you've posted in a separate answer.

When you powerUpSim908() you have to be aware that the gsm module may send unrequested data (see documentation, chapter 1.4):

Note: A HEX string such as "00 49 49 49 49 FF FF FF FF" will be sent out through serial port at the baud rate of 115200 immediately after SIM908 is powered on. The string shall be ignored since it is used for synchronization with PC tool. Only enter AT Command through serial port after SIM908 is powered on and Unsolicited Result Code "RDY" is received from serial port.

This means that before you send anything, you have to discard this data by reading it. I guess this is why you don't get CRLF when reading the response: you first get the HEX string or "RDY".

Then readBytesUntil() reads as many bytes as available (maxi 199 in my example above), stores them in the buffer. It stops reading when it encounters the byte 13 (ieCR). There is no need to loop on an index. The function returns the number of chars that could be read, and it doesn't put an ending 0 at the end of the buffer (ie no valid C string). If you want to use the function in another way than what I proposed, you must store the length returned, because you have no other way to find it out later on.

It's very interresting what you show me. Here is how I adapt my code

I adapted my code and by the way I created a file for testing Serail while we send a AT command. The concern function are loop() and read_AT_string(). (I renamed the read_String to read_AT_string().

Here my code and I explain, after the issue, regardin your proposal

#include <SoftwareSerial.h>

int baud_rate = 9600;
int pin_gsm = 3;
int pin_gps = 4;
int pin_power = 5;
//int pin_dtr = 6;
boolean debug = true;
boolean raedy_to_go = false;

// Reading String
#define BUFFERSIZE 200
char buffer[BUFFERSIZE];
char inChar;
int index;

void setup()
{
  Serial.begin(baud_rate);
  delay(5000);                         // Wait for 5sec after begin

  if(debug)
  {
    Serial.println(F("\n****************************"));
    Serial.println(F("STARTING SYSTEM Read AT stream"));
    Serial.println(F("******************************"));
  }
  pinMode(pin_gsm,OUTPUT);            // Set the pins
  pinMode(pin_gps,OUTPUT);
  pinMode(pin_power,OUTPUT);

  powerUpSim908:
  if(powerUpSim908())
  {
    delay(1000);

    if(gps_power()){

      gsm_enable();
      raedy_to_go = true;

      if(debug)
      {
        Serial.println(F("\n****************************"));
        Serial.println(F("READY TO GO\n"));
        Serial.println(F("****************************\n"));
      }  
    }
    else
    {
      raedy_to_go = false;
      if(debug)
      {
       Serial.println(F("\nNOT READY TO GO.\nGPS could not be power\nRestart the module\nor/and check the battery level.\n"));
      }
      goto powerUpSim908;
    }
  }
  else
  {
    raedy_to_go = false;
    if(debug)
    {
      Serial.println(F("\nNOT READY TO GO.\nCheck the battery level.\n"));
    } 
  };
}

void loop()
{
  /*
   if (Serial.available())
   {
     Serial.print("Character received: ");
     Serial.write(Serial.read());
     Serial.println("");
   }
   */
    if(raedy_to_go)
    {

       read_AT_string("AT",5000);
       delay(10000);

    }  

}

char read_AT_string(char* command, int timeout)
{
  unsigned long previous;
  previous = millis();


  Serial.println(F("\nDISPLAY BUFFER:"));
  index=0;

  Serial.println(command);
  do
  {
    if(Serial.available() > 0) // Don't read unless
    // there you know there is data
    {
      Serial.println("1");
      if (Serial.peek() == 13)           // check if CR (without reading)
      {      
        Serial.println("13");
        if(Serial.available() > 0)
        {
        Serial.read();                // read and ignore 
        if (Serial.peek()==10)        // then check if LF (without reading)
         {
           Serial.println("10");
           if(index < Serial.readBytesUntil(13, buffer, BUFFERSIZE-1))   // One less than the size of the buffer array
            {
              Serial.println("b");
              inChar = Serial.read();  // Read a character
              buffer[index] = inChar;  // Store it
              index++;                 // Increment where to write next
              buffer[index] = '\0';    // Null terminate the string
            }
          }
         }
      }
    }
  }while(((millis() - previous) < timeout));

  Serial.println(buffer);
  buffer[0]='\0';
  Serial.println(F("END DISPLAY BUFFER"));
}

/* FUNCTION */

boolean powerUpSim908(void)
{
  if(debug)
  {
    Serial.println(F("Powering up SIM908"));  
  }
  boolean turnedON = false;
  //uint8_t answer=0;
  int cont;

  for (cont=0; cont<3; cont++)
  {
    digitalWrite(pin_power,HIGH);
    delay(1500);
    digitalWrite(pin_power,LOW);

    Serial.println(F("Checking if the module is up"));
    if(sendATcommand("AT", "OK", 5000))
    {
    cont = 4; // Leave the loop
    turnedON = true;
    }
    else
    {
      turnedON = false;
      if(debug)
      {
    Serial.println(F("\nTrying agin to turn on SIM908"));  
      }
    };
  }

  if(turnedON)
  {
    if(debug)
    {
      Serial.println(F("Module is tunrned up\n"));
    }
  }
  else
  {
      if(debug)
      {
    Serial.println(F("Module is NOT tunrned ON\n"));  
      }
   }    
    return turnedON;
}

boolean sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout)
{
    uint8_t x=0;
    bool answer=false;
    //åchar response[100];
    //buffer[0]='\0';
    unsigned long previous;

    //memset(response, '\0', 100);    // Initialice the string
    //Serial.println(response);

    delay(100);

    while( Serial.available() > 0) Serial.read();    // Clean the input buffer

    if (ATcommand[0] != '\0')
    { 
        Serial.println(ATcommand);    // Send the AT command   
    }

    x = 0;
    previous = millis();

    index=0;
    do
    {
      if(Serial.available() > 0) 
      // there you know there is data
      {
        if(index < BUFFERSIZE-1) // One less than the size of the array // Same as buffer size
        {
          inChar = Serial.read(); // Read a character
          buffer[index] = inChar; // Store it
          index++; // Increment where to write next
          //Serial.println(index);
          buffer[index] = '\0'; // Null terminate the string
        }
      }
    }while(((millis() - previous) < timeout));


    if(strstr(buffer,"NORMAL POWER DOWN") != NULL)
    {
       answer = false;
    }
    else if (strstr(buffer, expected_answer) != NULL)    // check if the desired answer (OK) is in the response of the module
    {

      /*
      Serial.println(F("### BUFFER")); 
      Serial.println(buffer);
      Serial.println(F("### END BUFFER"));
      */
       answer = true;
    }
    else
    {
      answer = false;
    }   

    if(debug)
        {
          if(answer)
          {
            //Serial.println(F("Expected answer : OK!\n"));
          }
          else
          {
            //Serial.println(F("Expected answer : KO!\n"));
          };
  }     
  return answer;
}


void gps_enable(void)
{
  if(debug)
  {
    Serial.println(F("\nEnabling GPS ..."));
  }
  digitalWrite(pin_gps,LOW);                //Enable GPS mode
  digitalWrite(pin_gsm,HIGH);                //Disable GSM mode
  delay(2000);
}



void gsm_enable(void)
{
  if(debug)
  {
    Serial.println(F("\nEnabling GSM ..."));
  }
  digitalWrite(pin_gsm,LOW);                //Enable GSM mode
  digitalWrite(pin_gps,HIGH);               //Disable GPS mode
  delay(2000);
}


/* UTILISTIES */


/* GPS */

boolean gps_power(void)                            //turn on GPS power supply
{
  /*
  Serial.println("AT");  
  delay(2000);
  */

  boolean gpspwr = false;
  boolean gpsrst = false;


  if(sendATcommand("AT+CGPSPWR=1","OK",2000))
  {
    gpspwr = true;
     if(debug)
    {
      Serial.println("turn on GPS power supply => OK");
    }
  }
  else
  {
    if(debug)
    {
      Serial.println("turn on GPS power supply => KO");
    }
  }; 
  //delay(1000);

  if(sendATcommand("AT+CGPSRST=1","OK",2000))
  {
    gpsrst = true;
    if(debug)
    {
      Serial.println("reset GPS in autonomy mode => OK");
    }
  }
  else
  {
    if(debug)
    {
      Serial.println("reset GPS in autonomy mode => KO");
    }
  };   //reset GPS in autonomy mode

  delay(1000);

  if(gpspwr && gpsrst)
  {
    return true;
  }else
  {
    return false;
  }
}

At the read_AT_string, the first if(Serial.peek()==13) always return false.

1 is printed, but '13' is not, then I supposed

if(Serial.peek()==13)

return false

Here is what is printed within 5 sec

AT DISPLAY BUFFER:
1 
1 
1 
1 
1 
1 
1 
1 
1 
[...] // It prints 1 until now 
1

END DISPLAY BUFFER

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM