Como o IDE organiza as coisas
Primeiro, é assim que o IDE organiza seu "esboço":
- O principal
.inoarquivo é a do mesmo nome que a pasta está em Então, por. foobar.inoNa foobarpasta - o arquivo principal é foobar.ino.
- Quaisquer outros
.inoarquivos 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
.cpparquivo (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, .cppou .asmarquivos 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
.harquivos 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ê
strcpyetc.)
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 .inoarquivos). Em seguida, crie outra guia (um .cpparquivo) 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 .inoarquivo 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 .harquivos 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 .he os .cpparquivos separados entram em cena.
O .harquivo 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 .cpparquivo 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 .harquivo é o que é incluído em outros arquivos. O .cpparquivo é 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 .he .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 .he .cpp(por exemplo, myLibrary.he myLibrary.cpp) e, em seguida, colocar essa pasta dentro da sua librariespasta 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 .