Mémoire dynamique Arduino Uno pleine

Bonjour à tous,

J'utilise actuellement un shield gprs, un data logger SD et un arduino uno mais lorsque je compile mon code j'ai le message suivant :

Les variables globales utilisent 2.411 octets (117%) de mémoire dynamique, ce qui laisse -363 octets pour les variables locales. Le maximum est de 2.048 octets.

Comment est ce que je pourrais résoudre ce problème, car je ne veux pas utiliser un arduino méga, ca impose trop de contrainte au niveau du câblage de mes shields.

Je vous mets mon code pour que vous sachiez voir ca :slight_smile:

#include <RTClib.h>
#include <dht11.h>
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <GSM.h>


#define DHT11PIN 5
#define PINNUMBER "15987"

GSM gsmAccess;
GSM_SMS sms;
dht11 DHT11;
File myFile;
RTC_DS1307 RTC; // objet Real Time Clock
DateTime now;
long FileSize;

char remoteNumber[20]= "0496919092";
char txtMsg[200]= "Message d'alerte augmentation de temperature !";

void setup()
{
  // initialisation du RTC
  Wire.begin();
  RTC.begin();
  //RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
  now = RTC.now();
  
  Serial.begin(9600);
  boolean notConnected = true;
  
  while(notConnected)
  {
    if(gsmAccess.begin(PINNUMBER)==GSM_READY)
      notConnected = false;
    else
    {
    Serial.println("Not connected");
     delay(1000);
    }
  }
  Serial.println("GSM initialized");
  
  Serial.print("Initialisation carte SD ... ");
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
  pinMode(53, OUTPUT);
   
  if (!SD.begin(4)) // Vérifie que la carte SD est bien dans le slot
  {
    Serial.println("Initialisation echouee!");
    return;
  }
  Serial.println("Initialisation reussie!");

  myFile = SD.open(NomFichier(), FILE_WRITE);
  if (myFile) 
  {
    FileSize = myFile.size();
    if (FileSize < 2)
    {
      Serial.print("Writing to file ... ");
      myFile.println("date;heure;humidite;temperature");
      Serial.println("done");
    }
    else {Serial.println("Le fichier contient deja des donnees");}
    myFile.close();
  } 
  else { Serial.println("error opening file"); }
  
  delay(1000);          // wait for sensor initialization

}

void loop()
{
  uint8_t chk = DHT11.read(DHT11PIN);

  Serial.println("----------Nouvelle sequence de mesures----------");  
  Serial.print("Sensor status: ");
  switch (chk)
  {
    case 0:  Serial.println("OK"); break;
    case -1: Serial.println("Checksum error"); break;
    case -2: Serial.println("Time out error"); break;
    case -3: Serial.println("The sensor is busy"); break;
    default: Serial.println("Unknown error"); break;
  }

  Serial.print("Lecture des capteurs : ");
  Serial.print("Humidite [%]: ");
  Serial.print(DHT11.humidity, DEC);

  Serial.print(" | Temperature [C]: ");
  Serial.println(DHT11.temperature, DEC);

  int lTemperature = DHT11.temperature;
  int TestTemperature = LireDerniereDonnees() - lTemperature;
  
  if (TestTemperature >= 2) {Serial.println("*Alerte* : Diminution de la temperature d'au moins 2 degres");}
  else if (TestTemperature <= -2) {Serial.println("*Alerte* : Augmentation de la temperature d'au moins 2 degres");}
  else {Serial.println("NB : Pas de variation anormale de temperature");}
  
  EcrireDonnees();

  delay(60000);
  Serial.println(" ");
}


//----------------------------------------------------------------------
// Fonction qui écrit les données relevées dans le fichier .csv
//----------------------------------------------------------------------
void EcrireDonnees()
{
  now = RTC.now();
    
  myFile = SD.open(NomFichier(), FILE_WRITE);
  if (myFile) 
  {              
    String sHumidity = String(DHT11.humidity); 
    String sTemperature = String(DHT11.temperature); 
    myFile.println(Date() + ";" + Heure() + ";" + sHumidity + ";" + sTemperature);  
    
    myFile.close();
  } 
  else {Serial.println("error opening file");}
  return;
}

//----------------------------------------------------------------------
// Fonction qui lit les dernières données du fichier .csv
//----------------------------------------------------------------------
int LireDerniereDonnees()
{  
  long FileSize;
  long Curseur;
  int i;
  static char Chaine[6];
  now = RTC.now();
    
  myFile = SD.open(NomFichier(), FILE_READ);

  if (myFile) 
  {
    FileSize = myFile.size();
    Curseur = FileSize - 7;

    myFile.seek(Curseur);
    
      for (i=0; i<=6; i++) {Chaine[i]=myFile.read();}
      delay(100);
    myFile.close();
  }  
  else {Serial.println("error opening file");}

  int iHumidite = 10 * (Chaine[0] - '0') + (Chaine[1] - '0');
  int iTemperature = 10 * (Chaine[3] - '0') + (Chaine[4] - '0');
  Serial.print("La derniere mesure d'humidite enregistree est : ");
  Serial.print(iHumidite);
  Serial.println(" %");
  Serial.print("La derniere mesure de temperature enregistree est : ");
  Serial.print(iTemperature);
  Serial.println(" C");
  
  return iTemperature;
}

//----------------------------------------------------------------------
// Fonction qui permet de retourner la date sous la forme jj-mm-aaaa
//----------------------------------------------------------------------
String Date()
{
  now = RTC.now();
  
  String sjour = String(now.day());
  String smois = String(now.month());
  String sannee = String(now.year());

  String sDate = sjour + "-" + smois + "-" + sannee; 
  return sDate;
}

//----------------------------------------------------------------------
// Fonction qui permet de retourner l'heure sous la forme hh:mm:ss
//----------------------------------------------------------------------
String Heure()
{
  now = RTC.now();
  
  String sheure = String(now.hour());
  String sminute = String(now.minute());
  String sseconde = String(now.second());

  String sHeure = sheure + ":" + sminute + ":" + sseconde;
  return sHeure;
}

//----------------------------------------------------------------------
// Fonction qui permet de retourner le nom du fichier d'enregistrement
// sous la forme aaaammjj.csv
// /!\ le nom du fichier ne peut contenir plus de 8 caractères /!\
//----------------------------------------------------------------------
char *NomFichier()
{
  now = RTC.now();
  static char Buf[13];
  String sjour = String(now.day());
  String smois = String(now.month());
  String sannee = String(now.year());
  String sNomFichier = sannee + smois + sjour + ".csv";
  sNomFichier.toCharArray(Buf, 13);
  
  return Buf;
}

//----------------------------------------------------------------------
// Envoi de sms
//----------------------------------------------------------------------

void sendSMS(){

  Serial.print("Message to mobile number: ");
  Serial.println(remoteNumber);

  // sms text
  Serial.println("SENDING");
  Serial.println();
  Serial.println("Message:");
  Serial.println(txtMsg);

  // send the message
  sms.beginSMS(remoteNumber);
  sms.print(txtMsg);
  sms.endSMS(); 
  Serial.println("\nCOMPLETE!\n");  
}

Bonjour,

Tu peux déjà mettre toutes tes chaines en flash en remplaçant "chaine" par F("chaine").

Il faut bien réaliser que tu ne programmes pas sur un PC. La mémoire est limitée. Alors il y a quelques précautions à prendre.

  • Dimensionner les variables au plus juste. Par exemple, cette ligne d'une cinquantaine de caractères dans un tampon de 200 c'est pas une bonne idée.
    char txtMsg[200]= "Message d'alerte augmentation de temperature !";
    [/li]
  • Eviter d'être trop verbeux. Ton code est truffé de Serial.print. Si c'est juste pour la mise au point, il suffit de mettre des Serial.print là où il y en a besoin pour voir ce qui ne va pas.
  • Etre conscient que les librairies aussi consomment de la mémoire. Pour la librairie GSM je ne sais pas trop mais la librairie SD consomme entre 700 et 800 octets (si ma mémoire est bonne). Il y a un tampon de 512 octets pour le stockage d'un secteur de la carte mémoire par exemple.

Bonjour 3Sigma,

Pourrais tu me montrais sur une de mes lignes de code comme définir cela, car quand j'essaie ca me met des erreurs :confused:

Bonjour fdufnews,

Je comprends tes remarques et je suis bien conscient que l'arduino est limité :confused:
Est ce qu'on sait limiter la taille de ces librairies justement ?
Car j'imagine que la GSM elle doit prendre pas mal de place déjà...

Gus2108:
Pourrais tu me montrais sur une de mes lignes de code comme définir cela, car quand j'essaie ca me met des erreurs :confused:

ex : Serial.print(F(“Hello World”))

Rien qu'en faisant ca je passe à 97% c'est déjà beaucoup mieux :smiley:

Maintenant faudra que je trouve un moyen pour modifier les bibliothèques, car je n'utilise pas toutes les fonctions de celle-ci !

Dans le cas de la librairie SD le buffer de 512 octets est inévitable c'est l'unité de lecture (un secteur à la fois).
Pour les autres librairies c'est plus compliqué et il faudrait les analyser en profondeur.

Je sais que la bibliothèque GSM possède énormément de fonctions mais je n'en utilise qu'une légère partie. Pensez-vous que je pourrais supprimer toutes les fonctions qui me sont inutiles ??

En fait je me rends compte que vu ce que je veux faire et la mémoire SRAM de l'UNO je vais définitivement devoir passer sur le MEGA.

J'ai déjà essayer d'utiliser un MEGA et le shield gsm, ca marche nikel !
J'ai déjà essayer d'utiliser un MEGA et le data logger, ca marche nikel !

Maintenant quand je mets les 2 ensembles ca plante ... Je soupçonne que ca vienne du câblage nécessaire pour faire fonctionner les 2 shields avec le MEGA. Je m'explique :

pour faire fonctionner le data logger sur le méga je dois faire le câblage suivant :
PIN10 shield --> PIN53 MEGA
PIN11 shield --> PIN51 MEGA
PIN12 shield --> PIN50 MEGA
PIN13 shield --> PIN52 MEGA

PINA4 shield --> PIN20 MEGA
PINA5 shield --> PIN21 MEGA

pour faire fonctionner le shield gsm sur le méga je dois faire le câblage suivant :
Ne pas connecter la PIN2 (Gsm TX), j'ai du plier la broche
Réaliser un pont entre la PIN2 et le PIN10

Du coup la PIN10 est "utilisée" 2x et j'ai l'impression que c'est ca qui fait planter mon histoire :frowning: