首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在PROGMEM中按ID查找消息的最好方法?

在PROGMEM中按ID查找消息的最好方法?
EN

Stack Overflow用户
提问于 2013-07-01 03:38:36
回答 1查看 86关注 0票数 1

我正在尝试确定根据从外部设备返回的整数来检索和显示来自PROGMEM的错误消息的最佳方法。

代码语言:javascript
复制
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查找字符串的方法是必需的,但我在实现这一点的最佳方法上并没有取得太大进展。

EN

回答 1

Stack Overflow用户

发布于 2013-07-01 05:02:33

而不是执行以下操作:

代码语言:javascript
复制
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等)。作为矩阵的第一索引,将实际误差作为数组的第二索引:

想法是这样的:

代码语言:javascript
复制
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";

(编辑)下面是一个有效的语法:

代码语言:javascript
复制
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"}};

唯一的缺点是您需要指定内部数组的长度,因此在每个内部数组中需要具有相同数量的字符串。

然后,您可以编写一个执行状态代码转换的函数:

代码语言:javascript
复制
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));
}

该解决方案不会比使用一个数组使用更多的内存(只需多使用一个指针)。唯一的缺点是,如果您需要不连续的状态代码,如1000101010421300。然后,我想不出什么很酷的解决方案,除了使用一个很好的旧开关/案例:

代码语言:javascript
复制
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");
    }
}

(编辑)关于如何处理你的问题,我有第三个想法:

代码语言:javascript
复制
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];
}

但我认为使用所有三个解决方案中较少内存的解决方案是使用用例的第二个解决方案。因为所有的事情都是在程序内存中完成的,而且所有的字符串都在闪存中,这要归功于F()宏。为了节省一些额外的字节,您甚至可以使fmt_error()函数内联,这样它就不会添加到函数调用堆栈中。

HTH

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17394147

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档