domingo, 11 de noviembre de 2018

La función definida map()

La función map() trabaja con dos rangos de datos, lo que hace es tomar un valor del primer rango y obtener su equivalente del segundo rango.
Su sintaxis es la siguiente:
map(var,valMinRangoEntrada,valMaxRangoEntrada,valMinRangoSalida,valMaxRangoSalida)

donde;
var; es la variable que recibe para ser mapeada
valMinRangoEntrada; es el valor mínimo que le entrará
valMaxRangoEntrada; es el valor máximo que le entrará
valMinRangoSalida; es el valor mínimo que ofrecerá
valMaxRangoSalida; es el valor máximo que ofrecerá

Sería conveniente que uno se instruya acerca de esta función para conocer más a fondo su funcionamiento, bien en el sitio oficial: Reference Language o en el blog de Manuel Delgado Crespo, que lo tiene en cristiano.

Podemos obtener el valor mapeado ingresándolo en una variable, ejemplo:
   int variable= map(var, 1,100,100,1) // esto invertiría el valor obtenido
o incluyéndolo como parámetro de una función o método que lo permita, ejemplo:
  Serial.println(map(var, 1,100,100,1));// imprimiría el valor sin guardarlo
o una función propia que requiera un parámetro para hacer alguna operación con el dato, ejem:
  funcionPropia(map(var, 1,100,100,1));// envía el valor mapeado a nuestra función
  int funcionPropia(int valor){
    valor=valor*PI;
    return valor;
 }

Bueno, una vez aclarado un tanto su funcionamiento vamos a darle una aplicación algo práctica. Para ello nos vamos a imaginar que hemos construido una veleta,  dados nuestros escasos recursos los queremos guardar en la EEPROM de nuestra Arduino para posteriormente almacenarlos y analizarlos, por ejemplo en una hoja de cálculo.
Bien, en nuestro teórico caso tenemos muy presente que en nuestra Arduino no podremos almacenar los datos recogidos minuto a minuto, ya que 24 horas X 60 minutos son 1440 registros (disponemos  de 1024 bytes) y en un futuro próximo ampliaremos nuestra esencial Estación.
Además, también sabemos que  nuestra veleta estará arrojando datos que oscilaran entre 0º y 360º,
a sabiendas que no podemos almacenar un valor superior a 255 en cada byte de nuestra EEPROM.
¡La cosa no pinta nada bien!
En este pésimo momento, quizás sería conveniente recordar una de las aptitudes mas esenciales que debe poseer un programador; La Tenacidad.

Una vez oxigenados, decidimos guardar los registros cada cinco minutos (288 registros), esto nos permitirá guardar en la EEPROM datos de tres sensores (que no es la panacea, pero hasta llegar ahí nos va a servir) y en referencia al valor recogido una posible solución sería mapear a bytes las lecturas antes de almacenarlas en la EEPROM y volver a mapearlas a Int al recuperarlas.

Acto seguido os dejo una captura del sketch que hace realidad esta idea, y como no puedo suministraros una veleta a cada uno de vosotr@s, en el sketch he incluido una nueva función; Random() esta función arroja un valor aleatorio dentro del rango especificado en sus parámetros. En este caso Random (muy útil para experimentar) simulará a la veleta, que arrojará valores comprendidos entre 255 y 360 (precisamente los que no podíamos almacenar).


Antes de colgar el Sketch hago algunas aclaraciones...
La primera columna impresa se corresponde con el valor inicial que ha generado random (o sea nuestra veleta) la segunda columna es el valor mapeado a byte y almacenado en la EEPROM, y la tercera columna es el valor leído de la EEPROM nuevamente mapeado para adaptarlo a nuestra necesidad, en esencia lo que debemos comparar son los datos de la primera y tercer columna, en un golpe de vista rápido detectamos que perdemos resolución (un máximo de 2º) ahora bien, cuando construyamos nuestra veleta descubriremos que el componente del viento oscila enormemente y en función de la intendidad, (unos 50º con viento moderado), con lo que esos 2º grados que podamos perder en las conversiones no van a representar ningún problema.

Y ahora si, ahí va el Sketch:


// By Santy, https://santyarduino.blogspot.com //
#include <EEPROM.h> //incluimos la libreria EEPROM para poder gestionar la ROM de Arduino
int dirVeleta;//creamos una variable de tipo entero capaz de almacenar valores superiores a 255
int valores[288]={};//creamos un array en tamaño equivalente a los datos a almacenar
void setup() {
  Serial.begin(9600);
  Serial.println();//Evita la primera linea impresa que suele salir un churro
  Serial.print("Original\t");Serial.print("guardado\t");Serial.println("Resultado");
  Serial.print("________\t"); Serial.print("________\t");Serial.println("_______");
  for(int i=0;i<288;i++){
    dirVeleta=random(255, 360);// simula los valores lanzados por la veleta y lo almacena en dirVeleta
    valores[i]=dirVeleta;// guardamos los valores en el array para las oportunas comprobaciones
    Serial.print(valores[i]);Serial.print("\t\t");// imprime por consola los valores guardados
    byte x = map(dirVeleta, 1, 360, 1, 255);//mapea el valor de dirVeleta y lo almacena en una variable tipo byte
    EEPROM.write(i,x);// como x es de tipo byte lo podemos guardar en la EEPROM sin problema
    Serial.print(EEPROM.read(i));Serial.print("\t\t");//imprime el valor anterior para las oportunas comprobaciones
    int z = map(EEPROM.read(i), 1, 255, 1, 360);//recupera el valor guardado en la EEPROM mapeandolo a la inversa
    Serial.println(z);//imprime el valor resultante para los oportunas comprobaciones
  }
}

void loop(){}

No hay comentarios:

Publicar un comentario

Gracias por tu comentario, en breve lo revisaremos.