• Post category:Utilitaires
  • Post comments:0 commentaire
  • Post last modified:mars 12, 2022
  • Temps de lecture :9 min de lecture

PROGMEM

Description :

Stockez les données dans la mémoire flash (programme) au lieu de la SRAM. Il y a une description des différents types de mémoire disponibles sur une carte Arduino.

Le PROGMEM mot-clé est un modificateur de variable, il ne doit être utilisé qu’avec les types de données définis dans pgmspace.h. Il dit au compilateur de « mettre ces informations dans la mémoire flash », au lieu de la SRAM, où elles devraient normalement aller.

PROGMEM fait partie de la bibliothèque pgmspace.h . Il est inclus automatiquement dans les versions modernes de l’IDE. Cependant, si vous utilisez une version IDE inférieure à 1.0 (2011), vous devrez d’abord inclure la bibliothèque en haut de votre sketch, comme ceci :

#include <avr/pgmspace.h> Bien qu’il puisse PROGMEM être utilisé sur une seule variable, cela ne vaut vraiment la peine que si vous avez un bloc de données plus volumineux à stocker, ce qui est généralement le plus simple dans un tableau (ou une autre structure de données C++ au-delà de notre discussion actuelle).

L’utilisation PROGMEM est également une procédure en deux étapes. Après avoir placé les données dans la mémoire Flash, des méthodes (fonctions) spéciales, également définies dans la bibliothèque pgmspace.h , sont nécessaires pour lire les données de la mémoire du programme dans la SRAM, afin que nous puissions en faire quelque chose d’utile.

Syntaxe :

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

Notez que parce que PROGMEM est un modificateur de variable, il n’y a pas de règle absolue sur l’endroit où il doit aller, donc le compilateur Arduino accepte toutes les définitions ci-dessous, qui sont également synonymes. Cependant, des expériences ont indiqué que, dans diverses 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é pour fonctionner avec Arduino 13. Les versions antérieures de l’IDE peuvent mieux fonctionner si PROGMEM est inclus après le nom de la variable.

const dataType variableName[] PROGMEM = {}; //utiliser 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 : le 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 ints non signés
const PROGMEM uint16_t charSet[] = { 65000, 32796, 16843, 10, 11234};

// enregistrer quelques caractères
const char signMessage[] PROGMEM = {"I AM PREDATOR,  UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPART"};

unsigned int displayInt;
char myChar;


void setup() {
  Serial.begin(9600);
  while (!Serial);  // attendez que le port série se connecte. 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
  for (byte k = 0; k < strlen_P(signMessage); k++) {
    myChar = pgm_read_byte_near(signMessage + k);
    Serial.print(myChar);
  }

  Serial.println();
}

void loop() {
  // mettez votre code principal ici, pour l'exécuter à plusieurs reprises :
}

 

Arrays of strings 

Il est souvent pratique, lorsque vous travaillez avec de grandes quantités de texte, comme un projet avec un écran LCD, de configurer un tableau de chaînes. Étant donné que les chaînes elles-mêmes sont des tableaux, il s’agit en fait d’un exemple de tableau à deux dimensions.

Ceux-ci ont tendance à être de grandes structures, il est donc souvent souhaitable de les mettre dans la mémoire du programme. Le code ci-dessous illustre l’idée.

/*
  PROGMEM string demo
  Comment stocker une table de chaînes dans la mémoire du programme (flash),
  et les récupérer.

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

  La configuration d'une table (tableau) de chaînes dans la mémoire du programme est un peu compliquée, mais
  voici un bon modèle à suivre.

  La configuration des chaînes est un processus 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 - changer en fonction.
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";


// Ensuite, mettez en place un tableau pour faire référence à 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 assez grand pour la plus grande chaîne qu'il doit contenir

void setup() {
  Serial.begin(9600);
  while (!Serial);  // attendez que le port série se connecte. Nécessaire pour l'USB natif
  Serial.println("OK");
}


void loop() {
  /* L'utilisation de la table de chaînes dans la mémoire du 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 ("buffer").
     Assurez-vous que votre chaîne de réception en RAM est suffisamment grande pour contenir tout
     vous récupérez de l'espace de programme. */


  for (int i = 0; i < 6; i++) {
    strcpy_P(buffer, (char *)pgm_read_word(&(string_table[i])));  // Casts 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 soit définies globalement, soit définies avec le mot-clé static, afin de fonctionner avec PROGMEM.

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

const char long_str[] PROGMEM = "Bonjour, je voudrais 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, je voudrais vous parler un peu de moi.\n"

La F()macro :

Quand une instruction comme :

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

est utilisé, la chaîne à imprimer est normalement enregistrée dans la RAM. Si votre croquis imprime beaucoup de choses sur le moniteur série, vous pouvez facilement remplir la RAM. Si vous avez de l’espace mémoire FLASH libre, vous pouvez facilement indiquer que la chaîne doit être sauvegardée en FLASH en utilisant la syntaxe :

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

 


 

Source : https://www.arduino.cc/reference/en/language/variables/utilities/progmem/

 

Laisser un commentaire