1

外部デバイスからの整数の戻り値に基づいて、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*/);
}

エラーは先頭の番号でグループ化されます (つまり、1xxx はデバイス エラー、2xxx は別のコンポーネントの問題、3xxx はトランザクション エラーです)。ただし、各カテゴリにはおそらく 5 ~ 10 個のエラーしかありません。

私はいくつかのメモリの重いライブラリを使用していますが、私のメモリはすでに Uno でほとんど使い果たされているため、ここでは物事を小さく保とうとしています。

基本的に、ID で文字列を検索することが必要ですが、これを行う最善の方法についてはあまり進歩していません。

4

1 に答える 1

0

次のことを行う代わりに:

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";

エラー カテゴリ ( 1000s、2000s など) を行列の最初のインデックスとしてインデックス化し、実際のエラーを配列の 2 番目のインデックスとしてインデックス化することをお勧めします。

アイデアは次のとおりです。

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";

(編集)有効な構文は次のとおりです。

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"}};

唯一の欠点は、内部配列の長さを指定する必要があるため、各内部配列に同じ数の文字列が必要になることです。

そして、ステータス コードの変換を行う関数をコーディングできます。

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));
}

そのソリューションは、1 つの配列を使用するよりも多くのメモリを使用しません (ポインタが 1 つ増えるだけです)。その唯一の欠点は、 、 、 のように連続1000していないステータス コードが必要な場合です。次に、古き良きスイッチ/ケースを使用する以外に、私が考えることができるクールな解決策はありません。101010421300

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");
    }
}

(編集)あなたの問題に対処する方法について3番目のアイデアがありました:

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];
}

しかし、3 つのソリューションすべての中でメモリ使用量が少ないソリューションは、ユース ケースを使用する 2 番目のソリューションだと思います。F()すべてがプログラムメモリで行われ、マクロのおかげですべての文字列がフラッシュにあるためです。数バイト余分に節約するために、fmt_error()関数をインライン化することもできます。これにより、関数呼び出しスタックに追加されなくなります。

HTH

于 2013-06-30T21:02:32.780 に答える