Pages: [1]   Go Down
Author Topic: map() Funktion - habe ich einen Denkfehler?  (Read 696 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 2
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

habe ich einen Denkfehler? Ich möchte z.B. 20 Messwerte auf 5 Werte mappen. Also 0-3 = 0, 4-7 = 1 usw.
Klar, ich könnte auch einfach Wert geteilt durch 5 rechnen, ich brauchs aber für ein anderes Projekt (das ist nur ein Test, weil es nicht funktioniert wie ich es mir dachte).
Hier ist der TestCode:
Code:
void setup(void) {
  Serial.begin(9600);
  Serial.println("Hallo zu MAP-Test");
}

void loop() {
  for (int i=0;i<20;i++) {
    int pos = map(i,0,19,0,4);
    Serial.print(i);
    Serial.print(": ");
    Serial.println(pos);   
  }

  while(true){
  }
}

Und das gibt der SerialMonitor aus:
Code:
Hallo zu MAP-Test
0: 0
1: 0
2: 0
3: 0
4: 0
5: 1
6: 1
7: 1
8: 1
9: 1
10: 2
11: 2
12: 2
13: 2
14: 2
15: 3
16: 3
17: 3
18: 3
19: 4

Kann mich bitte jemand aufklären?

Vielen Dank
Logged

Offline Offline
Edison Member
*
Karma: 31
Posts: 1040
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich verstehe dein Problem nicht.

Was ist falsch an dem Ergebnis?
Was hattest zu erwartet?
Logged

Grüße
Gunther

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 235
Posts: 20236
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

vieleicht int pos = map(i,0,20,0,5);
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2743
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Also 0-3 = 0, 4-7 = 1 usw.
Klar, ich könnte auch einfach Wert geteilt durch 5 rechnen

Nee, ist mir nicht klar. (Bei mir ist  4 / 5 = 0  und auch 3 / 5 = 0)

" 0-3 = 0, 4-7 = 1 usw. " interpretiere ich so, dass du am oberen Ende 16...19 => 4 erwartest. ( Also "geteilt durch 4" )

Uwe's Vorschlag sollte das gleiche sein wie map(i,0,16,0,4) .
Zumindest solange i im Bereich  0...19 bleibt.
« Last Edit: April 04, 2013, 11:59:05 am by michael_x » Logged

Offline Offline
Newbie
*
Karma: 2
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,
ok, ich versuch es mal noch genauer. Erster Schreibfehler war: "den Wert durch 4 teilen", nicht durch 5. Ich will 5 neue Werte.

In der Referenz steht folgendes: map(value, fromLow, fromHigh, toLow, toHigh). Ich habe das so verstanden, ich gebe 10 Werte von 1 bis 10 rein, möchte gerne 5 neue Werte und dann entspricht:

1,2 = 1
3,4 = 2
5,6 = 3
7,8 = 4
9,10 = 5

Deswegen war meine Idee: map(i,1,10,1,5). Aber anscheinend wird hier irgendwas geteilt und nicht einfach nur neu zugeordnet.
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2743
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

map macht Division mit Ganzen Zahlen ( integer ). Der Rest wird abgeschnitten.
map(i,1,9,1,5)   rechnet  (i-1) * (5-1) / (9-1) + 1

Quote
For the mathematically inclined, here's the whole function

long map(long x, long in_min, long in_max, long out_min, long out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Code:
i map
1 1  (0*4/8 + 1)
2 1  (1*4/8  +1)
3 2  (2*4/8  +1)
4 2  (3*4/8  +1)
...

Interessanter ist eher, was map ausserhalb des definierten Bereichs macht ( i <= 0 oder i >= 9 in deinem Beispiel):
Begrenzen oder Extrapolieren ?
Die Referenz schweigt sich dazu aus. Falls die Formel tatsächlich so implementiert ist, wird extrapoliert.
Logged

Munich/Germany
Offline Offline
God Member
*****
Karma: 9
Posts: 642
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Die Formel ist so implementiert.
Wenn man z.B. den Wert von analogRead() auf den Bereich von 0 bis 255 ummappen möchte, nimmt man besser nicht map(wert,0,1023,0,255) sondern map(wert,0,1024,0,256)
Logged

_______
Manfred

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2743
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Wenn man z.B. den Wert von analogRead() auf den Bereich von 0 bis 255 ummappen möchte, nimmt man besser nicht map(wert,0,1023,0,255) sondern map(wert,0,1024,0,256)

Als Beispiel für map richtig.

Unabhängig davon: Noch besser ist /4  oder >>2.
Logged

Munich/Germany
Offline Offline
God Member
*****
Karma: 9
Posts: 642
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Wenn man z.B. den Wert von analogRead() auf den Bereich von 0 bis 255 ummappen möchte, nimmt man besser nicht map(wert,0,1023,0,255) sondern map(wert,0,1024,0,256)

Als Beispiel für map richtig.

Unabhängig davon: Noch besser ist /4  oder >>2.

 smiley-lol Ich hätte für das Beispiel doch besser 99 statt 255 nehmen sollen.
Logged

_______
Manfred

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2743
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Ich hätte für das Beispiel doch besser 99 statt 255 nehmen sollen.

Sehr guter Einwand:
man nimmt map (i, 0,1024, 0,100) um sicherzugehen, dass man nur max zweistellige Werte im Bereich 0 .. 99 kriegt.
Und damit die 99 einen genauso großen Bereich abdeckt wie die 98 oder alle anderen Werte.

Darauf kommt man nicht so leicht ohne deine Anregung.
Logged

Pages: [1]   Go Up
Jump to: