Concatenare char

Ciao
Sto' cercando di ottimizzare il codice per mandare dei comandi at ad un modem, volevo concatenare delle stringhe
Vecchi post del forum mi hanno aiutato a con quello sotto e funziona
Quello che volevo adesso e' sostituire la parte

+39mionumero

con un vettore in modo che se in futuro devo aggiornare "+39mionumero" possa farlo all inizio del programma prima del setup()

image

ho provato la funzione strncat( ma senza successo, in certi casi il programma si bloccava ma questo penso sia legato alla dimensione del programma
Grazie in anticipo

 //sezione sms
      Modem.print("AT+CMGS=\"+39mionumero\"");
      Modem.write(13);  // \r
      delay(100);

      Modem.print("rilevata presenza");  //SMS 1 inserisci tuo testo
      //Modem.write(13); // \r

      delay(100);

      //Modem.print(char(26)); // CTRL Z

      Modem.println(char(26));  // CTRL .3|Z per spedire

      //Modem.write(27);  // ESC per abortire

      Modem.write(13);

      delay(100);

      ReadModem();

      Serial.println("SMS done");

Il programma è stato inserito male, prova a controllare e editare il tuo post perché c'è solo una parte.
Inoltre non è chiara la tua richiesta, se vuoi usare un vettore cablato nel programma quando cambierai numero dovrai comunque riprogrammare la scheda quindi non ti servirà utilizzare la strncat.
In ogni caso la lunghezza del programma non è mai la causa di blocchi, il programma in un micro o ci sta o non ci sta e se ci sta allora anche se utilizzi tutto lo spazio "programma" allora funzionerà come un programma con due sole istruzioni.
Può essere che utilizzando (poco bene) la strncat su un array troppo piccolo per contenere il risultato tu vada a scrivere in aree di memoria di altri dati e quindi da li il blocco.
Senza il programma non si può dire di più, almeno io non ho altro da aggiungere :slight_smile:

Non è una buona idea concatenare le stringhe da soli per inviarle sulla porta seriale. In ogni caso, i byte vengono inviati in un buffer ed emessi uno per uno.

Non fate

Modem.print("AT+CMGS=\"+39mionumero\""); // bug !

ma fate piuttosto:

Modem.print(F("AT+CMGS=\"+39"));
Modem.print(mionumero);
Modem.print(F("\""));

Così risparmierete memoria ed è trasmesso sulla UART allo stesso modo.

Ciao

il programma e' solo un elenco di case

/*
v57
per testare i comandi AT
*/

//comunicazione con modem GSM
#include <AltSoftSerial.h>  // AltSoftSerial - Version: Latest rx 8 tx 9
AltSoftSerial Modem;        // pin 8 arduino -> Modem TX Pin, pin 9 arduino -> Modem RX Pin

char incoming_char;
char stringOne[70] = " ";
char substringa[50] = " ";
char response[50] = " ";

char creg[] = "0,1";  //risposta modem registrato

char PhoneNumber1[] = "ATD+39mionumero;";
char PhoneNumber2[] = "ATD+39xxx22;\r\n";
char PhoneNumber3[] = "ATD+39xxx33;\r\n";
char PhoneNumber4[] = "ATD+39xxx44;\r\n";

char SMSPhoneNumber1[] = "+39mionumero";

char casoSingolo[] = " ";

int comando;

byte i, j, k;  //contatore

void setup() {

  delay(100);

  Serial.begin(9600);  //Initialize serial ports for communication.

  Modem.begin(9600);  //Initialize serial ports for communication.

  i = 0;
  j = 0;
  k = 0;

  comando = 0;

  Serial.println("inizio programma");  //stampa di controllo

  delay(1000);
}

void loop() {

  ReadSerial();
  ReadModem();

  delay(1000);

  switch (casoSingolo[0]) {
      // case '1':
      //   Serial.println("caso 1 Manufacturer identification +CGMI");
      //   Serial.println("AT+CGMI");
      //   Serial.println("scrivo sul modem");

      //   Modem.print("AT+CGMI;");
      //   Modem.write(13);  //\r
      //   Modem.write(10);  //\n

      //   delay(100);

      //   ReadModem();

      //   memset(casoSingolo, 0, sizeof(casoSingolo));

      //   comando = 0;
      //   break;

      // case '2':
      //   Serial.println("caso 2 Request model identification +CGMM");
      //   Serial.println("AT+CGMM");
      //   Serial.println("scrivo sul modem");

      //   Modem.print("AT+CGMM;");
      //   Modem.write(13);  //\r
      //   Modem.write(10);  //\n

      //   delay(50);

      //   ReadModem();
      //   memset(casoSingolo, 0, sizeof(casoSingolo));

      //   break;

      // case '3':
      //   Serial.println("caso 3 Product Serial Number +CGSN");
      //   Serial.println("AT+CGSN");
      //   Serial.println("scrivo sul modem");

      //   Modem.print("AT+CGSN;");
      //   Modem.write(13);  //\r
      //   Modem.write(10);  //\n

      //   delay(50);

      //   ReadModem();

      //   memset(casoSingolo, 0, sizeof(casoSingolo));
//memset(stringOne, 0, sizeof(stringOne));

      //   break;

      // case '4':
      //   Serial.println("caso 4 Card Identification +CCID");
      //   Serial.println("AT+CCID;");
      //   Serial.println("scrivo sul modem");

      //   Modem.print("AT+CCID");
      //   Modem.write(13);  //\r
      //   Modem.write(10);  //\n

      //   delay(50);

      //   ReadModem();

      //   memset(casoSingolo, 0, sizeof(casoSingolo));
//memset(stringOne, 0, sizeof(stringOne));

      //   break;

      // case '5':
      //   Serial.println("caso 5 Phone activity status +CPAS");
      //   Serial.println("AT+CPAS");
      //   Serial.println("scrivo sul modem");

      //   Modem.print("AT+CPAS;");
      //   Modem.write(13);  //\r
      //   Modem.write(10);  //\n

      //   delay(50);

      //   ReadModem();

      //   memset(casoSingolo, 0, sizeof(casoSingolo));
//memset(stringOne, 0, sizeof(stringOne));

      //   break;

      // case '6':
      //   Serial.println("caso 6 Hang-Up command H");
      //   Serial.println("ATH");
      //   Serial.println("scrivo sul modem");

      //   Modem.print("ATH;");
      //   Modem.write(13);  //\r
      //   Modem.write(10);  //\n

      //   delay(50);

      //   ReadModem();
      //   memset(casoSingolo, 0, sizeof(casoSingolo));
//memset(stringOne, 0, sizeof(stringOne));

      //   break;

    case '7':
      Serial.println("caso 7 Signal Quality +CSQ");
      Serial.println("AT+CSQ");
      Serial.println("scrivo sul modem");

      Modem.print("AT+CSQ;");
      Modem.write(13);  //\r
      Modem.write(10);  //\n

      delay(50);

      ReadModem();

      //estraggo parti dalla la stringa

      for (j = 16; j <= 17; j++) {

        response[k] = stringOne[j];

        k++;
      }

      Serial.print("response ");  //stampa di controllo
      Serial.println(response);   //stampa di controllo

      Serial.println();

      Serial.print("RSSI ");           //stampa di controllo
      Serial.println(atoi(response));  //stampa di controllo

      if (atoi(response) >= 11 && atoi(response) <= 30) {
        Serial.println("Segnale RSSI sufficente");
      } else {
        Serial.println("Segnale RSSI insufficente");
      }

      Serial.println();
      Serial.println("This command returns the received signal strength (rssi) and the channel bit error rate (ber)");
      Serial.println("0-10 not ok");              //stampa di controllo
      Serial.println("11-31 ok");                 //stampa di controllo
      Serial.println("32-98 not defined");        //stampa di controllo
      Serial.println("99 no measure available");  //stampa di controllo
                                                  /*
This command returns the received signal strength (rssi) and the channel bit error rate (ber).
  Value	RSSI dBm	Condition
2	-109	Marginal
3	-107	Marginal
4	-105	Marginal
5	-103	Marginal
6	-101	Marginal
7	-99	Marginal
8	-97	Marginal
9	-95	Marginal
10	-93	OK
11	-91	OK
12	-89	OK
13	-87	OK
14	-85	OK
15	-83	Good
16	-81	Good
17	-79	Good
18	-77	Good
19	-75	Good
20	-73	Excellent
21	-71	Excellent
22	-69	Excellent
23	-67	Excellent
24	-65	Excellent
25	-63	Excellent
26	-61	Excellent
27	-59	Excellent
28	-57	Excellent
29	-55	Excellent
30	-53	Excellent
  */

      Serial.println();

      i = 0;  //azzero contatore
      k = 0;  //azzero contatore

      memset(casoSingolo, 0, sizeof(casoSingolo));
      memset(response, 0, sizeof(response));  //svuoto vettore
memset(stringOne, 0, sizeof(stringOne));

      break;

    case '8':
      Serial.println("caso 8 Network registration +CREG");
      Serial.println("AT+CREG?");

      Modem.print("AT+CREG?;");
      Modem.write(13);  //\r
      Modem.write(10);  //\n

      delay(50);

      ReadModem();

      //estraggo parti dalla la stringa

      for (j = 19; j <= 22; j++) {

        response[k] = stringOne[j];

        k++;
      }

      Serial.println();

      Serial.println("+CREG response");  //stampa di controllo
      Serial.println(response);          //stampa di controllo

      if (strncmp(response, creg, 3) == 0) {
        Serial.println("dispositivo registrato in rete");
      } else {
        Serial.println("dispositivo non registrato in rete");
      }

      i = 0;  //azzero contatore
      k = 0;  //azzero contatore

      memset(casoSingolo, 0, sizeof(casoSingolo));
      memset(response, 0, sizeof(response));  //svuoto vettore
memset(stringOne, 0, sizeof(stringOne));

      break;

      // case '9':
      //   Serial.println("caso 9 Network registration +CPIN");
      //   Serial.println("AT+CPIN");

      //   Modem.print("AT+CPIN?;");
      //   Modem.write(13);  //\r
      //   Modem.write(10);  //\n

      //   delay(50);

      //   ReadModem();

      //   memset(casoSingolo, 0, sizeof(casoSingolo));
//memset(stringOne, 0, sizeof(stringOne));

      //   break;

      case 'a':
        Serial.println("caso a Dial command D IT");
        Serial.println("ATD IT");

        //----------------------------------------------chima il 1mo numero

        Modem.print("ATD+39mionumero;");
        Modem.write(13);
        Modem.write(10);

        delay(50);

        ReadModem();

        memset(casoSingolo, 0, sizeof(casoSingolo));
memset(stringOne, 0, sizeof(stringOne));

        break;

      // case 'e':
      //   Serial.println("caso e AT+CMGF configre the text mode");
      //   Serial.println("AT+CMGF?");

      //   Modem.print("AT+CMGF?");
      //   Modem.write(13);
      //   Modem.write(10);

      //   delay(50);

      //   ReadModem();

      //   memset(casoSingolo, 0, sizeof(casoSingolo));
//memset(stringOne, 0, sizeof(stringOne));

      //   break;

    case 'f':
      Serial.println("caso f AT+CMGS Send message");
      Serial.println("AT+CMGS");

      //--------------------------------------------------SMS al 1mo numero

      Modem.print("AT+CMGF=1;");
      Modem.write(13);
      Modem.write(10);

      delay(50);

      ReadModem();

      Modem.print("AT+CMGF?;");
      Modem.write(13);
      Modem.write(10);

      delay(50);

      ReadModem();

      delay(50);

      //sezione sms

      //char SMS[] = "AT+CMGS=", sms2[] = {SMSPhoneNumber1};

      //strcat(SMS, sms2);

      Modem.print("AT+CMGS=\"+393385078535\"");

      //Modem.println("AT+CMGS=\SMSPhoneNumber1\"");

      //Modem.println(SMS);

      Modem.write(13);  // \r

      delay(100);

      Modem.print("rilevata presenza");  //SMS 1 inserisci tuo testo

      delay(100);

      //Modem.print(char(26)); // CTRL Z
      Modem.println(char(26));  // CTRL .3|Z per spedire
      //Modem.write(27);  // ESC per abortire
      Modem.write(13); // \r

      delay(100);

      ReadModem();

      Serial.println("SMS done");

      memset(casoSingolo, 0, sizeof(casoSingolo));
memset(stringOne, 0, sizeof(stringOne));

      break;

    default:
      Serial.println("Not a valid command/waiting for a comand");
  }
  delay(1000);
}

void ReadModem() {

  memset(stringOne, 0, sizeof(stringOne));
  i = 0;

  Serial.println("ReadModem()");  //stampa risposta modem

  delay(500);

  //while a character is coming from the Modem
  while (Modem.available() > 0) {

    incoming_char = Modem.read();  //Get the character from the Modem port.
    stringOne[i] = incoming_char;  //compone la stringa
    i++;

    delay(50);
  }

  Serial.println("stringOne");  //stampa risposta modem
  Serial.println(stringOne);    //stampa risposta modem

  //memset(stringOne, 0, sizeof(stringOne));
}

void ModemCRLF() {
  Modem.write(13);
  Modem.write(10);
}

void ReadSerial() {

  i = 0;

  //while a character is coming from the Serial
  while (Serial.available() > 0) {

    incoming_char = Serial.read();  //Get the character coming from the terminal
    casoSingolo[i] = incoming_char;

    Serial.println("incoming_char");
    Serial.println(incoming_char);

    i++;

    delay(50);
  }

  if (i > 0) {

    Serial.println("casoSingolo");
    Serial.println(casoSingolo);

    //comando = atoi(casoSingolo);

    //Serial.println("comando");
    //Serial.println(comando);
  }
}

Si ma non c'è la parte dove usi l'strncat. Se non ci mostri cosa hai implementato in tal senso difficile dire cosa è errato e che porta ai blocchi

Concordo con quanto già suggerito da @J-M-L

Non c'è alcun vantaggio (anzi solo svantaggi) nel concatenare le stringhe solo per poi inviarle.

@fabpolli
Si c'è ma non si vede.

case 'f':
      Serial.println("caso f AT+CMGS Send message");
      Serial.println("AT+CMGS");

      //--------------------------------------------------SMS al 1mo numero

      Modem.print("AT+CMGF=1;");
      Modem.write(13);
      Modem.write(10);

      delay(50);

      ReadModem();

      Modem.print("AT+CMGF?;");
      Modem.write(13);
      Modem.write(10);

      delay(50);

      ReadModem();

      delay(50);

      //sezione sms          // GUARDA QUI

      //char SMS[] = "AT+CMGS=", sms2[] = {SMSPhoneNumber1};

      //strcat(SMS, sms2);

      Modem.print("AT+CMGS=\"+393385078535\"");

      //Modem.println("AT+CMGS=\SMSPhoneNumber1\"");

      //Modem.println(SMS);

      Modem.write(13);  // \r

      delay(100);

      Modem.print("rilevata presenza");  //SMS 1 inserisci tuo testo

      delay(100);

      //Modem.print(char(26)); // CTRL Z
      Modem.println(char(26));  // CTRL .3|Z per spedire
      //Modem.write(27);  // ESC per abortire
      Modem.write(13); // \r

      delay(100);

      ReadModem();

      Serial.println("SMS done");

      memset(casoSingolo, 0, sizeof(casoSingolo));
memset(stringOne, 0, sizeof(stringOne));

      break;

Già ti ha risposto @J-M-L.
La variabile mionumero sarà una c string es:

char mionumero[] = "3228125544";

Nota: F() su ESP mi pare non serva.
Se in questo case o altro vuoi selezionare un numero di telefono da un elenco durante l'esecuzione puoi indicizzare i numeri di telefono come segue:

char *numeritelefono[] = {
        "3254851110",
        "3254851111",
        "3254851112"
};

Ora il codice di @J-M-L diventa:

byte idx = 0;    // indice 
Modem.print(F("AT+CMGS=\"+39"));
Modem.print(numeritelefono[idx]);
Modem.print(F("\""));

Se l'elenco dei numeri di telefono sono costanti andrebbero dichiarate const, es: const char *numeritelefono[] ecc come mostrato in questo post:Cocncatenare char - #9 by J-M-L.
Questo forse su ESP li salva in flash e non in ram per cui si risparmia ram, ma di questo non sono certo. certo per me vuole dire che non ho verificato.

Altro discorso per la concatenazione di c string che se ti serve ancora per altri motivi chiedi specificamente: come si usa strncat?

Ciao.

L'avevo visto ma se l'OP scrive che usa strncat e poi non lo usa e usa strcat...
Concordo anche con le varie opzioni fornite, semplicemente volevo portare l'OP ad utilizzare in modo corretto la funzione richiesta

const char *numeritelefono[] = {
        "3254851110",
        "3254851111",
        "3254851112"
};

Scusa non avevo visto che gli mancava la n. Se lo ritieni opportuno puoi ancora perseguire il tuo intento che male non fa anche a me. Sai una rinfrescata a ciò che uso raramente può solo farmi bene.

Ciao.

hai ragione
grazie molti spunti per uno come me sono manna

testo i suggerimenti e aggiorno

grazie ancora

char SMS[] = "AT+CMGS=", sms2[] = {SMSPhoneNumber1};
strcat(SMS, sms2)

Comunque tolto o meno l'uso di strncat (più sicuro di strcat) il succo non cambia, il vettore di destinazione (SMS in questo caso) deve avere una lunghezza tale da poter ospitare tutto il contenuto facendo:

char SMS[] = "AT+CMGS="

Vai a definire un array con un numero di elementi con dimensione tale da contenere la stringa che usi per inizializzarlo (9 caratteri nel tuo caso perché bisogna sempre considerare il terminatore), va da se che se tu ci concateni qualcosa vai a scrivere in area di memoria di qualcos'altro.
Devi provare a cambiare approccio (anche se in questo caso è più utile seguire i suggerimenti che hanno fornito gli altri) ovvero:

  1. Definire un array con una dimensione fissa che possa contenere tutte le stringhe che vorrai inserirvi (con il terminatore)
  2. Inserirvi la prima stringa (strcpy)
  3. Concatenare con la seconda parte del testo
    Il punto tre lo puoi ovviamente ripetere per tutto quanto vuoi concatenare.

Ciao

ho seguito i suggerimenti, questo sotto funziona

 Modem.print(F("AT+CMGS=\""));
    Modem.print(SMSPhoneNumber1);
    Modem.print(F("\""));
    Modem.write(13);  // \r

image

provo anche la forma matriciale suggerita, che mi piace molto perche' non voglio, in generale, andare in giro per il programma a modificare valori

grazie e' stato un utile esercizio per i prossimi progetti a per qualcuno precedente che voglio tornare a modificare in questo senso

La butto li, quel numero è possibile memorizzarlo in un unsigned long, risparmiando un bel pò di memoria (4 byte invece di 11 byte per ogni numero)
Bisogna solo provare se la print() della libreria AltSoftSerial stampa per bene gli UL (se capisce che non c'e' segno)

In questo caso cambia solo la dichiarazione, il modo di usarlo non cambia.

const uint32_t numeritelefono[] = {
        3254851110,
        3254851111,
        3254851112
};

Perché non eredita la classe Print?

Ciao.

Si... PrintStreamAltSoftSerial

Si, ma non sò se la Print ha tutti gli overload, non vorrei prendesse UL come L e quindi stampa numero negativo ?!?

1 Like

ciao
sotto il programma finale funzionanate
ho commentato il millis()
grazie al suppporto il programma e' compatto e facile da aggiornare con nuovi numeri

/*
25
effettua una chiamata
allarme capannone
un sensore pir
una sirena 

modem simcom 7600G H
allarme 
effettua una chiamata
manda un SMS
utilizza:
un sensore pir
una sirena     

1. Text Mode: 
"REC UNREAD" received unread message (i.e. new message) 
"REC READ" received read message 
"STO UNSENT" stored unsent message 
"STO SENT" stored sent message 
"ALL" all messages

AT+CMGR=1 
+CMGR: "REC UNREAD"
*/

#include <AltSoftSerial.h>  // AltSoftSerial - Version: Latest rx 8 tx 9
AltSoftSerial Modem;        // pin 8 arduino -> Modem TX Pin, pin 9 arduino -> Modem RX Pin

#define LedRete 13      //rosso per visualizzare stato della registrazione alla rete
#define LedSegnale 12   //rosso per visualizzare stato del livello del segnale
#define PinSirena 11    //verde collegato a rele sirena
#define LedChiamata 10  //verde indicazione chiamata in corso

char incoming_char;
char ModemMsg[200] = " ";
char substringa[50] = " ";
char response[] = " ";

char creg[] = "0,1";

char *PhoneNumber[] = {
  "+39num1",  
  "+39num2",  
  "+39num3", 
  "+39num4",  
  "+39num5",  
  "+39num6"   
};


const char SMSMsg[] = "rilevata presenza";

char casoSingolo[] = " ";

int comando;

byte i, j, k, idx;  //contatore

unsigned long previousMillis;  // will store last time
long sampling_delay;           //intervallo di campionamento

//sezione sensore pir
const byte interruptPin = 2;  //pin dell interrrupt
volatile byte state = 0;      //stato iniziale della variabile

void setup() {

  Serial.begin(9600);  //Initialize arduino serial ports for communication

  //gsm Modem
  Modem.begin(9600);  //Initialize Modem serial ports for communication

  pinMode(LedRete, OUTPUT);
  digitalWrite(LedRete, LOW);

  pinMode(PinSirena, OUTPUT);
  digitalWrite(PinSirena, LOW);

  pinMode(LedChiamata, OUTPUT);
  digitalWrite(LedChiamata, LOW);  //indicazione chiamata in corso

  //sezione sensore pir
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), PIRevent, RISING);

  //memset(ModemMsg, 0, sizeof(ModemMsg));
  //memset(substringa, 0, sizeof(substringa));

  //sezione verifica registrazione in rete prima di entrare nel loop
  do {
    delay(1000);

    Serial.println();
    Serial.println();
    Serial.println("sono nel SETUP");
    Serial.println();
    Serial.println();

    Serial.println("Network registration +CREG");
    Serial.println("AT+CREG?");

    Modem.print("AT+CREG?;");
    Modem.write(13);  //\r
    Modem.write(10);  //\n

    delay(50);

    ReadModem();

    //estraggo parti dalla la stringa
    k = 0;

    for (j = 19; j <= 21; j++) {

      response[k] = ModemMsg[j];

      // Serial.print(k);
      // Serial.print('\t');
      // Serial.println(response[k]); //stampa di controllo

      k++;
    }

    Serial.println();

    Serial.println("+CREG response");  //stampa di controllo
    Serial.println(response);          //stampa di controllo

    if (strncmp(response, creg, 3) == 0) {
      Serial.println("dispositivo registrato in rete");
      digitalWrite(LedRete, HIGH);  //indicazione per registrazione in rete
    } else {
      Serial.println("dispositivo non registrato in rete");
      digitalWrite(LedRete, LOW);  //indicazione per registrazione in rete
    }

    memset(response, 0, sizeof(response));  //svuoto vettore

  } while (response[2] != '1');

  Modem.print("AT+CVHU=0");  //comando parametro per utilizzare ATH
  Modem.write(13);           // \r
  Modem.write(10);           // \n

  delay(50);

  ReadModem();

  sampling_delay = 10000;  //millis intervallo di verifica
  previousMillis = 0;

  idx = 0;

  Serial.println("inizio programma");
}

void loop()  //programma principale
{
  Serial.println();
  Serial.println();
  Serial.println("sono nel LOOP");
  Serial.println();
  Serial.println();

  //if (millis() - previousMillis >= sampling_delay) {
  //  previousMillis = millis();  //save the last time

  Modem.print("AT+CSQ;");  //controllo livello segnale GSM
  ModemCRLF();             // \r\n

  ReadModem();  //per leggere messaggi dal modem

  //estraggo le informazioni dalla stringa
  k = 0;

  for (j = 16; j <= 17; j++) {

    response[k] = ModemMsg[j];

    k++;
  }

  Serial.print("response ");  //stampa di controllo
  Serial.println(response);   //stampa di controllo

  Serial.print("RSSI ");           //stampa di controllo
  Serial.println(atoi(response));  //stampa di controllo

  if (atoi(response) >= 11 && atoi(response) <= 30) {
    Serial.println("Segnale RSSI sufficente");
    digitalWrite(LedSegnale, HIGH);  //indicazione livello segnale
  } else {
    Serial.println("Segnale RSSI insufficente");
    digitalWrite(LedSegnale, LOW);  //indicazione livello segnale
  }

  Serial.println("This command returns the received signal strength (rssi) and the channel bit error rate (ber)");
  Serial.println("0-10 not ok");              //stampa di controllo
  Serial.println("11-31 ok");                 //stampa di controllo
  Serial.println("32-98 not defined");        //stampa di controllo
  Serial.println("99 no measure available");  //stampa di controllo

  //sezione PIR rilevato evento
  if (state == 1) {

    Serial.println(SMSMsg);

    Serial.println("accendo sirena");
    digitalWrite(PinSirena, HIGH);  //sirena ON

    //----------------------------------------------chimata al numero

    Serial.println("Dial command D IT");
    Serial.println("ATD IT");

    digitalWrite(LedChiamata, HIGH);  //indicazione chiamata in corso

    Modem.print(F("ATD"));
    Modem.print(PhoneNumber[idx]);
    //Modem.print(F("\""));
    Modem.print(";");
    Modem.write(13);  // \r
    Modem.write(10);  // \n

    ReadModem();

    Serial.println("dial done");

    delay(20000);  //durata della chiamata

    Serial.println("chiudo chiamata");  //stampa di controllo

    digitalWrite(LedChiamata, LOW);  //indicazione chiamata in corso

    Modem.print("ATH");  //chiude chiama 1
    ModemCRLF();         // \r \n

    //memset(ModemMsg, 0, sizeof(ModemMsg));  //svuoto messaggi modem

    ReadModem();

    Serial.println("spengo sirena");
    digitalWrite(PinSirena, LOW);  //sirena OFF

    //--------------------------------------------------SMS al numero

    Modem.print("AT+CMGF=1;");
    Modem.write(13);
    Modem.write(10);

    ReadModem();

    Modem.print("AT+CMGF?;");
    Modem.write(13);
    Modem.write(10);
    ReadModem();

    //sezione sms

    //dal forum
    // [quote="J-M-L, post:3, topic:1264554"]
    // ```
    // Modem.print(F("AT+CMGS=\"+39"));
    // Modem.print(PhoneNumber[idx]);
    // Modem.print(F("\""));
    // ```
    // [/quote]

    Modem.print(F("AT+CMGS=\""));
    Modem.print(PhoneNumber[idx]);
    Modem.print(F("\""));
    Modem.write(13);  // \r

    delay(100);

    Modem.print(SMSMsg);  //SMS testo
    //Modem.write(13); // \r

    delay(100);

    Modem.write(26);  // CTRL Z
    //Modem.println(char(26));  // CTRL Z per spedire
    //Modem.write(27);  // ESC per abortire
    Modem.write(13);

    ReadModem();

    Serial.println("SMS done");

    idx++;

    if (idx == 6) {
      state = 0;  // per evitare le continue chiamate
      idx = 0;
    }
  }
  //}
  delay(5000);
}
//fine loop


//----------------------------------------------------------------------------functions

//sensore PIR
void PIRevent() {
  state = 1;  //HIGH quamdo il pir rileva una presenza
}

//scrive messaggi ricevuti dal Modem
void ReadModem() {

  Serial.println("ReadModem()");  //stampa risposta modem

  delay(500);

  memset(ModemMsg, 0, sizeof(ModemMsg));  //svuoto vettore
  i = 0;                                  //azzero contatore

  //while a character is coming from the Modem
  while (Modem.available() > 0) {

    delay(100);

    incoming_char = Modem.read();  //Get the character from the Modemular serial port.
    ModemMsg[i] = incoming_char;   //compone la stringa

    //Serial.print(incoming_char);  //Print the incoming character to the terminal.
    // Serial.println(ModemMsg);  //stampa di controllo

    i++;
  }
  Serial.println(ModemMsg);  //stampa di controllo
  delay(50);
}


void ModemCRLF() {
  Modem.write(13);  // \r
  Modem.write(10);  // \n
  //oppure
  //Modem.print(char(13)); // \r
  //Modem.print(char(10)); // \n
}

puoi semplificare un po' il codice

    Modem.println"AT+CREG?;");

perché println() aggiunge \r e \n per te