Perte controle SIM900

Bonjour, je suis entrai de réaliser une alarme maison avec un dialogue via une carte SIM900. Tout semble fonctionner (envoi et réception sms avec traitement associé), mais, de façon aléatoire, il n'y plus de dialogue avec la carte SIM900). l'arduino continue à tourner mais du fait ignore l'arrivée des SMS. Fait troublant, c'est que sur le moniteur serie, il apparait des caractères spéciaux (petit carré). A chaque fois que j'envoie un sms, un petit carré s'ajoute, mais rien de plus. Je pensais que cela pouvait être le moniteur serie de l'IDE qui plantait mais non, sans IDE ca se plante. Cela semble être lié à l'inactivité.
Si quelqu'un pouvant m'aider ça serait vraiment sympa. j'ai réduit mon code au plus simple.

code SMS.txt (3.45 KB)

Tu as oublié de dire comment tout ça était alimenté et branché.

Ok, bonjour, tout est alimenté par une alim 9v 3a, c'est une carte arduino uno, une carte acheté ici : SIM900 GSM GPRS Shield - Maker Advisor

Et la SIM900 est alimentée par le 5V ARDUINO, je suppose ?
Quel ARDUINO ?

Non, elle est alimentée en parrallèle en extérieur, elle sont donc indépendantes.

voici mon code :

/*********
  Complete project details at https://randomnerdtutorials.com
*********/
#include <SoftwareSerial.h>// Configure software serial port
SoftwareSerial SIM900(7, 8);
//Variable to save incoming SMS characters
char incoming_char = 0;
String textMessage = "rien";             // Variable réception des SMS
int outputPower = 9;            // Commande mise sous tension carte GSM


void setup() {
  // Arduino communicates with SIM900 GSM shield at a baud rate of 19200
  // Make sure that corresponds to the baud rate of your module

  Serial.begin(19200);
  // Give time to your GSM shield log on to network
  /********************************/
  /* Mise sous tension carte GSM  */
  /********************************/
  digitalWrite(outputPower, HIGH);
  delay(1000);
  digitalWrite(outputPower, LOW);
  delay(1000);

  SIM900.begin(19200);
  // For serial monitor

  delay(20000);
  // AT command to set SIM900 to SMS mode
  SIM900.print("AT\r");
  delay(100);
  SIM900.print("AT + CSCLK = 0\r"); //désactive le mode veille
  delay(100);
  SIM900.print("AT+CMGF=1\r");
  delay(100);
  SIM900.print("AT+CMGL=\"ALL\"\r");
  delay(100);
  // Set module to send SMS data to serial out upon receipt
  SIM900.print("AT+CNMI=2,2,0,0,0\r");
  delay(100);
  sendSMS();
}
void loop() {
  textMessage = "";
  // Display any text that the GSM shield sends out on the serial monitor
  while (SIM900.available() > 0) {
    //Get the character from the cellular serial port
    incoming_char = (unsigned char)SIM900.read(); //Print the incoming character to the terminal
    Serial.print(incoming_char);
    textMessage += incoming_char;
    delay(50);
  }
  SIM900.flush();
  if (textMessage.indexOf("Tel1") >= 0) {
    textMessage = textMessage.substring(9, 21);
    textMessage += "\r";
    sendSMS();
  }
  if (textMessage.indexOf("Tel2") >= 0) {
    textMessage = textMessage.substring(9, 21);
    textMessage += "\r";
    sendSMS();
  }
  if (textMessage.indexOf("Tel3") >= 0) {
    textMessage = textMessage.substring(9, 21);
    textMessage += "\r";
    sendSMS();
  }
  if (textMessage.indexOf("Alarmeon") >= 0) {
    textMessage = "Alarme ON";
    textMessage += "\r";
    sendSMS();
  }
  if (textMessage.indexOf("Alarmeoff") >= 0) {
    textMessage = "Alarme OFF";
    textMessage += "\r";
    sendSMS();
  }
  if (textMessage.indexOf("Gsmoff") >= 0) {
    SIM900.print("AT+CPOWD=1\r"); // Arrêt Réseau
    delay(1000);
  }
  delay(2000);
}

void sendSMS() {
  /******************************************/
  /* Procédure d'envois SMS                 */
  /* si Tel2 différent ""                   */
  /* si Tel3 différent ""                   */
  /******************************************/
  // AT command to set SIM900 to SMS mode
  //SIM900.println("AT + CMGS = \"+33685484478\"");
  //Note: pour inclure un " dans une chaine de caractère, il faut utiliser la notation \"
  //digitalWrite(outputCom, HIGH);
  //SIM900.print("AT+CMGF=1\r");
  //delay(100);
  // REPLACE THE X's WITH THE RECIPIENT'S MOBILE NUMBER
  // USE INTERNATIONAL FORMAT CODE FOR MOBILE NUMBERS
  SIM900.println("AT + CMGS = \"+33685484478\"");
  delay(100);
  // REPLACE WITH YOUR OWN SMS MESSAGE CONTENT
  SIM900.println(textMessage);
  delay(100);// End AT command with a ^Z, ASCII code 26
  SIM900.write(26);
  delay(100);
  SIM900.println();
  // Give module time to send SMS
  delay(5000);
  SIM900.flush();
}

Comme c'est un shield, est-tu certain que le module soit vraiment alimenté par l'alim extérieure ?
Je vois une powerkey, des jumpers. Tout cela est-il bien positionné ?

Il faudrait également mesurer la tension. Est-elle stable ?
Apparemment le SIM900 est exigeant côté alimentation.

Sinon, côté code, il y a truc qui me chiffonne : String.
Ce n'est pas vraiment recommandé sur une plateforme ATMEGA328P, à moins qu'il s'agisse d'une MEGA ?

Si c'est une UNO, il vaudrait mieux utiliser un char textMessage, size étant la taille maximale d'un SMS dans ton utilisation.

  textMessage = "";
  // Display any text that the GSM shield sends out on the serial monitor
  while (SIM900.available() > 0) {
    //Get the character from the cellular serial port
    incoming_char = (unsigned char)SIM900.read(); //Print the incoming character to the terminal
    Serial.print(incoming_char);
    textMessage += incoming_char;
    delay(50);
  }
  // ##########
  // à remplacer par 
  // ##########
  int index = 0;
  // Display any text that the GSM shield sends out on the serial monitor
  while (SIM900.available() > 0) {
    //Get the character from the cellular serial port
    incoming_char = (unsigned char)SIM900.read(); //Print the incoming character to the terminal
    Serial.print(incoming_char);
    textMessage[index++] = incoming_char;
    // pourquoi ce délai ?
    // delay(50);
  }

textMessage.indexOf("Tel1") peut être remplacé par strstr(textMessage, "Tel1")
textMessage.substring(9, 21) peut être remplacé par strncpy(buffer, textMessage+9, 12)

buffer est aussi un char[] de la taille nécessaire.

C'est juste un soupçon.

strstr : Page manuel de STRSTR
Attention valeur retournée = NULL si sous-chaîne non trouvée. Ton test >= 0 ne convient pas. Plutôt != NULL.
strncpy : Page manuel de STRCPY

Tout d'abord merci pour votre aide. J'ai modifié le code en supposant que c'était les strings que vous soupçonniez.

J'ai réduit encore mon code à l'essentiel pour mettre en évidence le pB. Ce nouveau code fonctionne même si je ne suis pas convaincu d'utiliser correctement les tableaux, mais il se plante aussi après l'envoi de quelques dizaine de SMS "Tel1". cela fait des semaines que je suis la dessus, je désespère. nb mon alimentation est très stable même si elle est un peu élevée à mon gout 10,7V.

/*********
  Complete project details at https://randomnerdtutorials.com
*********/
#include <SoftwareSerial.h>// Configure software serial port
SoftwareSerial SIM900(7, 8);

char incoming_char = 0;
char textMessage[129];
char textSMS[129]= "HELLO";
char Tel1[13] ;

int outputPower = 9;            // Commande mise sous tension carte GSM


void setup() {
  // Arduino communicates with SIM900 GSM shield at a baud rate of 19200
  // Make sure that corresponds to the baud rate of your module

  Serial.begin(19200);
  // Give time to your GSM shield log on to network
  /********************************/
  /* Mise sous tension carte GSM  */
  /********************************/
  digitalWrite(outputPower, HIGH);
  delay(1000);
  digitalWrite(outputPower, LOW);
  delay(1000);

  SIM900.begin(19200);
  // For serial monitor

  delay(20000);
  // AT command to set SIM900 to SMS mode
  SIM900.print("AT\r");
  delay(100);
  SIM900.print("AT + CSCLK = 0\r"); //désactive le mode veille
  delay(100);
  SIM900.print("AT+CMGF=1\r");
  delay(100);
  SIM900.print("AT+CMGL=\"ALL\"\r");
  delay(100);
  // Set module to send SMS data to serial out upon receipt
  SIM900.print("AT+CNMI=2,2,0,0,0\r");
  delay(100);
  sendSMS();
}
void loop() {
  int index = 0;
  while (SIM900.available() > 0) {
    //Get the character from the cellular serial port
    incoming_char = (unsigned char)SIM900.read(); //Print the incoming character to the terminal
    Serial.print(incoming_char);
    textMessage[index++] = incoming_char;
  }
  SIM900.flush();



  if (strstr(textMessage, "Tel1")) {
    strncpy(textSMS, textMessage + 9, 12);
    textMessage[0] = '\0';  // Permet de considérer que le tableau est vide
    sendSMS();
    textSMS[0] = '\0';  // Permet de considérer que le tableau est vide
  }
  delay(2000);
}

void sendSMS() {
  /******************************************/
  /* Procédure d'envois SMS                 */
  /* si Tel2 différent ""                   */
  /* si Tel3 différent ""                   */
  /******************************************/
  SIM900.println("AT + CMGS = \"+33685484478\"");
  delay(100);
  // REPLACE WITH YOUR OWN SMS MESSAGE CONTENT
  SIM900.println(textSMS);
  delay(100);// End AT command with a ^Z, ASCII code 26
  SIM900.write(26);
  delay(100);
  SIM900.println();
  // Give module time to send SMS
  delay(5000);
  SIM900.flush();
}

C'était juste un soupçon.
Si la carte est une UNO, le peu de mémoire fait que les allocations provoquées par String aboutissent généralement à une fragmentation de la mémoire RAM et à terme à un plantage.

D'autres membres connaissent certainement mieux que moi les SIM800 SIM900.
Je sais qu'ils sont chatouilleux sur la qualité de l'alimentation, sans plus.

Merci en tout cas,

voici une copie de moniteur au plantage : ce sont des petit carré au lieu des points d'interrogation

18:55:20.554 -> >
18:55:20.554 -> +CMGS: 98
18:55:20.600 ->
18:55:20.600 -> OK
19:00:18.702 ->
19:00:18.702 -> +CMT: "+33685484478","","20/01/31,19:00:06+04"
19:00:18.702 -> Tel1
19:00:26.003 -> AT + CMGS = "+33685484478"
19:00:26.050 ->
19:00:26.050 -> > +33685484478
19:00:26.050 ->
19:00:26.050 -> >
19:00:26.050 -> +CMGS: 99
19:00:26.050 ->
19:00:26.050 -> OK
19:00:26.050 -> ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮