Cómo organiza las cosas el IDE
Primero, así es como el IDE organiza su "boceto":
- El
.ino
archivo principal tiene el mismo nombre que la carpeta en la que se encuentra. Por lo tanto, foobar.ino
en la foobar
carpeta, el archivo principal es foobar.ino.
- Todos los demás
.ino
archivos de esa carpeta se concatenan juntos, en orden alfabético, al final del archivo principal (independientemente de dónde esté el archivo principal, alfabéticamente).
- Este archivo concatenado se convierte en un
.cpp
archivo (p. Ej. foobar.cpp
), Se coloca en una carpeta de compilación temporal.
- El preprocesador "útilmente" genera prototipos de funciones para las funciones que encuentra en ese archivo.
- El archivo principal se analiza en busca de
#include <libraryname>
directivas. Esto activa el IDE para copiar también todos los archivos relevantes de cada biblioteca (mencionada) en la carpeta temporal y generar instrucciones para compilarlos.
- Cualquiera
.c
, .cpp
o los .asm
archivos en la carpeta de croquis se agregan al proceso de compilación como unidades de compilación separadas (es decir, se compilan de la manera habitual como archivos separados)
- Todos los
.h
archivos también se copian en la carpeta de compilación temporal, por lo que sus archivos .c o .cpp pueden consultarlos.
- El compilador agrega al proceso de compilación archivos estándar (como
main.cpp
)
- El proceso de compilación luego compila todos los archivos anteriores en archivos de objetos.
- Si la fase de compilación tiene éxito, se vinculan entre sí junto con las bibliotecas estándar de AVR (p. Ej., Ofreciéndole,
strcpy
etc.)
Un efecto secundario de todo esto es que puede considerar que el boceto principal (los archivos .ino) es C ++ a todos los efectos. Sin embargo, la generación del prototipo de la función puede generar mensajes de error oscuros si no tiene cuidado.
Evitar las peculiaridades del preprocesador
La forma más sencilla de evitar estas idiosincrasias es dejar su boceto principal en blanco (y no usar ningún otro .ino
archivo). Luego crea otra pestaña (un .cpp
archivo) y coloca tus cosas en ella de esta manera:
#include <Arduino.h>
// put your sketch here ...
void setup ()
{
} // end of setup
void loop ()
{
} // end of loop
Tenga en cuenta que debe incluir Arduino.h
. El IDE lo hace automáticamente para el boceto principal, pero para otras unidades de compilación, debe hacerlo. De lo contrario, no sabrá cosas como String, los registros de hardware, etc.
Evitar la configuración / paradigma principal
No tiene que ejecutar con el concepto de configuración / bucle. Por ejemplo, su archivo .cpp puede ser:
#include <Arduino.h>
int main ()
{
init (); // initialize timers
Serial.begin (115200);
Serial.println ("Hello, world");
Serial.flush (); // let serial printing finish
} // end of main
Forzar inclusión de biblioteca
Si ejecuta con el concepto de "boceto vacío" aún necesita incluir bibliotecas utilizadas en otros lugares del proyecto, por ejemplo, en su .ino
archivo principal :
#include <Wire.h>
#include <SPI.h>
#include <EEPROM.h>
Esto se debe a que el IDE solo escanea el archivo principal para el uso de la biblioteca. Efectivamente, puede considerar el archivo principal como un archivo de "proyecto" que designa qué bibliotecas externas están en uso.
Problemas de nombres
No nombre su boceto principal "main.cpp": el IDE incluye su propio main.cpp, por lo que tendrá un duplicado si lo hace.
No asigne un nombre a su archivo .cpp con el mismo nombre que su archivo .ino principal. Dado que el archivo .ino se convierte efectivamente en un archivo .cpp, esto también le daría un choque de nombres.
Declarar una clase de estilo C ++ en el mismo archivo .ino único (he oído hablar de él, pero nunca lo he visto funcionar, ¿es eso posible?);
Sí, esto compila OK:
class foo {
public:
};
foo bar;
void setup () { }
void loop () { }
Sin embargo, probablemente sea mejor que siga la práctica normal: coloque sus declaraciones en .h
archivos y sus definiciones (implementaciones) en .cpp
(o .c
) archivos.
¿Por qué "probablemente"?
Como muestra mi ejemplo, puedes juntar todo en un solo archivo. Para proyectos más grandes es mejor estar más organizado. Finalmente, llega al escenario en un proyecto de tamaño mediano a grande donde desea separar las cosas en "cajas negras", es decir, una clase que hace una cosa, lo hace bien, se prueba y es autónoma ( tan lejos como sea posible).
Si esta clase se usa en varios otros archivos en su proyecto, aquí es donde entran en juego los archivos separados .h
y .cpp
.
El .h
archivo declara la clase, es decir, proporciona detalles suficientes para que otros archivos sepan qué hace, qué funciones tiene y cómo se llaman.
El .cpp
archivo define (implementa) la clase, es decir, en realidad proporciona las funciones y los miembros de clase estáticos que hacen que la clase haga lo suyo. Como solo desea implementarlo una vez, esto está en un archivo separado.
El .h
archivo es lo que se incluye en otros archivos. El .cpp
IDE compila el archivo una vez para implementar las funciones de clase.
Bibliotecas
Si sigue este paradigma, entonces está listo para mover toda la clase (los archivos .h
y .cpp
) a una biblioteca muy fácilmente. Luego se puede compartir entre múltiples proyectos. Todo lo que se requiere es hacer una carpeta (p. Ej. myLibrary
) Y poner los archivos .h
y .cpp
en ella (p. Ej. myLibrary.h
Y myLibrary.cpp
) y luego poner esta carpeta dentro de su libraries
carpeta en la carpeta donde se guardan sus bocetos (la carpeta del cuaderno de bocetos).
Reinicie el IDE y ahora sabe sobre esta biblioteca. Esto es realmente trivialmente simple, y ahora puede compartir esta biblioteca en múltiples proyectos. Lo hago mucho.
Un poco más de detalle aquí .