La funcion map() permite re-mapear valores de un rango de entrada, a valores de un rango de salida. En post pasados hablamos de las lecturas análogas y se mencionó que los valores esperados estarán entre 0 y 1023, que representan los 10 bits que maneja la función analogRead(). En muchos casos es necesario re escalar dichos valores a un rango con mayor utilidad, sea el control de temperatura de un sistema de domótica, la velocidad de un motor o en nuestro caso, la intensidad de un LED.
Esta experiencia tratara sobre el uso de la función map para el control de un led rgb con Arduino, usando analogWrite() a partir de lecturas análogas de tres (3) potenciómetros.
El primer problema que encontraremos es que la función analogRead() maneja 10 bits (0 a 1023), mientras que la función analogWrite() maneja 8 bits (0 a 255). Una opción para este problema es re-escalar los valores de lectura mediante el uso de una ecuación lineal, como lo hizo el compañero Edwin De Leon, en su post: «Ventilador con Encendido Automático Ajustable». Este método puede volverse algo complicado cuando se deben trabajar con rangos distintos simultaneamente ya que se debe plantear una ecuación para cada rango.
Para esta experiencia utilizaremos:
- Placa Arduino UNO (Rev3)
- Breadboard o protoboard
- 3 resistencias de 1 kΩ
- 3 resistencias de 220 Ω
- 3 potenciometros de cualquier valor
- 1 led RGB
Para empezar veamos la función map(). La sintaxis de esta función es la siguiente :
map(X, inMin,inMax,outMin,outMax), siendo:
- X: valor a re-mapear (re-escalar)
- inMax: valor máximo del rango de entrada
- inMin: valor mínimo del rango de entrada
- outMax: valor máximo del rango de salida
- outMin: valor mínimo del rango de salida
Esta función realiza la siguente operación matemática:
Para realizar una pequeña prueba para familiarizarnos con la función utilizaremos la siguiente configuración:
Cargamos el siguiente código en ArduinoIDE:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void setup(){ Serial.begin(9600); } void loop(){ int pot1=analogRead(A0); long pot2= analogRead(A0); int map1=map(pot1,0,1023,0,255); long map2=(pot2*255)/(1023); Serial.println("Lectura Map Matematico"); Serial.print(pot1);Serial.print(" "); Serial.print(map1);Serial.print(" ");Serial.println(map2); delay(1000); } |
El código medirá el valor del potenciómetro y devolverá el valor re escalado usando la función map y la operación matemática mostrada anteriormente.
*Nota: Se utilizan variables long en la operación matemática ya que poseen una mayor capacidad de almacenamiento de números (32 bits), lo que las hace más aptas para cualquier proceso matemático.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
Lectura Map Matematico 0 0 0 Lectura Map Matematico 0 0 0 Lectura Map Matematico 0 0 0 Lectura Map Matematico 0 0 0 Lectura Map Matematico 467 116 113 Lectura Map Matematico 993 247 247 Lectura Map Matematico 1023 255 255 Lectura Map Matematico 1023 255 255 Lectura Map Matematico 1014 252 252 Lectura Map Matematico 955 238 237 Lectura Map Matematico 845 210 213 Lectura Map Matematico 824 205 204 Lectura Map Matematico 712 177 177 Lectura Map Matematico 565 140 139 Lectura Map Matematico 462 115 117 Lectura Map Matematico 420 104 105 Lectura Map Matematico 447 111 110 Lectura Map Matematico 492 122 122 Lectura Map Matematico 518 129 130 Lectura Map Matematico 565 140 141 Lectura Map Matematico 611 152 151 Lectura Map Matematico 665 165 166 Lectura Map Matematico 820 204 205 Lectura Map Matematico 1023 255 255 Lectura Map Matematico 1023 255 255 Lectura Map Matematico 921 229 230 Lectura Map Matematico 804 200 199 Lectura Map Matematico 1023 255 255 Lectura Map Matematico 1023 255 255 Lectura Map Matematico 1023 255 255 Lectura Map Matematico 1023 255 255 Lectura Map Matematico 1023 255 255 |
Como habrán notado, los valores que devuelve la función map y la operación matemático son muy parecidos, solo variando en algunos valores intermedios mas no en los mínimos y máximos
El rango de salida debe ajustarse a su necesidad, en mi caso requería que el valores mínimos y máximos de lectura análoga se ajustaran a los valores mínimos y máximos de escritura análoga.
Ahora procederemos a controlar un LED RGB re-mapeando los valores de lectura de potenciómetros para ser usados en la función analogWrite() mediante PWM. Utilizaremos la siguiente configuración:
El código a utilizar es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
int R=9,G=10,B=11; void setup(){ Serial.begin(9600); pinMode(13,OUTPUT); } void loop (){ int potR= analogRead(A0); int potG= analogRead(A1); int potB= analogRead(A2); int mapR= map(potR,0,1023,0,255); int mapG= map(potG,0,1023,0,255); int mapB= map(potB,0,1023,0,255); Serial.print(mapR); Serial.print(" "); Serial.print(mapG); Serial.print(" "); Serial.println(mapB); analogWrite(R,mapR); analogWrite(G,mapG); analogWrite(B,mapB); delay(500); } |
Como vemos cada potenciómetro está ligado, a través de la función map, al control de cada uno de los ánodos correspondiente a los tres colores (rojo, verde y azul). Este código deberá realizar mediciones cada 0.5 segundos y actualizar el color del led dependiendo de los valores de lectura con analogRead().
A continuación un video donde se muestra el funcionamiento del codigo:
[youtube http://www.youtube.com/watch?v=Y35NOrPh36M]
Nota: Al utilizar la modulación por ancho de pulso (PWM) se debe recordar utilizar los pines habilitados para dicha funcion que se distinguen por tener este simbolo: «~» .
Espero que la información suministrada sea de utilidad para todos.
Saludos.
Este proyecto se puede llevar a cabo en java?
Es correcto