|

PROGMEM


Description :

Conservez les données constantes uniquement en mémoire flash (programme), au lieu de les copier dans la SRAM au démarrage du programme. Une description des différents types de mémoire disponibles sur une carte Arduino est disponible.

Le mot-clé PROGMEM est un modificateur de variable ; il ne doit être utilisé qu’avec les types de données définis dans pgmspace.h. Il indique au compilateur de « conserver ces informations uniquement en mémoire flash », au lieu de les copier dans la SRAM au démarrage, comme il le ferait normalement.

PROGMEM fait partie de la bibliothèque pgmspace.h. Il est automatiquement inclus dans l’IDE Arduino.

Bien que PROGMEM puisse être utilisé sur une seule variable, cela n’en vaut vraiment la peine que si vous avez un bloc de données plus important à stocker, ce qui est généralement plus simple dans un tableau (ou une autre structure de données C++ non abordée ici).

L’utilisation de PROGMEM se fait en deux étapes. Une fois qu’une variable a été définie avec PROGMEM, elle ne peut pas être lue comme une variable classique basée sur SRAM : vous devez la lire à l’aide de fonctions spécifiques, également définies dans pgmspace.h.

PROGMEM est utile seulement :

Lors de l’utilisation de cartes AVR (UNO R3, Leonardo, etc.), les cartes plus récentes (Due, MKR WiFi 1010, GIGA R1 WiFi, etc.) utilisent automatiquement l’espace programme lorsqu’une variable est déclarée comme const. Cependant, pour des raisons de compatibilité rétroactive, PROGMEM peut toujours être utilisé avec les cartes plus récentes. Cette implémentation est actuellement disponible ici.

Syntaxe :

const dataType variableName[] PROGMEM = {data0, data1, data3...};

Notez que PROGMEM étant un modificateur de variable, il n’existe pas de règle absolue quant à son emplacement. Le compilateur Arduino accepte donc toutes les définitions ci-dessous, qui sont également synonymes. Cependant, des expériences ont montré que, dans différentes versions d’Arduino (liées à la version GCC), PROGMEM peut fonctionner à un endroit et pas à un autre. L’exemple de « table de chaînes » ci-dessous a été testé avec Arduino 13. Les versions antérieures de l’IDE pourraient mieux fonctionner si PROGMEM était inclus après le nom de la variable.

  • const dataType variableName[] PROGMEM = {}; // utilisez ce formulaire
  • const PROGMEM dataType variableName[] = {}; // ou celui-ci
  • const dataType PROGMEM variableName[] = {}; // pas celui-ci

Paramètres :

  • dataType : Types de données autorisés : tout type de variable
  • variableName : nom de votre tableau de données

Exemple de code :

Les fragments de code suivants illustrent comment lire et écrire des caractères non signés (octets) et des entiers (2 octets) dans PROGMEM.

// enregistrer quelques entiers non signés
    const PROGMEM uint16_t charSet[] = { 65000, 32796, 16843, 10, 11234};

    // save some chars
    const char signMessage[] PROGMEM = {"JE SUIS UN PRÉDATEUR, UN COMBATTANT INVISIBLE. CRÉÉ PAR LE DÉPARTEMENT DES ÉTATS-UNIS"};

    unsigned int displayInt;
    char myChar;


    void setup() {
      Serial.begin(9600);
      while (!Serial);  // Attendre la connexion du port série. Nécessaire pour l'USB natif.

      // mettez votre code d'installation ici, à exécuter une fois:
      // relire un int de 2 octets
      for (byte k = 0; k < 5; k++) {
        displayInt = pgm_read_word_near(charSet + k);
        Serial.println(displayInt);
      }
      Serial.println();

      // relire un caractère
      int signMessageLength = strlen_P(signMessage);
      for (byte k = 0; k < signMessageLength; k++) {
        myChar = pgm_read_byte_near(signMessage + k);
        Serial.print(myChar);
      }

      Serial.println();
    }

    void loop() {
      // mettez votre code principal ici, pour l'exécuter de manière répétée:
    }
Tableaux de chaînes

Il est souvent pratique de créer un tableau de chaînes de caractères lorsqu’on travaille avec de grandes quantités de texte, comme pour un projet avec un écran LCD. Les chaînes étant elles-mêmes des tableaux, il s’agit d’un exemple de tableau à deux dimensions.

Comme il s’agit généralement de structures volumineuses, il est souvent préférable de les stocker en mémoire programme. Le code ci-dessous illustre ce principe.

/*
      Démonstration de chaînes PROGMEM
      Comment stocker une table de chaînes en mémoire programme (flash) et les récupérer.

      Informations résumées de :
      http://www.nongnu.org/avr-libc/user-manual/pgmspace.html

      Configurer une table (un tableau) de chaînes en mémoire programme est un peu compliqué, mais voici un bon modèle à suivre.

      La configuration des chaînes se fait en deux étapes. Tout d'abord, définissez les chaînes.
    */

    #include <avr/pgmspace.h>
    const char string_0[] PROGMEM = "String 0"; // "String 0" etc sont des chaînes à stocker - à modifier en fonction de la situation.
    const char string_1[] PROGMEM = "String 1";
    const char string_2[] PROGMEM = "String 2";
    const char string_3[] PROGMEM = "String 3";
    const char string_4[] PROGMEM = "String 4";
    const char string_5[] PROGMEM = "String 5";


    // Créez ensuite un tableau pour référencer vos chaînes.

    const char *const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5};

    char buffer[30];  // assurez-vous qu'il est suffisamment grand pour la plus grande chaîne qu'il doit contenir

    void setup() {
      Serial.begin(9600);
      while (!Serial);  // Attendre la connexion du port série. Nécessaire pour l'USB natif.
      Serial.println("OK");
    }


    void loop() {
      /* L'utilisation de la table de chaînes en mémoire programme nécessite l'utilisation de fonctions spéciales pour récupérer les données.
         La fonction strcpy_P copie une chaîne de l'espace programme vers une chaîne en RAM (« tampon »).
         Assurez-vous que la chaîne de réception en RAM est suffisamment grande pour contenir les données récupérées depuis l'espace  programme.. */


      for (int i = 0; i < 6; i++) {
        strcpy_P(buffer, (char *)pgm_read_ptr(&(string_table[i])));  // Castings et déréférencements nécessaires, il suffit de copier.
        Serial.println(buffer);
        delay(500);
      }
    }

Remarques et avertissements :

Veuillez noter que les variables doivent être définies globalement ou avec le mot-clé static pour fonctionner avec PROGMEM.

Le code suivant ne fonctionnera PAS à l’intérieur d’une fonction :

const char long_str[] PROGMEM = "Bonjour, j'aimerais vous parler un peu de moi.\n";

Le code suivant fonctionnera, même s’il est défini localement dans une fonction :

const static char long_str[] PROGMEM = "Bonjour, j'aimerais vous parler un peu de moi.\n"
La macro F()

Lorsqu’une instruction comme :

Serial.print("Écrivez quelque chose sur le moniteur série");

Si vous utilisez un string, la chaîne à afficher est généralement enregistrée en RAM. Si votre croquis imprime beaucoup de données sur le moniteur série, vous pouvez facilement remplir la RAM. Pour éviter cela, ne chargez les chaînes de la mémoire FLASH que lorsque cela est nécessaire. Vous pouvez facilement indiquer que la chaîne ne doit pas être copiée en RAM au démarrage grâce à la syntaxe suivante :

Serial.print(F("Écrivez quelque chose sur le moniteur série qui est stocké dans FLASH"));


Source : https://docs.arduino.cc/language-reference/en/variables/utilities/PROGMEM/

Publications similaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *