Partage
  • Partager sur Facebook
  • Partager sur Twitter

Probleme de memoire dynamique arduino

14 mars 2017 à 11:52:54

Bonjour, alors voila, lorsque je téléverse mon code sur mon arduino avec la valeur de la variable "debug" qui vaut 0 alors il me renvoie l'erreur suivante :

Arduino : 1.8.1 (Windows 10), Carte : "Arduino/Genuino Uno"

Le croquis utilise 6898 octets (21%) de l'espace de stockage de programmes. Le maximum est de 32256 octets.
Les variables globales utilisent 2350 octets (114%) de mémoire dynamique, ce qui laisse -302 octets pour les variables locales. Le maximum est de 2048 octets.
Mémore insuffisante ; consulter la page http://www.arduino.cc/en/Guide/Troubleshooting#size pour obtenir des astuces sur comment le réduire.

Erreur de compilation pour la carte Arduino/Genuino Uno

Ce rapport pourrait être plus détaillé avec
l'option "Afficher les résultats détaillés de la compilation"
activée dans Fichier -> Préférences.

alors que si cette meme variable vaut 1 les variables valent alors 68%. Cela n'arrive qu'avec cette variable.

Voila le lien vers le code (je ne l’insère pas car il est treees long). Je tiens à préciser que c'est la v1 du code donc à amélioré :) :

http://pastebin.com/nSSnyV38

Merci d'avance

  • Partager sur Facebook
  • Partager sur Twitter
14 mars 2017 à 12:27:53

Bah oui c'est normal car quand debug=1, tu actives plein de Println() et il faut savoir que comme les cpu AVR ont une archi cpu Harvard qui sépare les bus de programmes et de données, les chaînes de caractères doivent être stockées en RAM. C'est une grosse faiblesse des AVR.

Donc, raccourcis tes chaînes, genre "Light : La variable light_etat à été inversé et vaut maitenant 0"...

  • Partager sur Facebook
  • Partager sur Twitter
14 mars 2017 à 12:52:04

Ok, merci à toi mais ce qui me parais bizarre c'est que si au fil du programme, la variable debug vaut 0, alors cela engendre des bugs ? A moins que je n’ai pas tout compris. Et pour régler ce problème (ce n'est que le début du programme), est-il possible de stocke tout les messages et/ou morceau de code sur une carte sd et d'y accéder sans trop de latence. Merci d'avance.
  • Partager sur Facebook
  • Partager sur Twitter
14 mars 2017 à 13:18:13

Si debug vaut 0, tout ce qui est dans les "if(debug){}" n'est pas compilé, donc ne prend pas de mémoire.

Tu peux mettre tes strings en PROGMEM mais c'est chiant.

  • Partager sur Facebook
  • Partager sur Twitter
14 mars 2017 à 13:45:12

Plutot, si debug vaut 0 alors "if(debug){}" est compile :) (réflexe de 0 = vrai et autre = faux). J'ai pas vraiment envie d'utilisé PROGMEM (trop de problèmes) mais je pense utilisé un fichier sur une carte sd avec tout les messages du debug mode mais les seules méthodes d’accès que je trouves sur internet se font caractères par caractères mais j'aimerais le faire ligne par ligne.

Si tu as la solution, je suis preneur.

  • Partager sur Facebook
  • Partager sur Twitter
14 mars 2017 à 13:49:02

Ta variable debug ne change jamais au cours du programme donc le compilateur optimise cela ;)

Par exemple, si debug est déclaré à 1 au début du programme, alors le compilateur va automatiquement remplacé ce bout de code :

  if(debug == 1){
    bluetooth_com();
    manual_com();        
   }  
   else if(debug == 0){
    Serial.println("Console : Appel de la fonction bluetooth_com");
    bluetooth_com();
    Serial.println("-------------------Fin de l'action !-------------------\n");
    Serial.println("Console : Appel de la fonction manual_com");    
    manual_com();
    Serial.println("-------------------Fin de l'action !-------------------\n");  
   } 

Par ceci :

bluetooth_com();
manual_com();

Au final, avec debug à 1, le compilateur supprime énormément d'appels à Serial.println.

Toutes les chaines de caractères que tu déclares pour les appels à Serial.println occupent de l'espace en mémoire RAM (pour leur utilisation) et de l'espace en Flash (pour leur initialisation).

Mais l'espace mémoire n'est pas infinie... surtout la mémoire RAM qui est limitée à 2Ko à partager entre les chaines de caractères mais aussi toutes les variables de ton code.

Au final, avec debug à 1, tu exploses l'espace RAM pour stocker les chaines et c'est ce que te dis le compilateur :

Les variables globales utilisent 2350 octets (114%) de mémoire dynamique, ce qui laisse -302 octets pour les variables locales. Le maximum est de 2048 octets.

Il serait plus judicieux de placer tes chaines en mémoire Flash uniquement.

Pour cela, il te suffit d'utiliser la macro F.

Exemple :

// Sans la macro F :
Serial.println("Hello !");

// Avec la macro F :
Serial.println(F("Hello !"));



-
Edité par lorrio 14 mars 2017 à 13:49:45

  • Partager sur Facebook
  • Partager sur Twitter
14 mars 2017 à 13:49:30

> si debug vaut 0 alors "if(debug){}" est compile
C'est l'inverse...
> J'ai pas vraiment envie d'utilisé PROGMEM (trop de problèmes) mais je pense utilisé un fichier sur une carte sd
Franchement, les deux sont casse burnes.
Il y a des tonnes de uC qui ne sont pas en archi harvard et peuvent donc stocker les constantes en flash... genre arduino Due ou autre...
  • Partager sur Facebook
  • Partager sur Twitter
14 mars 2017 à 14:44:47

Ok merci pour toute vos réponse. Je n'ai pas d'autre arduino sous la mains et j'ai un temps assez limité mais merci quand meme lord.

Pour le if voila leurs syntaxe :

if (debug == 0) {
    Serial.println("Console : Debug Mode actif !\n");
  }



Je vais essayer ta technique des macros lorrio et je vous tiens au courant.

  • Partager sur Facebook
  • Partager sur Twitter
14 mars 2017 à 14:50:18

Ah ouais, un debug actif quand debug=0, t'es un grand pervers quand même !!!

Sinon, voilà ma méthode perso: remplacer...

Serial.println("Console : Appel de la fonction bluetooth_com");
  bluetooth_com();
  Serial.println("-------------------Fin de l'action !-------------------\n");
  Serial.println("Console : Appel de la fonction manual_com");   
  manual_com();
  Serial.println("-------------------Fin de l'action !-------------------\n"); 


...par...

const char[] MSG_END="fin";

Serial.println("bt_com()");
  bluetooth_com();
  Serial.println(MSG_END);
  Serial.println("manual_com()");   
  manual_com();
  Serial.println(MSG_END); 



  • Partager sur Facebook
  • Partager sur Twitter
14 mars 2017 à 15:05:27

Oui, pour je vais replacer les 'fin de l'action" par une variable et pour le reste j'utiliserais le f()

Pour le debug, cela permet qu'il soit actif même si sa valeur n'est pas déclaré.

Edit : le macro f() fait bien partie de la librairie eeprom ?

Edit n° 1257457 : C'est bon j'ai regle le probleme de f() :)

Edit n° 9+8683 : C'est énorme le f(), merci lorrio. Juste en mettant quelques println, je gagne pleins d'octets. Il ne me rest plus qu'à faire le reste du code.

Dernier edit (enfin j'espere) : Merci beaucoup à vous, J'ai réussi à descendre à 30%. Petite question bête, est-ce que les commentaires utilisent de l'espace ?

-
Edité par Rennor974 14 mars 2017 à 16:52:40

  • Partager sur Facebook
  • Partager sur Twitter
14 juin 2020 à 22:46:36

#include #include "NewPing.h" #define TRIGGER_PIN 12 #define ECHO_PIN 11 #define MAX_DISTANCE 200 int angle; Servo servo; NewPing sonar (TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE) ; void setup() { Serial.begin(115200) ; servo.attach(8); servo.write(angle); } void loop() { delay(200) ; unsigned int uS = sonar.ping() ; Serial.print ("Ping:") ; Serial.print(uS / US_ROUNDTRIP_CM) ; Serial.println("cm") ; if ((uS / US_ROUNDTRIP_CM) == 5) { // now scan back from 180 to 0 degrees for(angle = 140; angle > 0; angle--) { servo.write(angle); delay(10); } } }#include <Servo.h>
#include "NewPing.h"
#define TRIGGER_PIN 12
#define ECHO_PIN 11
#define MAX_DISTANCE 200
int angle;
Servo servo;
NewPing sonar (TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE) ;
void setup() {
Serial.begin(115200) ;
  servo.attach(8);
  servo.write(angle);
}
void loop() {
delay(200) ;
unsigned int uS = sonar.ping() ;
Serial.print ("Ping:") ;
Serial.print(uS / US_ROUNDTRIP_CM) ;
Serial.println("cm") ;
if ((uS / US_ROUNDTRIP_CM) == 5)
{
  // now scan back from 180 to 0 degrees
  for(angle = 140; angle > 0; angle--)    
  {                                
    servo.write(angle);           
    delay(10);                   
  }
}
}
  • Partager sur Facebook
  • Partager sur Twitter
15 juin 2020 à 8:10:36

Bonjour WinnieMarley ,

Je dois avouer ne pas comprendre l’intérêt de déterrer un sujet vieux de 3 ans pour y poser un code sans aucune explication ni aucun rapport avec le sujet initial.

Si tu souhaites obtenir de l'aide, il te faut créer ton propre sujet, expliquer brièvement ton problème et poster ton code en utilisant les balises appropriées (le petit bouton </> en haut de la zone d'édition du message).

En attendant, je ferme ce sujet.

  • Partager sur Facebook
  • Partager sur Twitter