web-dev-qa-db-fra.com

manière correcte d'inclure des fichiers .cpp et .h dans un croquis Arduino

Tout d'abord, le problème:

fichier d'esquisse principal:

char foo;            // required to clean up some other problems
#include <Arduino.h> // tried it in desperation, no help
#include "a.h"

void setup(){
  Serial.begin(9600);
  Serial.println("\nTest begins");
  for (int num = -1; num < 1; num++){
    Serial.print(num);
    if (isNegative(num)){
      Serial.println(" is negative");
    } else {
      Serial.println(" is NOT negative");
    }
  }
}

void loop(){}

// a.h

#ifndef H_A
#define H_A

boolean isNegative(int x);                  // Err#1
int anotherOdity();

#endif // H_A

// a.cpp

#include "a.h"

int isNegative(int x){
  Serial.println("I can't print this from inside my INCLUDE FILE"); //Err#2
  if (x<0) return true;
  return false;
}

int anotherOdity(){
  char ch[5];
  memcpy(ch,"1",1);  //doesn't work, memcpy not declared      // Err#3
}

Ce qui précède, tel quel, ne se compile pas et voici les erreurs que j'obtiens:

In file included from a.cpp:1:
a.h:4: error: 'boolean' does not name a type
a.cpp: In function 'int isNegative(int)':
a.cpp:4: error: 'Serial' was not declared in this scope
a.cpp: In function 'int anotherOdity()':
a.cpp:11: error: 'memcpy' was not declared in this scope

Le premier problème est le type booléen, qui semble souffrir de quelques altérations de noms que l'environnement Arduino fait, mais qui est généralement corrigé par le char foo; Dans le fichier principal. Et dans certaines situations, ça l'est. Mais l'utilisation de ce type dans le fichier .cpp Génère cette erreur.

Je peux voir que les erreurs 2 et 3 sont liées, mais comment les obtenir dans la portée? Je me rends compte qu'une partie du problème est probablement le #include Lui-même (peut-être) parce que Serial et memcpy ne sont pas encore définis/déclarés? J'ai essayé d'inclure la bibliothèque Arduino.h, Mais cela n'a pas aidé. En fait, cela a aidé le problème booléen, mais uniquement dans le cas de tout mettre dans le fichier .h (Comme je l'explique plus loin), cela n'aide pas l'exemple ci-dessus.

Si je rassemble les trois fichiers et que tout est dans le fichier de croquis principal (.ino), Cela fonctionne comme il se doit. Mais l'idée ici est que je veux sortir du code et rendre mon croquis plus lisible.

Le plus proche d'une solution a été trouvé ici: http://liudr.wordpress.com/2011/02/16/using-tabs-in-arduino-ide/ où, après avoir exécuté mon propre tests, j'ai déterminé que si je mettais TOUT dans un fichier .h, ça marche!

Par exemple, en laissant le fichier d'esquisse principal inchangé, si je supprime a.cpp Et que je crée juste a.h (Comme suit) cela fonctionne!

#ifndef H_A
#define H_A

boolean isNegative(int x){
  Serial.println("I can't print this from inside my INCLUDE FILE");
  if (x<0) return true;
  return false;
}

int anotherOdity(){
  char ch[5];
  memcpy(ch,"1",1);  //doesn't work, memcpy not declared
}

#endif // H_A

Cela corrige le problème booléen (enfin ... j'ai toujours besoin de Arduino.h Ou char foo;), Et il résout les problèmes de portée.

Mais c'est juste mal.

Il ne s'agit pas de créer une bibliothèque de fonctions standard que je pourrais utiliser dans divers croquis, il s'agit de diviser mon code en petits morceaux (lisibles) et de les garder tous ensemble dans le dossier du projet. Je veux le faire de la manière la plus correcte possible, il semble que je sois limité par l'IDE. Je suis sûr que j'ai une bonne compréhension de la façon de rassembler un en-tête et le fichier .cpp Associé (j'espère que je ne me suis pas trompé).

Je suis totalement autodidacte avec tout C/C++ et je ne suis vraiment entré dans la programmation que récemment.

J'ai fait des recherches à ce sujet dans les profondeurs de Google et je suis toujours en train de manquer.

Sans recourir à hacks et en gardant les choses simples pour des gens comme moi, comment puis-je assembler au mieux les exemples ci-dessus pour que l'Arduino IDE/gcc le compile?

edit: Je pensais que j'inclurais juste CERTAINS des onglets que j'ai ouverts ici pour montrer que j'ai vraiment fait des recherches à ce sujet!

http://arduino.cc/en/Reference/Include

http://arduino.cc/en/Hacking/LibraryTutorial

http://forum.arduino.cc/index.php/topic,124904.msg938861.html#msg938861

http://forum.arduino.cc/index.php?topic=84412. (c'est là que j'ai trouvé la solution char foo;)

http://liudr.wordpress.com/2011/02/16/using-tabs-in-arduino-ide/

y compris les fichiers .cpp

Garder toutes les bibliothèques dans le répertoire de croquis Arduino

En-tête C++ et CPP inclus

12
Madivad

La raison pour laquelle cela ne fonctionne pas est que vous devez inclure quelque chose dans vos fichiers a.h ou a.cpp.

Essayez ceci dans votre fichier a.h et alors tout devrait fonctionner.

#ifndef H_A
#define H_A

#include <Arduino.h> //needed for Serial.println
#include <string.h> //needed for memcpy

...

La raison en est que vous pouvez penser que le compilateur compile séparément chaque fichier cpp. Un #include n'est en fait qu'un copier-coller automatisé. Lorsque le compilateur vient de compiler a.cpp, il ne sait pas que Serial.println () existe, car il n'a pas été défini dans a.h, qui est le seul autre texte qui apparaît dans a.cpp. La raison pour laquelle cela fonctionne lorsque vous mettez tout cela dans l'en-tête est que dans votre fichier cpp principal, vous avez inclus Arduino.h avant l'inclusion ah, donc une fois que ces #includes ont été copiés collés dans son comme si vous veniez d'écrire le code dans la première place.

Vous pouvez simplement écrire tout votre code dans les en-têtes, mais ce n'est pas conseillé pour diverses raisons, notamment l'efficacité au moment de la compilation (mais comme un programme Arduino ne peut faire que 32 Ko, je ne pense pas que les temps de compilation vont devenir trop longs!)

20
user2711915