Como o IDE organiza as coisas
Primeiro, é assim que o IDE organiza seu "esboço":
- O principal
.ino
arquivo é a do mesmo nome que a pasta está em Então, por. foobar.ino
Na foobar
pasta - o arquivo principal é foobar.ino.
- Quaisquer outros
.ino
arquivos nessa pasta são concatenados juntos, em ordem alfabética, no final do arquivo principal (independentemente de onde o arquivo principal está, em ordem alfabética).
- Este arquivo concatenado se torna um
.cpp
arquivo (por exemplo foobar.cpp
) . É colocado em uma pasta de compilação temporária.
- O pré-processador "útil" gera protótipos de funções para as funções encontradas nesse arquivo.
- O arquivo principal é verificado quanto a
#include <libraryname>
diretivas. Isso aciona o IDE para copiar também todos os arquivos relevantes de cada biblioteca (mencionada) na pasta temporária e gerar instruções para compilá-los.
- Nenhum
.c
, .cpp
ou .asm
arquivos na pasta esboço são adicionados ao processo de construção de unidades de compilação separadas (isto é, eles são compilados na forma usual como arquivos separados)
- Todos os
.h
arquivos também são copiados para a pasta de compilação temporária, para que possam ser referidos pelos arquivos .c ou .cpp.
- O compilador adiciona aos arquivos padrão do processo de compilação (como
main.cpp
)
- O processo de compilação compila todos os arquivos acima em arquivos de objetos.
- Se a fase de compilação for bem-sucedida, eles serão vinculados juntamente com as bibliotecas padrão do AVR (por exemplo, fornecendo a você
strcpy
etc.)
Um efeito colateral de tudo isso é que você pode considerar o esboço principal (os arquivos .ino) em C ++ para todos os efeitos. A geração do protótipo da função, no entanto, pode levar a mensagens de erro obscuras, se você não tomar cuidado.
Evitando as peculiaridades do pré-processador
A maneira mais simples de evitar essas idiossincrasias é deixar o esboço principal em branco (e não usar outros .ino
arquivos). Em seguida, crie outra guia (um .cpp
arquivo) e coloque suas coisas assim:
#include <Arduino.h>
// put your sketch here ...
void setup ()
{
} // end of setup
void loop ()
{
} // end of loop
Observe que você precisa incluir Arduino.h
. O IDE faz isso automaticamente para o esboço principal, mas para outras unidades de compilação, você precisa fazer isso. Caso contrário, ele não saberá sobre coisas como String, os registros de hardware, etc.
Evitando o paradigma de configuração / principal
Você não precisa executar o conceito de configuração / loop. Por exemplo, seu arquivo .cpp pode 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
Forçar a inclusão da biblioteca
Se você executar com o conceito "esboço vazio", ainda precisará incluir bibliotecas usadas em outras partes do projeto, por exemplo, no .ino
arquivo principal :
#include <Wire.h>
#include <SPI.h>
#include <EEPROM.h>
Isso ocorre porque o IDE verifica apenas o arquivo principal quanto ao uso da biblioteca. Efetivamente, você pode considerar o arquivo principal como um arquivo de "projeto" que indica quais bibliotecas externas estão em uso.
Problemas de nomeação
Não nomeie seu esboço principal como "main.cpp" - o IDE inclui seu próprio main.cpp, assim você terá uma duplicata se fizer isso.
Não nomeie seu arquivo .cpp com o mesmo nome que o arquivo .ino principal. Como o arquivo .ino se torna efetivamente um arquivo .cpp, isso também gera um conflito de nome.
Declarar uma classe de estilo C ++ no mesmo arquivo .ino único (já ouviu falar, mas nunca viu funcionar - isso é possível?);
Sim, isso compila OK:
class foo {
public:
};
foo bar;
void setup () { }
void loop () { }
No entanto, é melhor você seguir a prática normal: Coloque suas declarações em .h
arquivos e suas definições (implementações) em .cpp
(ou .c
) arquivos.
Por que "provavelmente"?
Como meu exemplo mostra, você pode juntar tudo em um arquivo. Para projetos maiores, é melhor ser mais organizado. Eventualmente, você chega ao estágio em um projeto de médio a grande porte, no qual deseja separar as coisas em "caixas pretas" - ou seja, uma classe que faz uma coisa, faz bem, é testada e é independente ( o mais longe possível).
Se essa classe for usada em vários outros arquivos no seu projeto, é nesse ponto que os arquivos .h
e os .cpp
arquivos separados entram em cena.
O .h
arquivo declara a classe - ou seja, fornece detalhes suficientes para outros arquivos saberem o que fazem, quais funções têm e como são chamados.
O .cpp
arquivo define (implementa) a classe - ou seja, na verdade fornece as funções e os membros estáticos da classe que fazem com que a classe faça seu trabalho. Como você deseja implementá-lo apenas uma vez, isso está em um arquivo separado.
O .h
arquivo é o que é incluído em outros arquivos. O .cpp
arquivo é compilado uma vez pelo IDE para implementar as funções da classe.
Bibliotecas
Se você seguir esse paradigma, estará pronto para mover a classe inteira (os arquivos .h
e .cpp
) para uma biblioteca com muita facilidade. Em seguida, ele pode ser compartilhado entre vários projetos. Tudo o que é necessário é criar uma pasta (por exemplo, myLibrary
) e colocar os arquivos .h
e .cpp
(por exemplo, myLibrary.h
e myLibrary.cpp
) e, em seguida, colocar essa pasta dentro da sua libraries
pasta na pasta em que seus esboços são mantidos (a pasta do caderno de rascunhos).
Reinicie o IDE e agora ele conhece essa biblioteca. Isso é realmente trivialmente simples e agora você pode compartilhar esta biblioteca em vários projetos. Eu faço muito isso.
Um pouco mais detalhadamente aqui .