El espacio de memoria es limitado en una placa Arduino, puede ser importante mejorar su programa Arduino para evitar ciertos problemas. Cuanto más avanzamos en la programación, más llegamos a escribir programas largos y complejos. Es importante, lo antes posible, tomar los reflejos correctos. Se pueden tomar buenos hábitos para facilitar compartir y leer su trabajo; así como para mejorar su ejecución y el espacio ocupado en la memoria.
Veremos en este artículo algunos métodos para mejorar su programa Arduino.
Prerrequisito : Programación con Arduino
Nombres de variables y funciones
Utilice funciones claras y nombres de variables:
nombres explícitos en lugar de letras (Ej: » sensorValue » en lugar de » a «)
Creación de bucles y funciones
Cuando un código se repite varias veces en un programa, crea una función o un bucle.
Use bucles en vectores (matriz). Vamos a leer todas las entradas analógicas del Arduino.
int a,b,c,d,e,f; void setup() { Serial.begin(9600); } void loop() { a=analogRead(A0); b=analogRead(A1); c=analogRead(A2); d=analogRead(A3); e=analogRead(A4); f=analogRead(A5); Serial.print(a); Serial.print(b); Serial.print(c); Serial.print(d); Serial.print(e); Serial.print(f); }
Resultado:
Le croquis utilise 1952 octets (6%) de l'espace de stockage de programmes. Le maximum est de 32256 octets. Les variables globales utilisent 196 octets (9%) de mémoire dynamique, ce qui laisse 1852 octets pour les variables locales. Le maximum est de 2048 octets.
Introducción de un bucle for y una matriz
int a[6]; void setup() { Serial.begin(9600); } void loop() { for(int i=0;i<6;i++){ a[i]=analogRead(14+i); Serial.print(a[i]); } }
Podemos ver que, además de ser más legible, el espacio de memoria que ocupa el código se reduce después de esta operación
Le croquis utilise 1746 octets (5%) de l'espace de stockage de programmes. Le maximum est de 32256 octets. Les variables globales utilisent 184 octets (8%) de mémoire dynamique, ce qui laisse 1864 octets pour les variables locales. Le maximum est de 2048 octets.
Tipo de variables
Use los tipos correctos de variable. Los tipos variables ocupan espacios de memoria de diferentes tamaños en el microcontrolador.
Aquí hay una tabla resumen de tamaños variables.
Type | Size | Range |
boolean | 1 byte | 0 to 1 |
char | 1 byte | -128 to 127 |
unsigned char | 1 byte | 0 to 255 |
int | 2 bytes | -32,768 to 32,767 |
unsigned int | 2 bytes | 0 to 65,535 |
word | 2 bytes | 0 to 65,535 |
long | 4 bytes | -2,147,483,648 to 2,147483,647 |
unsigned long | 4 bytes | 0 to 4,294,967,295 |
float | 4 bytes | 3.4028235E-38 to 3.4028235E+38 |
double | 4 bytes | 3.4028235E-38 to 3.4028235E+38 |
string | 1 byte + # of chars | N/A |
array | 1 byte + (sizeOfType * # of elements) | N/A |
enum | N/A | N/A |
struct | N/A | N/A |
pointer | N/A | N/A |
void | N/A | N/A |
Para elegir correctamente el tipo de variable, es bueno conocer sus valores extremos y saber qué tipos de operaciones se realizarán en esta variable. Debe elegir el tipo más pequeño para describir la variable y la operación.
Ejemplo: escribir flotante a = analogRead (A0); no tiene sentido porque la función analogRead () devuelve un valor entre 0 y 1023. Por lo tanto, la variable debe ser de tipo unsigned int
Definido como un float
float a; void setup() { Serial.begin(9600); } void loop() { a=analogRead(A0); Serial.print(a); }
Le croquis utilise 2968 octets (9%) de l'espace de stockage de programmes. Le maximum est de 32256 octets. Les variables globales utilisent 196 octets (9%) de mémoire dynamique, ce qui laisse 1852 octets pour les variables locales. Le maximum est de 2048 octets.
Definido como un int
int a; void setup() { Serial.begin(9600); } void loop() { a=analogRead(A0); Serial.print(a); }
Le croquis utilise 1736 octets (5%) de l'espace de stockage de programmes. Le maximum est de 32256 octets. Les variables globales utilisent 184 octets (8%) de mémoire dynamique, ce qui laisse 1864 octets pour les variables locales. Le maximum est de 2048 octets.
Tipo de variable constante
Cuando la variable no se mueva mientras el programa se está ejecutando, use «const» o #define para definir la variable
Variable global o local
Cuando la variable se usa en diferentes funciones, puede ser interesante definirla como global. Si es una variable que solo existe para mostrar un resultado intermedio, es mejor definirlo localmente.
Función F() para visualizar en el monitor serie
Al colocar las cadenas en la función F (), esto ahorra mucho espacio cuando se envía mucha información al monitor en serie.
Ejemplo: Encontré un código en Internet con una cantidad fenomenal de print () (incluso escribí un script de Python para modificar el código para incluir la función F ()). Aquí está el resultado de la compilación:
Le croquis utilise 36966 octets (14%) de l'espace de stockage de programmes. Le maximum est de 253952 octets.
Les variables globales utilisent 6500 octets (79%) de mémoire dynamique, ce qui laisse 1692 octets pour les variables locales. Le maximum est de 8192 octets.
La mémoire disponible faible, des problèmes de stabilité pourraient survenir.
Después de modificar todo Serial.print () y Serial.println () en el script .INO, aquí está el resultado de la compilación:
Le croquis utilise 36770 octets (14%) de l'espace de stockage de programmes. Le maximum est de 253952 octets.
Les variables globales utilisent 4830 octets (58%) de mémoire dynamique, ce qui laisse 3362 octets pour les variables locales. Le maximum est de 8192 octets.
Una reducción del 79 al 58% y más problemas de estabilidad. Más bien práctico.
Use la función millis ()
En principio, debe prohibir el uso de funciones que bloquean la ejecución de código como delay (). Para códigos simples, esto está bien, pero cuando tiene que intentar ejecutar múltiples tareas en paralelo, ya no puede permitírselo.
Existen varias soluciones para hacer sin demora (): millis (), Timer.h, Timer2.h, interupt. Te muestro en este artículo, la solución millis () que es suficiente en la mayoría de los casos, pero no dudes en preguntar sobre los demás.
Aquí hay un ejemplo de un código que lee la entrada analógica A0 cada 500 ms
int a; void setup() { Serial.begin(9600); } void loop() { a=analogRead(A0); Serial.print(a); delay(500); }
Cuando modificamos el código para integrar la función millis (), obtenemos el mismo resultado con, además, la capacidad de hacer algo más durante estos 500 ms
int a; unsigned long previousTime=0; void setup() { Serial.begin(9600); } void loop() { if(millis()-previousTime)>500{ previousTime=millis(); a=analogRead(A0); Serial.print(a); } }
Si conoce otros métodos o mejores prácticas para escribir y mejorar su programa Arduino, no dude en dejar un comentario.
Sources
- https://robotresearchlab.com/2016/11/14/variable-data-types/
Si, muy recomendable seguir las buenas prácticas al programar, sobretodo si la memoria es limitada.