Función MAP en CCS

Después de trabajar con CCS y Arduino, me ha parecido muy útil la función MAP, ya que muchas veces vamos a leer valores análogos con nuestro MCU, pero los niveles de tensión de entrada son diferentes a los valores que queremos mostrar por ejemplo en un LCD, debemos re-escalar nuestra lectura, si bien es muy sencillo realizar una multiplicación y división entre el rango de representación del ADC y el valor de tensión de referencia del ADC, pero en esta función podremos definir los límites del ADC LSB y MSB, también podremos definir los límites de la salida a escalar, por ejemplo si nosotros queremos mostrar el porcentaje entre 0 y 99% de la rotación de un potenciómetro, solo bastará con indicarle que el mínimo del ADC corresponde al 0% y el máximo del ADC corresponde al 100%, de esta forma nuestra función MAP nos devolverá el valor re-escalado para la representación mencionada., quedando así por ejemplo, para un ADC a 8bit entre 0 y 255 que funciona con una referencia externa entre 0 y 5V, queremos que cuando el potenciómetro esté a la mitad nos muestre el 50%, entonces cuando se lean 127 o 2.5V nos mostrará el 50%, que es lo que necesitamos, y esta función lo realiza sencillamente el MAP.
Otro ejemplo útil, podría ser si necesitamos que la nos muestra entre 0 y 100% pero cuando la tensión de entrada esté entre 2.5 y 5V ósea entre 127 y 255, aqui sera util nuevamente la función MAP., o bien  si queremos el caso inverso, que la salida sea entre el 50 y el 100%, y el resto no nos interese.
La función es claramente útil para el trabajo con el ADC y es extremadamente simple ya que es solamente una pequeña fórmula de grado simple.

map(valor, entradaMin, entradaMax, salidaMin, salidaMax)


valor: el valor a escalar (el valor que proviene del ADC)
entradaMin: valor mínimo del rango de entrada (suele ser 0)
entradaMax: valor máximo del rango de entrada (suele ser 255 o 1023)
salidaMin: valor mínimo del rango de salida (puede ser cualquiera)
salidaMax: valor máximo del rango de salida (puede ser cualquiera)

A continuación se mostrará la fórmula de la misma:

double map(float valor, float entradaMin, float entradaMax, float salidaMin, float salidaMax)    
{                                
   return ((((valor-entradaMin)*(salidaMax-salidaMin))/(entradaMax-entradaMin))+salidaMin);
}  

Como podemos ver la función será del tipo double, que es más preciso que float, aunque no utilizaremos todos los decimales que estas nos proporcionan.
El resto de las variables son float con excepción del valor del ADC que es int ya que este viene directamente del módulo ADC interno que estará entre 0 y 255 para 8bits o 0 y 1023 para 10bit.
la función devolverá el valor calculado que luego volcaremos a otra variable para el proceso de la misma en el programa.

Ejemplos:

leeADC = read_adc();    
valorADC = map(leeADC, 0, 1023, 0, 10);
Suponiendo leeADC=512

(((leeADC-0)(10-0))/(1023-0))+0
(((512-0)(10-0))/(1023-0))+0
(512*10)/1023
5120/1023=5.04

-------------------------------------------------------

leeADC = read_adc();  
valorADC = map(leeADC, 0, 255, 0, 100);
Suponiendo leeADC=200

(((leeADC-0)(100-0))/(255-0))+0
(((200-0)(100-0))/(255-0))+0
(200*100)/255
20000/255=78.43

-------------------------------------------------------

leeADC = read_adc();         
valorADC = map(leeADC, 0, 255, 50, 100);
Suponiendo leeADC=25

(((leeADC-0)(100-50))/(255-0))+50
(((25-0)(100-50))/(255-0))+50
(25*50)/255)+50
(1250/255)+50=54.90

Ahora realizaremos un pequeño ejemplo para mostrar el valor entre 0 y 100% como se mencionaba al principio de la nota.

#include <16F883.h>
#device adc=8
#use delay(clock=4000000)
#include <LCD.C>
double map(float valor, float entradaMin, float entradaMax,
                    float salidaMin, float salidaMax){
  return ((((valor-entradaMin)*(salidaMax-salidaMin))/
                 (entradaMax-entradaMin))+salidaMin);
}  
void main(){
  setup_adc_ports(sAN0|VSS_VDD);
  setup_adc(ADC_CLOCK_DIV_2);
  lcd_init();
  int valorAdc, leeAdc;
  while(true){
  set_adc_channel(0);
  delay_us(10);
  leeAdc = read_adc();
  valorADC = map(leeADC, 0, 255, 0, 100);
  lcd_gotoxy(1,1);
  printf(lcd_putc,"Valor ADC: %u   \r",leeADC);
  lcd_gotoxy(1,2);
  printf(lcd_putc,"Valor MAP: %d   \r",valorADC);  
  }
}

No hay comentarios.:

Publicar un comentario