c - 减少非线性模拟值到数字输出

标签 c adc digital

我做了一个键盘,可以给我一个模拟值。现在我想根据电阻检测按下哪个键。然而,这些值是非线性的。

我用很多“if/else-es”来做到这一点。有更好的方法吗?

if(analogValue < 159){
  keyPress(KEY_A_ACUTE);
}else if(analogValue < 400){
  keyPress(KEY_I_ACUTE);
}else if(analogValue < 537){
  keyPress(KEY_O_ACUTE);
}else if(analogValue < 624){
  keyPress(KEY_U_ACUTE);
}else if(analogValue < 685){
  keyPress(KEY_N_TILDE);
}else if(analogValue < 800){
  keyPress(KEY_E_ACUTE);
}

最佳答案

您可以创建结构类型的数组并使用循环:

struct KeyValue
{
    int    key_name;
    int    max_value;  // Strictly less than threshold
};

static const struct KeyValue keys[] =
{
    { KEY_A_ACUTE, 159 },
    { KEY_I_ACUTE, 400 },
    { KEY_O_ACUTE, 537 },
    { KEY_U_ACUTE, 624 },
    { KEY_N_TILDE, 685 },
    { KEY_E_ACUTE, 800 },
};
enum { NUM_KEYS = sizeof(keys) / sizeof(key[0]) };

int analague_to_key_name(int analogue_value)
{
    for (int i = 0; i < NUM_KEYS; i++)
    {
         if (analogue_value < keys[i].max_value)
             return keys[i].key_name;
    }
    return KEY_UNKNOWN;
}

唯一的问题是处理超出范围的值——我选择返回一个特殊的 KEY_UNKNOWN 值,但您可以使用任何合适的替代策略。当然,数据必须按 max_value 的升序排列。

此技术的一个优点是它不受表中添加内容的影响,并且可以处理阈值之间的任意差异。如果表变得足够大(可能有几十个条目),您可以切换到对值进行专门的二进制搜索,这样可以减少比较。二进制搜索是专门的,因为您需要接受一个范围;您可能需要使用 min_valuemax_value 创建结构。

关于c - 减少非线性模拟值到数字输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54031045/

相关文章:

c - 增加带有 Realloc 的结构的大小(第二次增加时出错)

android - 如何让数字时钟只显示小时和分钟

c - 将模数转换器ADC(0804)的数字数据存储在8051中

C++的两种替代输入法

c++ - 原始数据类型的相等运算符与 memcmp 的性能

c - 新指针(通过 malloc)与释放/旧指针之一相同

c - AVR Xmega USART 读取完整字符串时出现问题

c - STM32f3 - 多个ADC

c - Atmel AVR ADMUX 寄存器未分配值

python - Adafruit ADC 和 Python 属性错误