Pourquoi ne puis-je pas déclarer une classe dans un autre onglet dans Arduino IDE?

20

Je voulais déplacer une partie de mon code dans un deuxième onglet de l'IDE Arduino, pour garder les choses mieux organisées. Au début, j'ai seulement essayé de déplacer une fonction, et cela semblait bien fonctionner. Je pouvais appeler la fonction à partir de la setup()fonction dans mon onglet principal, et il n'y avait aucun problème de compilation ou de téléchargement.

Cependant, j'ai essayé de mettre toute une classe dans le deuxième onglet, et soudain, cela n'a plus fonctionné. Par exemple:

Tab 1:

TestClass obj;

void setup()
{
    obj.init();
}

void loop()
{
    //...
}

Tab 2:

class TestClass
{
public:
    void init()
    {
        //...
    }
};

Lorsque j'ai essayé de compiler cela, cela m'a donné les erreurs suivantes:

tab1:1: error: 'TestClass' does not name a type
tab1.ino: In function 'void setup()':
tab1:5: error: 'obj' was not declared in this scope

Pourquoi reconnaît-il une fonction dans un autre onglet, mais pas une classe? Existe-t-il un moyen de le faire fonctionner dans l'IDE Arduino, ou dois-je utiliser une alternative comme Eclipse?

Peter Bloomfield
la source
Est-ce l'intégralité du code? Quels sont les noms de fichiers? N'y a-t-il pas de directives de préprocesseur comme #include?
asheeshr
Oui, c'est l'intégralité du code. Les onglets sont nommés tab1et tab2respectivement. Les noms ont été définis à l'aide de l'EDI, les fichiers sous-jacents sont donc les deux .ino.
Peter Bloomfield
Je commence à détester le pokery jiggery que l'IDE Arduino fait. Ce qu'il ajoute dans la facilité d'utilisation par rapport à l'AVR, il enlève en cassant des choses comme ça.
Cybergibbons

Réponses:

13

Il n'est pas possible de déclarer et d'utiliser des classes déclarées dans un .pdefichier dans un autre.pde fichier à partir de l'IDE Arduino.

Une solution de contournement consiste à transformer le deuxième fichier en fichier source C ++ ( .cpp), puis à ajouter une #include "<filename>"directive au début du premier fichier.


Ce code se compile correctement:

Tab 1:

#include "test.cpp"

TestClass obj;

void setup()
{
    obj.init();
}

void loop()
{
    //...
}

test.cpp:

class TestClass
{
public:
    void init()
    {
        //...
    }
};
asheeshr
la source
Merci pour la solution de contournement. Cela fonctionne pour l'exemple de base, mais malheureusement, cela ne fonctionne pas si j'ajoute des appels spécifiques à Arduino dans le fichier .cpp. Par exemple, si TestClass::init()essaie d'appeler pinMode(), le compilateur se plaint qui pinModen'a pas été déclaré dans cette étendue. Existe-t-il un moyen d'accéder aux fonctions Arduino dans ma classe?
Peter Bloomfield
6
@ PeterR.Bloomfield Ajoutez un #include <Arduino.h>en haut du .cppfichier.
asheeshr
1
Je pense que ce n'est pas bon d'apprendre aux autres à inclure des fichiers source ( #include "test.cpp"). Cela fonctionne, mais peut freiner la compréhension du processus de liaison. Seuls les fichiers d'en-tête doivent être inclus.
Mars
1
Je suis d'accord avec @Mars - une meilleure solution consiste à placer la déclaration de classe dans un fichier .h et la définition (implémentation) dans un fichier .cpp. Vous avez donc deux fichiers supplémentaires dans le projet. C'est en fait la façon normale de gérer les classes.
Nick Gammon
6

La façon dont Arduino IDE fonctionne est qu'il compile votre code (le code que vous écrivez dans l'IDE) comme code "principal". Il extrait ensuite le code de toutes les bibliothèques que vous avez importées et le compile avec le code principal. Pour faire ce que vous proposez, il vous faudrait créer une bibliothèque pour Arduino.

Voici quelques informations supplémentaires sur les bibliothèques Arduino:

http://arduino.cc/en/Guide/Libraries

Et voici quelques-unes sur la façon de créer une bibliothèque:

http://arduino.cc/en/Hacking/LibraryTutorial // celui-ci est le plus facile à comprendre imo
http://playground.arduino.cc/Code/Library
http://www.divilabs.com/2013/03/ écrivez-votre-bibliothèque-arduino.html #

Voici un exemple de bibliothèque que j'ai écrite https://github.com/jamolnng/Arduino/tree/master/libraries/ShiftRegister comme vous pouvez le voir, il n'y a aucun problème avec l'appel des fonctions Arduino à partir du fichier .cpp (je sais, j'ai testé la bibliothèque)

Jesse Laning
la source
3
Il est également possible de simplement créer .het de .cppfichiers dans votre projet principal, sans avoir à créer une bibliothèque distincte.
microtherion