Lo que voy a explicar ahora no es programación básica, pero creo que es necesario comentarlo aunque sea de pasada porque aunque vosotros no lo useis para programar necesitáis saber que es para reconocerlo si os tropezáis con ello.
Podemos definir una macro para que se comporte como lo haría una función.
Las macros que siguen sirven para lo siguiente:
ABS(x) Devuelve el valor absoluto de un entero, es decir para x igua a 5 o para x igual a -5 devolverá el valor positivo 5.
MAX(a,b) Devuelve el valor mayor de los dos.
MDE2(a,b) Devuelve la media de dos valores.
MED3(a,b,c) Devuelve la media de tres valores.
BIGGEST(a,b,c) Devuelve el mayor valor de los tres.
INRANGE(min, i, max) Devuelve true si el valor i está dentro del rango de valores comprendido entre los valores min, max ambos inclusive.
Código:
#define ABS(x) (((x) < 0) ? -(x) : (x))
#define MAX(a,b) ((a < b) ? (b) : (a))
#define MED2(a,b) (((a)+(b))/2)
#define MED3(a,b,c) (((a)+(b)+(c))/3)
#define BIGGEST(a,b,c) ((MAX(a,b) < c) ? (c) : (MAX(a,b)))
#define INRANGE(min, i, max) ((i <= min) || (i >= max) ? 0 : 1)
Son solo ejemplos.
Las macros de este tipo son delicadas de manejar porque pueden provocar problemas si no se usan bien. Las macros funciona por simple expansión de patrones en el código y por ello el compilador no puede verificar si existe un problema de compatibilidad de tipos de datos. Los mensajes de error que se produzcan como resultado de un mal uso de una macro pueden ser poco claros y no ayudar mucho a localizar el fallo.
Dicho esto hay una macro que yo en Arduino me he acostumbrado a usar bastante a menudo. Se trata de la macro F().
Se trata de una macro que permite al compilador guardar un dato en una zona de memoria totalmente diferente a la del resto de los datos.
Para ahorrar memoria SRAM que en Arduino suele ser escasa, recurrimos a usar la memoria FLASH con aquellos datos que son invariables. En la memoria FLASH que es más abundante, es donde se almacena el código del programa una vez compilado y por ello en Arduino se la suele denominar PROGMEM.
La función F() entrega una dirección de memoria PROMEM. Se suele usa mucho para ahorrar memoria con cadenas de caracteres entre comillas dobles.
Si en lugar de usar Serial.println("Hola mundo"); usamos Serial.println(F("Hola mundo")); ahorramos 11 carateres en SRAM.
En C las cadenas de caracteres incluyen siempre un caracter con valor nulo que hace de señal para indican el final de la cadena. de esa forma nos basta pasar la dirección de memoria donde empieza la cadena.
El caso es que la función F("cadena") devuelve un dato que es especial y solo unas pocas funciones entre las cuales se encuentra Serial.print() y Serial.println() son capaces de usarla. Aún así, F("cadena") es muy útil, dado que esas cadenas se usan con frecuencia para ser mandadas a un puerto Serial .
En mis programas vais a ver mucho cosas del tipo
Serial.println(F("lo que sea")); porque no me gusta malgastar la poca memoria SRAM del Arduino.
Ya sabéis que F() es una macro y para que sirve.