成为订阅者(免费)

加入29,000名其他订阅者以获得用户销售折扣和 其他免费资源。
:
:
大学教师'担心 - 您的邮件地址完全是 安全的。我保证使用它 只要 to send you MicroZine.

arduino. 地图

arduino. 地图 - 为什么它可能无法正常工作,您认为它的思维方式!这 MAP函数旨在将一个值更改为另一个范围 值和常用使用是读取 模拟输入 (10位长,因此值范围为0到1023)并将输出更改为字节,以便输出为0到255。

提示: Map()可以从正范围转换为负范围。

然后,您会编写以下代码

val =地图(ADC_VAL,0,1023,0,255);

一切都很好0码到0,1023次地图到255 ...

......偶然分布(真的?????)。

地图()函数很有用,但它有一个秘密隐藏在内部。它的 easy 足够使用(或者你思考),直到你在里面看起来有点深。一个 即使是分配也是你想要的,但它真的这样做了吗?

测试Arduino地图

让我们写一个草图来测试它确实是什么

void setup() {

  Serial.begin(9600);

  for ( 在 t adc = 0; adc < 1024; adc++) {

     在 t mapped = map(adc, 0, 1023, 0, 255);
    Serial.print(adc);
    Serial.print(',');
    Serial.println(mapped);
  }
}

void loop() {
}

串行输出的第一部分 串行输出的最后一部分
0,0
1,0
2,0
3,0
1007,251
1008,251
1009,251
1010,251
4,0
5,1
6,1
7,1
1011,252
1012,252
1013,252
1014,252
8,1
9,2
10,2
11,2
1015,253
1016,253
1017,253
1018,253
12,2
13,3
14,3
15,3
1019,254
1020,254
1021,254
1022,254

1023,255


在上面的表格中,逗号左侧的值是ADC值,而右侧是映射输出值。

您可以从上面的表中看到该输入映射到输出范围 在4(1个输出值的1个输入值范围内)的块中。这是 预期自1024/4 = 256以来。

问题是最终输出值只有1个输出输入 即1023导出255,而1019〜1022导致254次作为产出。 你真正想要的是整个范围内的价值观甚至传播。

要达到这一点,其他输出必须具有5个值 作为输入(您可以看到ADC值0〜4 - 所有5个输入导致 output of a zero.

素描检查Arduino地图分发

此草图每次映射返回a时增加箱数组中的值 值 - 所以每个垃圾箱[]保存在创建输出的次数。

#define SAMPLES 1024
#define OUTPUTS 256

 在 t bins[输出];
const  在 t binsize = (SAMPLES-1)/(输出-1);

void setup() {

  Serial.begin(9600);
  Serial.println("Arduino map output distribution");
  Serial.print("Bin size: ");
  Serial.println(binsize);

  // Initialise bins
  for ( 在 t i = 0; i < 输出; i++) bins[i]=0;

  for ( 在 t adc = 0; adc < SAMPLES; adc++) {
     在 t mapped = map(adc, 0, SAMPLES-1, 0, 输出-1);
    bins[mapped] +=1;
  }

  for( 在 t i=0;i<输出;i++) {
    Serial.print("Bin: ");
    Serial.print(i);
    Serial.print(" count ");
    Serial.print(bins[i]);

    // Show bin distribution error
    if ((bins[i] != binsize)) {
      Serial.println(" ***") ;
    } else Serial.println();

  }

  // Find wrong bin count
  for( 在 t i=0;i<输出;i++) {
    if (bins[i]!=binsize) {
      Serial.print("Bin error: ");
      Serial.println(i);
    }
  }
}

void loop() {
}

输出的最后一部分显示有错误值的四个箱:

Bin: 253 count 4
Bin: 254 count 4
Bin: 255 count 1 ***
Bin error: 0
Bin error: 85
Bin error: 170
Bin error: 255

那么为什么Arduino地图错误?

arduino. 地图()参考 has this to say:

"如前所述,Map()函数使用整数数学。所以 由于这个,分数可能会被抑制。例如,分数 与3/2,4 / 3,5 / 4一样,所有从地图()函数都将返回为1, 尽管有不同的实际价值。所以,如果您的项目需要 精确计算(例如,电压准确到3个小数位), 请考虑避免地图()并实施计算 手动在您的代码中。"

问题是1023的上值并不完全取下 到255,所以你得到一个轻微的错误。所以这是一个分数 suppressed.

函数的代码是:

长地图(长x,long in_min,long in_max,long out_min,long out_max){
   返回(x - in_min)*(out_max - out_min)/(in_max - in_min)+ out_min;
}

计算是

0 * 255/1023 = 0
1 * 255/1023 = 0
2 * 255/1023 = 0
3 * 255/1023 = 0
4 * 255/1023 = 0
5 * 255/1023 = 1

1022 * 255/1023 = 254
1023 * 255/1023 = 255

这些匹配Arduino输出。

看一个更简单的输出

问题变得更加明显。

如果将1023映射到输出范围0至7,问题变得甚至 more apparent.

更改先前草图重新定义的代码 'OUTPUTS' as 8.


然后输出变为:

 arduino.  map output distribution
Bin size: 146
Bin: 0 count 147 ***
Bin: 1 count 146
Bin: 2 count 146
Bin: 3 count 146
Bin: 4 count 146
Bin: 5 count 146
Bin: 6 count 146
Bin: 7 count 1 ***
Bin error: 0
Bin error: 7

如果您尝试使用电位器映射ADC输入来控制8 LED条形图唯一的最后一个LED亮起的时间是输入时 1023!

为了修复它,使值为2的倍数,因此不抑制分数。

注意:对于不同的范围,最大和min之间的差异必须是2的功率。

以下程序使用2个值的功率为输入,并显示校正的输出。

//#define NUM_SAMPLES 1024 // Must be a power of 2 (Range 0-1023)
//#define NUM_OUTPUTS 256  // Must be a power of 2 (Range 0-255)

#define NUM_SAMPLES 1024 // Must be a power of 2 (Range 0-1023)
#define NUM_OUTPUTS 8    // Must be a power of 2 (Range 0-7)

#define NUM_BINS (NUM_OUTPUTS)

 在 t bins[NUM_BINS];
const  在 t binsize = (NUM_SAMPLES)/(NUM_OUTPUTS);

void setup() {

  Serial.begin(9600);
  Serial.println("Arduino map output distribution");
  Serial.print("Bin size: ");
  Serial.println(binsize);

  // Initialise bins
  for ( 在 t i = 0; i < NUM_BINS; i++) bins[i]=0;

  for ( 在 t adc = 0; adc < NUM_SAMPLES; adc++) {
     在 t mapped = map(adc, 0, NUM_SAMPLES, 0, NUM_OUTPUTS);
    bins[mapped] +=1;
  }

  for( 在 t i=0;i< NUM_BINS;i++) {
    Serial.print("Bin: ");
    Serial.print(i);
    Serial.print(" count ");
    Serial.print(bins[i]);

    // Show bin distribution error
    if ((bins[i] != binsize)) {
      Serial.println(" ***") ;
    } else Serial.println();

  }

  // Find wrong bin count
  for( 在 t i=0;i< NUM_BINS;i++) {
    if (bins[i]!=binsize) {
      Serial.print("Bin error: ");
      Serial.println(i);
    }
  }
}

void loop() {
}

输出结果:for num_samples = 1024,num_outputs = 8

 arduino.  map output distribution
Bin size: 128
Bin: 0 count 128
Bin: 1 count 128
Bin: 2 count 128
Bin: 3 count 128
Bin: 4 count 128
Bin: 5 count 128
Bin: 6 count 128
Bin: 7 count 128

注意:还纠正了第一个例子,每个输出的4个输入值均匀校正。

另一个例子

这里'■使用随机样本和输出的另一个例子,即2值的非功率。

#define样品1976
#define输出153.

这里1976/153 = 12.91,每个垃圾箱都有13个值,除了最后一个有一个。所以算法近似正确。

串行输出的第一部分
串行输出的最后一部分
垃圾箱:0 count 13 ***
垃圾箱:1计数13 ***
垃圾箱:2计数13 ***
垃圾箱:3计数13 ***
垃圾箱:4计数13 ***
垃圾箱:5 count 13 ***
垃圾箱:6 Count 13 ***
垃圾箱:7计数13 ***
垃圾箱:145 count 13 ***
垃圾箱:146 Count 13 ***
垃圾箱:147 count 13 ***
垃圾箱:148 Count 13 ***
垃圾箱:149 count 13 ***
垃圾箱:150计数13 ***
垃圾箱:151计数12
垃圾箱:152计数1 ***

arduino. 地图结论

鉴于正常工作是如此痛苦,它可能最好做下列之一。

  • 大学教师'担心错误 - 它唯一的小如果是out 与输入相比,映射值相当大 - 但请记住 最后一个输出值只会生成一次。
  • 使用浮点计算 - 但会慢且更多的内存。
  • 避免使用地图()  - 例如,ADC转换为0 到255只需使用结果 - 使用功能的高8位 analogreadresolution()为此。


新的! Comments

让你说到你刚刚阅读的东西!留下下面的框中的评论。




隐私政策 | 接触 | 关于我

网站地图 | 使用条款


 ezoic. 报告此广告

访问我们的Facebook页面:

   点击这里



最近的文章

  1. 如何使用ADS1115

    使用ADS1115精度16位ADC进行教程进行低功耗。

    阅读更多

  2. arduino. 模拟输出...易模拟输出生成

    arduino. 模拟输出:如何创建最精确的PWM模拟输出以及如何创建模拟PWM正弦波。

    阅读更多

  3. 数号和等效的快速宏。加快代码!

    了解DigitalWrite()的工作原理......现在使用17倍宏宏!

    阅读更多

  4. TCS230颜色传感芯片:如何运作以及如何使用它。

    如何使用TCS230(/ TCS3200)彩色检测器芯片并轻松将其添加到您的任何项目中。

    阅读更多

  5. 如何使用ADXL345进行运动感测等。

    使用ADXL345 Acellerometer,您可以检测到16G!您还可以了解如何使用它来点击检测等。

    阅读更多

  6. HMC5883L 3轴数字MAGENTOMTER如何运作

    HMC5883L - 如何制作数字罗盘,了解HMC5883L和QMC5883L之间的差异以及它们是否兼容。

    阅读更多



读者 Comments

"I wanted to thank
你这么好
对于所有信息
你已经提供了
你的网站's

高超 极好的 ."

- 逃亡Potthath.

"This site really is
最好的和我最喜欢的。
我发现这里有很多很有用
项目和提示。"

- 米兰

Bursach.<at>gmail.com<

"Awesome site,
非常,非常容易和好
导航!"


-
Matt_tr. <at>
wolf359.cjb.net.


学习微控制器

"Interested in
微控制器?"

注册
免费7天指南:

自由 GUIDE : CLICK HERE


"I am a newbie to PIC
我想说
 how great your
网站一直在为我。"


- 戴夫

de_scott.<at>bellsouth.net

"Your site is a great
和完美的工作。
恭喜。"


- SURESH.

IntegratedInfosys.<at>
Yahoo.com.

"I couldn't find the correct
要定义的词语
你的网页。

非常有用,揭开,
诚实明确。

非常感谢
你的时间和作品。
问候。 "


- Anon.

回到顶部