2013-06-30 3 views
1

J'essaie de déterminer quel serait le meilleur moyen de récupérer et d'afficher un message d'erreur de PROGMEM basé sur un retour d'entier d'un périphérique externe.Meilleur moyen de trouver un message par ID dans PROGMEM?

const prog_char error_1000[] PROGMEM = "No data provided."; 
const prog_char error_1001[] PROGMEM = "device not activated"; 
const prog_char error_2000[] PROGMEM = "Machine ID invalid"; 
const prog_char error_3000[] PROGMEM = "Insufficient Balance"; 

void loop() 
{ 
    int result = device.GetStatus(); 
    Serial.println(/*error by code here*/); 
} 

Les erreurs sont regroupés par le nombre de tête (à savoir 1xxx sont des erreurs de l'appareil, 2xxx sont des problèmes avec un autre composant, 3xxx sont des erreurs de transaction). Cependant, il y a probablement seulement 5-10 erreurs dans chaque catégorie. J'utilise quelques bibliothèques lourdes de mémoire et ma mémoire est déjà presque épuisée sur l'Uno alors j'essaye de garder les choses petites ici.

Fondamentalement une certaine façon de rechercher des chaînes par un ID est ce qui est nécessaire, mais je ne fais pas beaucoup de progrès sur la meilleure façon de le faire.

Répondre

0

au lieu de faire ce qui suit:

const prog_char error_1000[] PROGMEM = "No data provided."; 
const prog_char error_1001[] PROGMEM = "device not activated"; 
const prog_char error_2000[] PROGMEM = "Machine ID invalid"; 
const prog_char error_3000[] PROGMEM = "Insufficient Balance"; 

Je vous conseille d'indexer la catégorie d'erreur (s 1000, 2000 s etc ..) comme premier indice d'une matrice, et l'erreur réelle seconde index du tableau:

Voici l'idée:

const prog_char error_code[1][0] PROGMEM = "No data provided."; 
const prog_char error_code[1][1] PROGMEM = "device not activated"; 
const prog_char error_code[2][0] PROGMEM = "Machine ID invalid"; 
const prog_char error_code[3][0] PROGMEM = "Insufficient Balance"; 

(modifier) ​​ Voici une syntaxe valide :

const prog_char* error_code[][3] PROGMEM = {{"ERROR 1000", "ERROR 1001", "ERROR 1002"}, 
              {"ERROR 2000", "ERROR 2001", "ERROR 2002"}, 
              {"ERROR 3000", "ERROR 3001", "ERROR 3002"}}; 

le seul inconvénient sera que vous devra spécifier la durée de la matrice intérieure, et ont donc besoin d'avoir le même nombre de chaîne dans chaque tableau interne.

Et vous pouvez coder une fonction qui fait la conversion de code d'état:

const prog_char* fmt_error(int code) { 
    return error_code[code/1000][code%1000]; 
} 

void loop() 
{ 
    int result = device.GetStatus(); 
    Serial.println(fmt_error(result)); 
} 

Cette solution n'utilise pas plus de mémoire que d'utiliser une matrice (juste un pointeur plus). Le seul inconvénient de cela est si vous avez besoin de code d'état qui ne sont pas contigus, comme 1000, 1010, 1042 et 1300. Ensuite, il n'y a pas de solution fraîche, je peux penser, sauf au moyen d'un bon vieux switch/case:

const prog_char* fmt_error(int code) { 
    switch (code) { 
     case (1000): return F("Error XXX"); 
     case (1042): return F("Error which code is not contiguous"); 
     case (2042): return F("Another error"); 
    } 
} 

(modifier) ​​ J'ai eu une troisième idée sur la façon de traiter votre problème:

typedef struct 
{ 
    int code; 
    prog_char* message; 
} error_code; 

const error_type error_codes[] = 
{ 
    {0000, F("Unknown error code")}, 
    {1000, F("Error foo")}, 
    {1001, F("Error bar")}, 
    {2000, F("Error foobar")} 
    ... 
}; 

const prog_char* fmt_error(int code) { 
    for (int i=0; i<sizeof(error_codes);++i) 
     if (error_codes[i].code == code) 
      return error_codes[i].message; 
    return error_codes[0]; 
} 

Mais je pense que la solution qui utilise le moins de mémoire des trois solutions est la seconde en utilisant des cas d'utilisation. Parce que tout est fait dans la mémoire du programme, et toutes les chaînes sont dans le flash grâce à la macro F(). Pour enregistrer quelques octets supplémentaires, vous pouvez même faire en sorte que la fonction fmt_error() soit intégrée, de sorte qu'elle ne s'ajoute pas à la pile des appels de fonction.

HTH

+0

J'aime l'idée, mais je ne peux pas le compiler: machine: 29: Erreur: tableau doit être initialisé avec un initialiseur joint brace- machine: 30: erreur: déclaration en conflit « const prog_char code_erreur [1] [1] ' Machine: 29: erreur:' code_erreur 'a une déclaration précédente comme' const prog_char code_erreur [1] [0] ' – GotWoods

+0

Je exposais juste l'idée, vous devez utiliser l'initialiseur const array pour y arriver. Regardez ma modification. – zmo

Questions connexes