Error en funcion map

hola estoy usando la funcion map, me di cuenta de que funciona bien desde el limmite inferior pero al llegar al valor maximo que es 1023 no le asigna el 100 que le corresponderia si no que le asigna un valor incorrecto wel cual es 101, alguien puede ayudarme?.
GRACIAS


int pot,i;
void setup() {
Serial.begin(115200);
Serial.println("HELLO ");
}

void loop() {
i=1023;

  pot=map(i,0,1023,7200,100);
  Serial.println("VALOR de i   "+String(i));
   Serial.println("VALOR de pot   "+String(pot));
  delay(10000);
  

}

Raro, no logro reproducir el error, siempre me devuelve 100.

HELLO
VALOR de i 1023
VALOR de pot 100

¿Qué placa usas?

Esto entrega con 1023

VALOR de i 1023
VALOR de pot 100

sin embargo en lugar de 1023 si usas 1022 miren

VALOR de i 1022
VALOR de pot 107

Analicemos la función map()

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

Reemplazando valores tienes

x = 1023
in_min = 0
in_max = 1023
out_min = 7200
out_max = 100

(1023-0)(100-7200)/(1023-0)+ 7200
(1023)
(-7100)/1023+7200
Para que de 101 tiene que hacer mal la cuenta 1023*(-7100)/1023 y en lugar de -7100 debería dar -7099

Buenas....
Según la referencia del IDE

No le veo la utilidad, ellos sabrán...
Saludos.

Y está perfecto porque la recta tiene pendiente negativa.

Como no dice que placa usa no sabemos si se debe a un problema de la implementación de map(), puede deberse al redondeo (otra cosa no se me ocurre).

La utilidad puede ser asegurar los valores en dos puntos de un rango.
Por ej., para indicar el nivel de carga de una pila de litio, tendrías 100% cuando tenga 4.18V (855 en ADC) y 0% cuando mida 3.31V (677 en ADC).
El resto no interesa.

Igual prefiero hacer el cálculo antes de usar map() o constrain(). :wink:

ESP 8266 node MCU v2, estaba empleandola para un dimmer PWM a traves de WEBSOCKET en NODE RED, pero obtenia el mismo problema, asi que solo probe la parte de MAP aparte pero veia que la inconsitencia venia de esta funcion

Y quien dijo que no lo esta?

Solo digo que con esos valores el pot da 107, de hecho el OP quiere valores entre 7200 y 100 no entre 0 y 100 como siempre esperamos.

101 esta dentro de lo esperable en su rango.
La pregunta es : Porqué a el le sale 101 y a nosotros no con 1023?

EDITO 1:
Creo que hay que mirar si map en un ESP esta hecho de otro modo. Si map fuera hecho con variables tipo float y al final le hicieran un redondeo, entonces valores proximos a 1022.8 darían un 101 de salida.

1022,85 101,0410557

Especulacion!!!

EDITO 2: Bueno estaba errado. esta es la función map del ESP

long map(long x, long in_min, long in_max, long out_min, long out_max) {
    const long dividend = out_max - out_min;
    const long divisor = in_max - in_min;
    const long delta = x - in_min;

    return (delta * dividend + (divisor / 2)) / divisor + out_min;
}

Habra que hacer un sketch y ver que resulta.

La intención fue reafirmar tu comentario y dar algún detalle más, nada más que eso.
:pleading_face:

Gran sorpresa!!!
Prueba funcion map ESP8266
i = 1023: 101
i = 1022: 108
i = 1021: 115
i = 1020: 122

long map2(long x, long in_min, long in_max, long out_min, long out_max) {
    const long dividend = out_max - out_min;
    const long divisor = in_max - in_min;
    const long delta = x - in_min;

    return (delta * dividend + (divisor / 2)) / divisor + out_min;
}

void setup() {
  Serial.begin(115200);
  Serial.println("Prueba funcion map ESP8266");
  delay(1000);
  for (long i=1023; i>1010; i--) {
    long tmp = map2(i, 0, 1023, 7200, 100);
    Serial.printf("i = %4ld: %ld\n", i, tmp);
  }
}

void loop() {
}

NOTA: @anon90500195, esta todo bien.

Edito 2: Yo sigo investigando, miren esto, apareció el responsable
Tal como dije antes, el cociente tenía que dar -7099 para que sumado a 7200 diera x resultado 101 y asi es.
Corrido en un ESP8266

long map2(long x, long in_min, long in_max, long out_min, long out_max) {
    const long dividend = out_max - out_min;
    const long divisor = in_max - in_min;
    const long delta = x - in_min;

    Serial.printf("divided : %ld\n", dividend);
    Serial.printf("divisor : %ld\n", divisor);
    Serial.printf("delta   : %ld\n", delta);
    Serial.printf("Suma 1  : %ld\n", delta * dividend + (divisor / 2));
    Serial.printf("Cociente: %ld\n", (delta * dividend + (divisor / 2)) / divisor);
    return (delta * dividend + (divisor / 2)) / divisor + out_min;
}

void setup() {
  Serial.begin(115200);
  Serial.println("Prueba funcion map ESP8266");
  delay(1000);
  long i = 1023;
  long tmp = map2(1023, 0, 1023, 7200, 100);
  Serial.printf("i = %4ld: %ld\n", i, tmp);
}

void loop() {
}

La respuesta del Serial Monitor

Prueba funcion map ESP8266
divided : -7100
divisor : 1023
delta : 1023
Suma 1 : -7262789
Cociente: -7099 <== CULPABLE
i = 1023: 101

De manera que esta operación en lugar de dar -7100 responde con un -7099

(delta * dividend + (divisor / 2)) / divisor

EDITO 3: Probé en un nano y la función map original contra la que traje del ESP que es idéntica pero luego de editar este post lo comprobaré de nuevo

#include <LibPrintf.h> // <== Esta librería es una maravilla!!!! 

long map2(long x, long in_min, long in_max, long out_min, long out_max) {
    const long dividend = out_max - out_min;
    const long divisor = in_max - in_min;
    const long delta = x - in_min;

    printf("divided : %ld\n", dividend);
    printf("divisor : %ld\n", divisor);
    printf("delta   : %ld\n", delta);
    printf("Suma 1  : %ld\n", delta * dividend + (divisor / 2));
    printf("Cociente: %ld\n", (delta * dividend + (divisor / 2)) / divisor);
    return (delta * dividend + (divisor / 2)) / divisor + out_min;
}

void setup() {
  Serial.begin(115200);
  Serial.println("Prueba funcion map en NANO");
  delay(1000);
  long i = 1023;
  long tmp = map(1023, 0, 1023, 7200, 100);
  printf("i = %4ld: %ld\n", i, tmp);
  tmp = map2(1023, 0, 1023, 7200, 100);
  printf("i = %4ld: %ld\n", i, tmp);
}

void loop() {
}

Resultados

i = 1023: 100 <===== esta es con la función map original para AVR
divided : -7100
divisor : 1023
delta : 1023
Suma 1 : -7262789
Cociente: -7099
i = 1023: 101 <===== esta es con la función map supuestamente del core para ESP

Bueno hago otro post porque se ensució mucho el anterior.
El problema esta en el cociente/2 que introduce el error por el truncamiento.
Esta función si funciona

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

Los resultados con 1 y otra versión de map

Map tal como figura en el core ESP
i = 1023: 101
Map tal como figura en el arduino.cc
i = 1023: 100

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.