Leer Remitente SMS

Hola como están, les consulto sobre como leer correctamente el remitente del sms recibido, ya que uso el siguiente código:

void Remitente_SMS() {
  if (mensaje == "") {
  }
  else {
    String char14 = mensaje;
    uint8_t startPos, endPos;
    startPos = char14.indexOf("\"") + 1;
    endPos = char14.indexOf("\"", startPos);
    Remitente = char14.substring(startPos, endPos);

pero no es el mas preciso...de hecho gral= el primer mensaje no lee el remitente, a partir del segundo después si hay cierta estabilidad..
estuve viendo la librería "Sim800l" Master, y obviamente el código que usa para leer el remitente esta ahi jaja, solo hay que ver como adaptarlo...el código original es:

String Sim800l::getNumberSms(uint8_t index){
  _buffer=readSms(index);
  Serial.println(_buffer.length());
  if (_buffer.length() > 10) //avoid empty sms
  {
    uint8_t _idx1=_buffer.indexOf("+CMGR:");
    _idx1=_buffer.indexOf("\",\"",_idx1+1);
    return _buffer.substring(_idx1+3,_buffer.indexOf("\",\"",_idx1+4));
  }else{
    return "";
  }
}

que invoca tmb a:

String Sim800l::readSms(uint8_t index){
  SIM.print (F("AT+CMGF=1\r")); 
  if (( _readSerial().indexOf("ER")) ==-1) {
    SIM.print (F("AT+CMGR="));
    SIM.print (index);
    SIM.print("\r");
    _buffer=_readSerial();
    if (_buffer.indexOf("CMGR:")!=-1){
      return _buffer;
    }
    else return "";    
    }
  else
    return "";
}

y que tamb usa:

String Sim800l::_readSerial(){
  _timeout=0;
  while  (!SIM.available() && _timeout < 12000  ) 
  {
    delay(13);
    _timeout++;

  }
  if (SIM.available()) {
 	return SIM.readString();
  }
}

mi pregunta es como puedo con eso hacer la función para detectar con precisión el remitente?
lo que hice fue hacer este cambio para adaptarlo a mi código:

    String char13 = mensaje;
    Serial.println(char13.length());
    if (char13.length() > 10) //avoid empty sms
   {
    uint8_t NumSMS=char13.indexOf("+CMGR:");
    NumSMS=char13.indexOf("\",\"",NumSMS+1);
    return char13.substring(NumSMS+3,char13.indexOf("\",\"",char13+4));
  }else{
    return "";
  }

pero me da el siguiente error:

no matching function for call to 'String::indexOf(const char [4], StringSumHelper&)'

que es lo que esta mal en el codigo que me da eses error?

return char13.substring(NumSMS+3,char13.indexOf("\",\"",NumSMS+4));

Va

NumSMS + 4

No

char13 + 4

Edito: ojo que la línea ya la subí corregida, comparala con la de tu código

Perfecto gatul, ahora si, muchas gracias...
igual al dejarlo de esta forma:

void Remitente_SMS() {
  if (mensaje == "") {
  }
   String char13 = mensaje;
    Serial.println(char13.length());
    if (char13.length() > 10) //avoid empty sms
   {
    uint8_t NumSMS=char13.indexOf("+CMGR:");
    NumSMS=char13.indexOf("\",\"",NumSMS+1);
    return char13.substring(NumSMS+3,char13.indexOf("\",\"",NumSMS+4));
    Serial.println(NumSMS);
  }
}

se activan aunque los números no estén agendados, cualquier numero lo activa...

gatul creo que el problema es el tiempo que lee el serial buscando el mensaje, o llenando la variable mensaje.. porque digo esto, porque probé lo siguiente:

void Remitente_SMS() {
  if (mensaje == "") {
  }
  else {
    String char13 = mensaje;
    uint8_t startPos, endPos;
    startPos = char13.indexOf("\"") + 1;
    endPos = char13.indexOf("\"", startPos);
    Remitente = char13.substring(startPos, endPos);
    Serial.println("desde aca");
    Serial.println(char13);
    Serial.println("Fin");
  }
}

el primer texto que envío lo toma incompleto:


en cambio ya después del 1er sms:

pero si este parte del código:

    String char13 = mensaje;
    uint8_t startPos, endPos;
 Serial.println(char13);  ///////  agregándole esta línea

la pongo en el void que llamó a esta función:

  if (rele_on >= 0)
  {
    Remitente_SMS();  aca llamo
    if (Remitente....

asi lo agregué:

  if (rele_on >= 0)
  {
    Remitente_SMS(); 
      String char13 = mensaje;
      uint8_t startPos, endPos;
      Serial.println(char13);
if (Remitente....

es mucho mas preciso, casi nunca falla...
no quiero arriesgar en tratar de explicar el porque, pero consulto, como puedo hacer una pausa para darle un poco mas de tiempo a leer el mensaje? o no es un tema de tiempo?

incluso intente con el código genial que me pasaste para la señal, que creí que debería de funcionar perfecto, pero claro si el mensaje llega incompleto y justo yo buscaba la parte que no salió, daría error...
veo como mejor solución por ahora dejarlo así, y cuando falla, reenviar el sms..

No se, no revisé todo el código, solo te marqué el error por el que no te compilaba ya que fue esa tu consulta.

Saludos

Hola gatul, es problema, después de horas de análisis de prueba y error ajaja, son los tipo de datos...
yo tengo almacenado a los números como char en una estructura, y la comparación la hago contra un string.. como puedo igual los datos para un lado o para otro? o sea o comparo todo char o todo string, correcto?
aca tengo mi dato string a comprar:

    String char13 = mensaje;
    uint8_t startPos, endPos;
    startPos = char13.indexOf("\"") + 1;
    endPos = char13.indexOf("\"", startPos);
    Remitente = char13.substring(startPos, endPos);

con mi estructura char:

struct {
  char Admin[15];
  char User1[15];
  char User2[15];
  char User3[15];
  char Clave[5];
} parametros;

como los puedo igualar?

Por ejemplo

String admin;

// lo que sigue ...

admin = String(parametros.Admin);

Con la salvedad de que el último caracter de parametros.Admin debe ser '\0' porque las String terminan con ese caracter.
O sea, si el número que almacenas ocupa 10 caracteres, el 11avo debe ser '\0'.
Si ocupase los 15 caracteres previstos simplemente defínelo con extensión 16 para poder agregar el terminador.

Te aclaro que googleando "char array to string arduino" lo resolvías, yo se que no es como mi invalorable ayuda pero...

Saludos

Si busque char array, de hecho tengo un ejemplo:

      numberSms = Sim800l.getNumberSms(1);
      numberSms.toCharArray(cnumberSms, numberSms.length());

que usa libreria Dim800l Master, pero a mi no me funcionó...por eso recurrí a tu invalorable ayuda..y la de Surbyte, no voy a dejar de mencionarlo a ver si en el futuro no me contesta mas las consultas :blush:
mi código rudimentario para poder hacer la comparación es este:

     admin = parametros.Admin;     
     int user = admin.indexOf("0");
     AdminSI = admin.substring(user, user+11);
     //Serial.println(AdminSI);

el tuyo es menos código, pero me perdí con el carácter terminador... lo tendría que poner en la instrucción de guardado? como lo debo hacer?

la duda mas recurrente es la de no gastar recursos innecesarios, por eso busco poder achicar y limpiar lo mas que pueda el código, y lograr a la vez que sea mas robusto, preciso...
una de las recomendaciones de Surbyte es que use librerías, pero me es mas difícil, la librería que me pasó es muy buena tiene de todo pero bueno, creo que para empezar a usarlas debería de saber un poco más, sino voy a llenar el foro de consultas yo sola :relaxed:...

edito:
usar librerías, consume recursos? o sea cargar como ·define librerías, como yo podría cargar la que me pasó surbyte para usar algo de esa librería, u otra cualquiera, cargarlas de esa manera y si no se usan quita recursos?

edito 2:
ahora para leer el serial uso este codigo:

void updateSerial()
{
    if(SIM900.available()>0){
       mensaje= SIM900.readString();
       delay(100);
       if (mensaje.indexOf("+CLIP")>-1){
           identifica_Llamada(); 
       //Serial.println("Llamada en curso");
       }
       else if (mensaje.indexOf("+CMT")>-1){
        identifica_SMS();
        //Serial.println("Mensaje en curso");
       }
      Serial.println(mensaje);
     }
    if (Serial.available()){
     while(Serial.available()) {
       inc_call=Serial.read();
        SIM900.write(Serial.read());
     }
   SIM900.println(); 
  }
}
me va mejor, no se pierden los mensajes...
no si se podría incluso mejorar...