Problema di memoria o altro - arduino nano con GSM, GPS, wire library [RISOLTO]

Sto lavorando a questo progetto da oltre 3 mesi, direi pure 5. Ho concluso praticamente il 95% di tutte le attività ed ho avviato la fase di test.

Il progetto prevede l'utilizzo di 3 arduino nano installati su una motocicletta di ultima generazione che hanno il compito di fare quanto segue:

  1. Arduino "Windshield"
    gestisce il parabrezza elettrico, lo sale e lo scende pilotando dei relè. Inoltre a questo arduino è collegato un sensore hall per il calcolo della velocità della ruota per gestire in parabrezza elettrico in funzione dalla velocità. Lavora con gli interrupts.
    Questo arduino è collegato con gli altri tramite bus I2C con un cavo a bassissima impedenza e resistenze di pull-up da 2,5 KOhm.

  2. Arduino "Accelorometer"
    gestisce il faro posteriore e lo fa lampeggiare tramite un mosfet in funzione della decelerazione calcolata tramite un accelerometro. Inoltre calcola anche l'imbarcata in caso la moto è piegata oltremodo ovvero contro le forze fisiche (non lo voglio scrivere... ma significa se fosse a terra...). E' collegato all'arduino che gestisce il GPS e l'GSM tramite I2C ma anche direttamente ed attiva gli SMS di emergenza e di frenata di emergenza.

  3. Arduino GSM e GPS
    Ha un GPS ed un GSM collegati e gestisce tutti i parametri di setup del sistema dei tre arduino (modalità del windshield, parametri del lampeggio luce di frenata, ecc.). Il sistema è concepito in modo che tramite SMS venga inviato un comando e l'arduino interpretandolo può attivare varie procedure. In generale, se il comando è di setup del GPS o GSM gestisce tutto al suo interno e memorizza alcune info sull'EProm, se invece il comando di setup riguarda gli altri arduino allora invia le richiesta via I2C.

Purtroppo è abbastanza complicato descrivere tutti i dettaglio che il sistema fa, tuttavia spero non sia necessario ma a domanda risponderò

Chiaramente il problema è nato quando allestito tutto sulla moto. L'arduino Windshield funziona alla perfezione. L'arduino Accelorometer funziona anch'esso alla perfezione. L'unico problema si sta verificando con il GSM e GPS.

Il GSM è collegato via softserial ed utilizza la libreria Sim800l-master mentre il GPS è collegato sia Serial. Quindi non posso fare un check online con il monitor serial a meno di modificare il codice e togliere il GPS (cosa che comunque ho fatto per capire quanto vi esporrò).

Alcuni pin sono utilizzati per ricevere il comando diretto dall'accelerometer per l'invio di SMS di emergenza.

L'arduino su richiesta può inviare la posizione, i numeri di telefono memorizzati e il completo setup del sistema, oltre gli sms di emergenza.

I problemi che registro sono di due nature diverse ...credo di aver capito. Il primo importante, dopo alcuni invii di sms (mio verso il modulo) in modo random (a volte dopo 1 a volte immediatamente, a volte dopo 5.... siano essi comandi e/o richieste) il sistema non risponde più. Facendo un check credo di aver capito che la stringa che contiene il messaggio viene tagliata.
Il comando che legge il messaggio non restituisce solo il testo ma una stringa che contiene, RTC, stato del messaggio (letto, non letto), numero di telefono ed infine il messaggio stesso per ultimo. Ho visto più di una volta che il modulo non vedendo più all'interno della stringa il codice "A1234" ovviamente non può interpretare il comando dopo tale stringa per come è pensato il sistema. Ho ottimizzato il codice riducendo per quello che sono le mie competenze la memoria utilizzata SRAM ed ho visto che è migliorato tuttavia non risolto. Pertanto penso sia un problema di memoria, dopo un certo numero di sms o non so perché la memoria si satura. Ho visto che ci sono dei metodi per capire l'utilizzo della memoria ma non mi sono serviti a molto forse ho bisogno di qualche dritta in più.

L'altro problema è che inviando sms che richiedono l'invio sul bus di comandi il sistema si pianta. Anche qui assolutamente random. Funziona a dovere (sembrerebbe) con l'arduino accelerometer che è a 2 cm e non con quello a 1.5 metri che è il windshield.

Questo è meno importante però perché potrebbe sempre dipendere dal primo.....

Vi posto il codice chiedendovi come modificarlo per ottimizzare eventualmente la gestione delle variabili e quindi la memoria e poi come implementare controllare che non si saturi...

Il codice non mi permette di metterlo (>9000 caratteri)

Provo a suddividerlo:

Setup e Loop

#include <EEPROM.h> 
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <Sim800l.h>
#include <Wire.h>

Sim800l Sim800l;
TinyGPSPlus gps;

int Pin_SMS_frenata=4;
int Pin_SMS_emergenza=5;

int Device_Accelerometer=9;
int Device_Windshield=8;

double Time_GSM=0;
double Time_GPS=0;
double Time_Allarm=0;
boolean OkSMS=true;
boolean OkGPS=true;
boolean OkAllarm=false;
boolean SMS_sent=false;
boolean SMS_sent_break=false;
String GPS_location="";

char num_cell[20];

byte cmd;
 
void setup() {
  Wire.begin();
  pinMode(Pin_SMS_emergenza, INPUT);
  pinMode(Pin_SMS_frenata, INPUT);
  Serial.begin(9600);
  Sim800l.begin();



setup_system();

}

 
void loop() { 


if(OkSMS) {
  if(digitalRead(Pin_SMS_emergenza)==HIGH && !SMS_sent) {
    SendSMS(0);
    SMS_sent=true;
  }
  else if(digitalRead(Pin_SMS_emergenza)==LOW) SMS_sent=false;
  
  if(digitalRead(Pin_SMS_frenata)==HIGH && !SMS_sent_break) {
    SendSMS(1);
    SMS_sent_break=true;
  }
  else if(digitalRead(Pin_SMS_frenata)==LOW) SMS_sent_break=false;
}


if(millis()-Time_GSM>10000) {
    Time_GSM=millis();
    setup_messages(1);
}


if(OkGPS && millis()-Time_GPS>5000) {
  smartDelay(1000);
  gps_text();
  Time_GPS=millis();
}
  

if(OkAllarm) {
  if(OkGPS) {
   if(millis()-Time_Allarm>120000) {
    String temp="<Allarme> "+GPS_location;
    GPS_location=temp;
    temp="";
        for(int xx=1; xx<=3; xx++) {
          if(ReadOK(num_cell, xx)){
             Sim800l.sendSms(num_cell, GPS_location.c_str());         
             delay(2000);
          } 
        }
        Time_Allarm=millis();
    }
  }
  else OkGPS=true;
}

}

Parte delle routine......

/* 
 * Questa funzione legge un numero di telefono nella posizione indicata 
 * e lo restituisce in num e da un ok se nella posizione indicata
 * c'è un numero memorizzato
 */


boolean ReadOK(char num[20], int pos) {

int c;
int i;

// Le prime 3 posizioni indicano se la posizione è libera: 0 libera, 1 occupata

   if(EEPROM.read(pos-1)==0) {
    return false;
   }
   else {
    if(EEPROM.read(pos-1)>0) {
                                   // legge il numero

              switch (pos) {
                case 1:
                       c=3;
                break;
                case 2:
                       c=23;
                break;
                case 3:
                       c=43;
                break;                     
              }
              for(i=c; i<=c+20-1; i++) {
                num[i-c]=EEPROM.read(i);
              }
              return true;
    }
    else {
      return false;
    }
   }
}




// Questa funzione cancella il numero nella posizione indicata

boolean CancCell(int pos) {
  
if(EEPROM.read(pos-1)>0) {
  EEPROM.write(pos-1, 0);
  return true;
}
else return false;
}

/* 
 * Questa funzione memorizza un numero di telefono nella posizione desiderata.
 * Scrive 0 se non c'è nessun numero .
 
 */
boolean MemOK(char num[20], int pos) {

int c;
int i;

// Le prime 3 posizioni indicano se la posizione è libera: 0 libera, 1 occupata
              
              c=0;
              switch (pos) {
                case 1:
                       c=3;
                break;
                case 2:
                       c=23;
                break;
                case 3:
                       c=43;
                break;                   
              }
              if(c==0) {
                return false;
              }
              else {
                for(i=c; i<=c+20-1; i++) {
                    EEPROM.write(i, char (num[i-c]));
                }            
                EEPROM.write(pos-1, 1);
                return true;  
              }
}

/*
 * Questa funzione invia un SMS di emergenza o frenata di emergenza
 */
 
void SendSMS(int type) {

int x;
char num[20];
  
  switch (type) {
    case 0: 
         for(x=1; x<=3; x++) { 
           if(ReadOK(num, x)) {
              GPS_location=GPS_location+" <E>";
               Sim800l.sendSms(num, GPS_location.c_str());
               delay(2000);  
           }
         }
    break;
    case 1: 
         for(x=1; x<=3; x++) {
         
           if(ReadOK(num, x)) {
              GPS_location=GPS_location+" <B.E.>";
               Sim800l.sendSms(num, GPS_location.c_str());
               delay(2000);
           }
         }
    break;
  }
}

ciao...non ho letto il codice...però ti dico cosa succedeva a me utilizzando gli interrupt...se l'arduino non è ben isolato solo avvicinando una mano si attivava la funzione prevista dall'interrupt...senza che realmente avessi l'ingresso al pin...vedevo addirittura il led "builtin" attivarsi...come per magia.
inutile dire che questo creava grossi problemi al programma.

io ho risolto isolando meglio la scheda...nel tuo caso prova ad escludere, solo per prova e se possibile, gli interrupt...oppure inserisci dei "detachInterrup" nel momento di gestione dell'SMS.

seconda parte dove c'è la funzione che gestisce gli SMS.. forse quella incriminata

void setup_messages(int ii) {
char num[20]="";
char cell[20]=""; 
boolean oK = false;
boolean Exit=false;
String temp="";
   
temp=Sim800l.getNumberSms(ii);
if(temp.length()>5) {
 temp.toCharArray(num, 20);
 temp=Sim800l.readSms(ii);
 Sim800l.delAllSms();
 int a=temp.indexOf("A1234");
 temp=temp.substring(a);
  if(temp.substring(0, 5)=="A1234") {
   if(temp.substring(5, 7)=="00" && !Exit) {
    temp="";
    temp="<Setup: ";
    switch (EEPROM.read(64)) {
    case 0:
      temp=temp+"DBL=STD, ";
    break;
    case 1:
      temp=temp+"DBL=MIN, ";
    break;
    case 2:
    temp=temp+"DBL=MAX, ";
    break;
    case 3:
     temp=temp+"DBL=NO, ";
    break;        
    case 4:
     temp=temp+"DBL=ALWAYS, ";
    break;                   
   }
   if(EEPROM.read(65)==1) temp=temp+"RC=Y, ";
   else temp=temp+"RC=N, ";                      
   if(EEPROM.read(66)==0) temp=temp+"W=Auto ON/OFF, ";
   else temp=temp+"W=Blck, ";                      
   if(EEPROM.read(67)==0) temp=temp+"SL=N, ";
   else temp=temp+"SL=Y, ";                      
   switch (EEPROM.read(68)) {
   case 0:
   temp=temp+"Ws=NO, ";
   break;
   case 1:
   temp=temp+"Ws=C, ";
   break;
   case 2:
   temp=temp+"Ws=T, ";
   break;
   case 3:
   temp=temp+"Ws=M, ";
   break;                      
  }
  if(EEPROM.read(69)==0) temp=temp+"Al=N, ";
  else temp=temp+"Al=Y, ";                      
  if(EEPROM.read(70)==0) temp=temp+"SMS=N, ";
  else temp=temp+"SMS=Y, ";                      
  if(EEPROM.read(71)==0) temp=temp+"GPS=N, ";
  else temp=temp+"GPS=Y>";
  Sim800l.sendSms(num, temp.c_str());
  num[20]="";
  temp="";
  Exit=true;
  }
  if(temp.substring(5, 7)=="01" && !Exit) {
    temp="<Cell N: ";
    for(int h=1; h<=3; h++) {
     if(ReadOK(cell, h))  {                     
      temp=temp+"("+h+") ";
      for(int q=0; q<20; q++) {
       int cell_int=char (cell[q]);
       if(cell_int==43 || (cell_int>47 && cell_int<58)) temp=temp+cell[q];
      }
      temp=temp+" ";
     } 
   }
   temp=temp+">";
   Sim800l.sendSms(num, temp.c_str());
   num[20]="";
   temp="";
   Exit=true;
  }
  if(temp.substring(5, 7)=="02" && !Exit) {
   char pos;
   pos=temp.charAt(7);
   int int_pos = pos-48;
    if(MemOK(num, int_pos)) {
    }
    num[20]="";
    temp="";
    Exit=true;
   }
   if(temp.substring(5, 7)=="03"  && !Exit) {
    char pos;
    pos=temp.charAt(7);
    int int_pos = pos-48;
    if(CancCell(int_pos)) {
    }  
    num[20]="";
    temp="";
    Exit=true;
   }
   if(temp.substring(5, 7)=="04"  && !Exit) {
    Sim800l.sendSms(num, GPS_location.c_str());
    num[20]="";
    temp="";
    Exit=true;
   }
   if(temp.substring(5, 7)=="05" && !Exit) {
    if(temp.substring(7, 8)=="0") {
     Wire.beginTransmission(Device_Accelerometer); 
     cmd=0;
     Wire.write(cmd);            
     Wire.endTransmission();  
     EEPROM.write(64, 0);
    }
    if(temp.substring(7, 8)=="1") {
     Wire.beginTransmission(Device_Accelerometer);
     cmd=1;
     Wire.write(cmd);            
     Wire.endTransmission();
     EEPROM.write(64, 1);
    }
    if(temp.substring(7, 8)=="2") {
     Wire.beginTransmission(Device_Accelerometer);
     cmd=2;
     Wire.write(cmd);            
     Wire.endTransmission(); 
     EEPROM.write(64, 2);
    }
    if(temp.substring(7, 8)=="3") {
     Wire.beginTransmission(Device_Accelerometer);
     cmd=3;
     Wire.write(cmd);            
     Wire.endTransmission(); 
     EEPROM.write(64, 3);
    }
    if(temp.substring(7, 8)=="4") {
     Wire.beginTransmission(Device_Accelerometer);
     cmd=4;
     Wire.write(cmd);            
     Wire.endTransmission(); 
     EEPROM.write(64, 4);
    }
    num[20]="";
    temp="";
    Exit=true;
   }
   if(temp.substring(5, 7)=="06"  && !Exit) {
    if(temp.charAt(7)=="0") {
      EEPROM.write(70, 0);
    }
    if(temp.charAt(7)=="1") {
      EEPROM.write(70, 1);
    }  
    num[20]="";
    temp="";            
    Exit=true;     
   }
   if(temp.substring(5, 7)=="07"  && !Exit) {
    if(temp.charAt(7)=="0") {
     EEPROM.write(71, 0);
    }
    if(temp.charAt(7)=="1") {
    EEPROM.write(71, 1);
    }  
    num[20]="";
   temp="";
    Exit=true;
   }
   if(temp.substring(5, 7)=="08"  && !Exit) {
    if(temp.substring(7, 8)=="0") {
     Wire.beginTransmission(Device_Windshield);
     cmd=0;
     Wire.write(cmd);            
     Wire.endTransmission(); 
     EEPROM.write(65, 0);
    }
    if(temp.substring(7, 8)=="1") {
     Wire.beginTransmission(Device_Windshield)
     cmd=1;
     Wire.write(cmd);            
     Wire.endTransmission(); 
     EEPROM.write(65, 1)
    }
    num[20]="";
    temp="";
    Exit=true;
    }
    if(temp.substring(5, 7)=="09" && !Exit) {
     if(temp.substring(7, 8)=="0") {
      Wire.beginTransmission(Device_Windshield);
      cmd=2;
      Wire.write(cmd);            
      Wire.endTransmission(); 
      EEPROM.write(66, 0);
     }
     if(temp.substring(7, 8)=="1") {
     Wire.beginTransmission(Device_Windshield);
     cmd=3;
     Wire.write(cmd);            
     Wire.endTransmission(); 
     EEPROM.write(66, 1);
     }
     if(temp.substring(7, 8)=="2") {
      Wire.beginTransmission(Device_Windshield);
      cmd=4;
      Wire.write(cmd);            
      Wire.endTransmission(); 
      EEPROM.write(67, 1);                    
     }
     if(temp.substring(7, 8)=="3") {
     Wire.beginTransmission(Device_Windshield);
     cmd=5;
     Wire.write(cmd);            
      Wire.endTransmission(); 
     EEPROM.write(67, 0);
     }
     if(temp.substring(7, 8)=="4") {
      Wire.beginTransmission(Device_Windshield);
      cmd=6;
      Wire.write(cmd);            
      Wire.endTransmission(); 
       EEPROM.write(68, 1); 
      }
     if(temp.substring(7, 8)=="5") {
      Wire.beginTransmission(Device_Windshield);
       cmd=7;
       Wire.write(cmd);            
       Wire.endTransmission(); 
       EEPROM.write(68, 2); 
      }
      if(temp.substring(7, 8)=="6") {
       Wire.beginTransmission(Device_Windshield);
        cmd=8;
        Wire.write(cmd);            
        Wire.endTransmission(); 
        EEPROM.write(68, 3); 
       }
      if(temp.substring(7, 8)=="7") {
       Wire.beginTransmission(Device_Windshield);
        cmd=9;
       Wire.write(cmd);            
       Wire.endTransmission(); 
       EEPROM.write(68, 0); 
      }
      num[20]="";
      temp="";
      Exit=true;
     }
            if(temp.substring(5, 7)=="10" && !Exit) {
             if(temp.substring(7, 8)=="0") EEPROM.write(69, 0);
             if(temp.substring(7, 8)=="1") EEPROM.write(69, 1);
             num[20]="";
             temp="";
             Exit=true;
           }
           if(temp.substring(5, 7)=="11" && !Exit) {
             if(temp.substring(7, 8)=="1") {
              Wire.beginTransmission(Device_Windshield);
              cmd=10;
              Wire.write(cmd);           
               Wire.endTransmission();       
             }
             if(temp.substring(7, 8)=="0") {
               Wire.beginTransmission(Device_Windshield);
               cmd=11;
               Wire.write(cmd);         
               Wire.endTransmission();       
             }
             num[20]="";
             temp="";
             Exit=true;
           }
          }
     setup_system();
  } 
}

Ultimo parte del codice

TUTTO IL CODICE POSTATO E' SOLO QUELLO DELL'ARDUINO CHE GESTISCE GSM E GPS.....

/*
 * Questa funzione converte un float in una char*
 */

String ftoa(float number, uint8_t precision, uint8_t size) {

  String s = "";

  // Negative 
  if (number < 0.0)  {
    s = "-";
    number = -number;
  }

  double rounding = 0.5;
  for (uint8_t i = 0; i < precision; ++i)    rounding /= 10.0;

  number += rounding;
  s += String(uint16_t(number));  // prints the integer part

  if(precision > 0) {
    s += ".";                // prints the decimal point
    uint32_t frac;
    uint32_t mult = 1;
    uint8_t padding = precision -1;
    while(precision--)     mult *= 10;

    frac = (number - uint16_t(number)) * mult;

    uint32_t frac1 = frac;
    while(frac1 /= 10)    padding--;
    while(padding--)      s += "0";

    s += String(frac,DEC) ;  // prints the fractional part
  }

  if (size>0)                // checks size
    if (s.length()>size)        return("#");
    else while(s.length()<size) s = " "+s;

  return s;
}

/*
 * Questa funzione crea il testo per il GPS da inviare vis SMS
 */
 
void gps_text() {
       
            GPS_location="H: ";
            if (gps.time.isValid()) {
               if ((gps.time.hour()+1) < 10) GPS_location=GPS_location+"0";
               GPS_location=GPS_location+(gps.time.hour()+1)+":";
               if (gps.time.minute() < 10) GPS_location=GPS_location+"0";
               GPS_location=GPS_location+gps.time.minute()+"; ";
            }
            else {
               GPS_location=GPS_location+"N VAL; ";
            }
            GPS_location=GPS_location+ "Pos: "; 
            if (gps.location.isValid()) {
                GPS_location=GPS_location+ftoa(gps.location.lat(), 5, 8);
                GPS_location=GPS_location+","+ftoa(gps.location.lng(), 5, 8);  
            }
            else GPS_location=GPS_location+"N VAL";
}

/*
 * Delay per leggere il buffer del seriale
 */

static void smartDelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    while (Serial.available())
      gps.encode(Serial.read());
  } while (millis() - start < ms);
}



/*
 * Setup di alcuni parametri relativi a questo arduino
 */
void setup_system() {
  if(EEPROM.read(70)==0) OkSMS=false;
    else OkSMS=true;
  if(EEPROM.read(71)==0) OkGPS=false; 
  else OkGPS=true; 
  if(EEPROM.read(69)==1) OkAllarm=true;
  else OkAllarm=false;
}

ORSO2001:
ciao...non ho letto il codice...però ti dico cosa succedeva a me utilizzando gli interrupt...se l'arduino non è ben isolato solo avvicinando una mano si attivava la funzione prevista dall'interrupt...senza che realmente avessi l'ingresso al pin...vedevo addirittura il led "builtin" attivarsi...come per magia.
inutile dire che questo creava grossi problemi al programma.

io ho risolto isolando meglio la scheda...nel tuo caso prova ad escludere, solo per prova e se possibile, gli interrupt...oppure inserisci dei "detachInterrup" nel momento di gestione dell'SMS.

L'ho pensato, ma l'interrupts è gestito dall'arduino windshield, il problema della memoria (o altro.....) è sull'arduino GPS/GSM....

Adesso sto sostituendo tutte le stringhe dentro le virgolette " "... con la relativa conversione utilizzando char(x).

Mi spiego meglio poiché le stringhe in questione rubano memoria sto sostituendo:

"Pos: " con char(80)+char(111)+char(115)+char(58)+char(32)...... e vedo che recupero bytes...

Ricorda che ... NON sei su un PC dove c'è un sistema operativo ed un "garbage collector", sei su una piccola MCU con solo 2KBytes di SRAM, dove devi fare tutto tu e dove usare la classe "String", a causa dell'allocazione e riallocazione dinamica della memoria, porta quasi sempre ... a grossi problemi e sicuri mal di testa !!! :smiling_imp:

Impara ad usare le stringhe classiche del C ... ovvero semplici array di char terminati dal carattere null (0x00) e le funzioni che trovi nella libreria standard (... che, oltretutto, è automaticamente inclusa dal IDE) AVR libc ed, in particolare, quanto è in <string.h>.

Vedrai che i problemi di "memoria" scompariranno ... :wink:

Guglielmo

int a=temp.indexOf("A1234");
temp=temp.substring(a);

Tra queste due cose dovresti aggiungere un if (a >= 0), altrimenti cosa succede se l'SMS non contiene la stringa A1234?

Comunque il consiglio di gpb è più che valido. Il problema è che questa libreria SMS usa le String :(.

SukkoPera:

int a=temp.indexOf("A1234");

temp=temp.substring(a);




Tra queste due cose dovresti aggiungere un if (a >= 0), altrimenti cosa succede se l'SMS non contiene la stringa A1234?

Comunque il consiglio di gpb è più che valido. Il problema è che questa libreria SMS usa le String :(.

Thanks

il problema è proprio questo. Intanto non ho trovato di meglio, altre librerie mangiano molto spazio già in fase di compilazione.

Comunque sostituendo tutte le stringe "kkkk" con le relative somme di char (x) sono sceso da 51% a 39% di occupazione per le variabili locali. Direi un buon risultato.

non saprei come agire in altro modo se non con le stringhe......

P.S. se non c'è A1234 allora non deve fare nulla, verifico e come se ricevesse un sms senza codice di sblocco (,.... che ora non è più segreto...) :slight_smile:

Guarda però che "AAA" non è la stessa cosa di char(65)+char(65)+char(65)... :frowning:

SukkoPera:
Guarda però che "AAA" non è la stessa cosa di char(65)+char(65)+char(65)... :frowning:

Io sto usando

String temp="Ciao...";
temp=temp+char(65);

non dovrebbe darmi Ciao...A?

Ah ok, così dovrebbe funzionare.

consigli su come monitorare la memoria?

folagana:
consigli su come monitorare la memoria?

Prova a leggere QUESTO articolo ...

Guglielmo

thanks Gugliemo

l'avevo già letto qualche settimana fa e mi sono fatto alcune domande. Io ho usato MemoryFree (che mi ha aiutato a capire che forse il problema è di memoria ) però non sono certo che mi dia indicazioni utili. Mi spiego meglio, io in effetti leggo la memoria libera nel momento in cui eseguo l'istruzione di memoryfree ma come faccio ad essere certo che quando viene eseguita una funzione della libreria Sim800l quest'ultima non consumi la memoria residua? Io lo posso mettere prima e dopo l'istruzione "temp=Sim800l.readSms(ii);" per esempio ma a parte il valore di temp come faccio ad essere sicuro che Sim800l.readSms non consumi la memoria residua.... io spesso ho visto che temp è una stringa incompleta come se si saturasse la memoria ma senza un check non posso essere sicuro....

Spero di essermi spiegato.

... è chiaro che, se vuoi fare questo tipo di analisi, devi aprire i sorgenti della libreria (i .cpp) ed inserire la chiamata anche li dentro, nei punti critici.

Guglielmo

gpb01:
... è chiaro che, se vuoi fare questo tipo di analisi, devi aprire i sorgenti della libreria (i .cpp) ed inserire la chiamata anche li dentro, nei punti critici.

Guglielmo

Ora si che mi hai fatto venire il mal di testa!... :frowning:

Premesso che non conosco benissimo il C (neanche ++) ma solo quel po che arduino ha in comune. Del codice sotto, nella funzione che invia gli sms, immagino che la variabile buffer potrebbe aumentare la richiesta di memoria perché la variabile text è passata come puntatore corretto?

Quindi se metto la funzione MemoryFree() nel codice di questa funzione potrei vedere se in effetti la memoria è ulteriormente sacrificata......durante l'invio di sms...

Mentre durante la lettura di sms non mi pare vi sia la possibilità di un incremento della memoria necessaria (leggasi consumo di memoria)

Invece di pare di capire che la funzione che legge il numero e lo restituisce legge prima il testo dell'sms e quindi si ciuccia un bel pò di memoria.... o mi sbaglio?

A proposito a che serve leggere il buffer del softserial nella funzione che invia gli sms se occorre inviare l'sms (scusate l'ignoranza)

Potrebbe anche readSerial() consumare e necessitare di un controllo con MemoryFree() (non mi pare)....

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


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

}



// Public methods



bool Sim800l::sendSms(char* number,char* text){

    SIM.print (F("AT+CMGF=1\r")); //set sms to text mode  
    _buffer=_readSerial();
    SIM.print (F("AT+CMGS=\""));  // command to send sms
    SIM.print (number);           
    SIM.print(F("\"\r"));       
    _buffer=_readSerial(); 
    SIM.print (text);
    SIM.print ("\r"); 
	//change delay 100 to readserial	
    _buffer=_readSerial();
    SIM.print((char)26);
    _buffer=_readSerial();
    //expect CMGS:xxx   , where xxx is a number,for the sending sms.
    if (((_buffer.indexOf("CMGS") ) != -1 ) ){
      return true;
    }
    else {
      return false;
    }
}



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 "";
  }
}



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 "";
}

Nel file cpp ho notato che in alcune funzioni c'è la chiamata di Serial.println(variabile).... credo che nel mio caso avendo la seriale impegnata con il GPS queste righe vadano commentate // (eliminate) Giusto?