Dlaczego nie mogę zadeklarować klasy w innej zakładce w Arduino IDE?

20

Chciałem przenieść część mojego kodu do drugiej zakładki w Arduino IDE, aby lepiej zorganizować. Na początku próbowałem tylko przenieść funkcję i wydawało się, że działa dobrze. Mogłem wywołać funkcję z setup()funkcji na mojej karcie głównej i nie wystąpiły problemy z kompilacją lub przesyłaniem.

Próbowałem jednak umieścić całą klasę w drugiej zakładce i nagle przestało to działać. Na przykład:

Zakładka 1:

TestClass obj;

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

void loop()
{
    //...
}

Zakładka 2:

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

Kiedy próbowałem to skompilować, wystąpiły następujące błędy:

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

Dlaczego rozpoznaje funkcję na innej karcie, ale nie klasę? Czy istnieje sposób, aby działał w Arduino IDE, czy też muszę używać alternatywy takiej jak Eclipse?

Peter Bloomfield
źródło
Czy to cały kod? Jakie są nazwy plików? Czy nie ma takich dyrektyw preprocesora #include?
asheeshr
Tak, to jest cały kod. Karty mają odpowiednio nazwy tab1i nazwy tab2. Nazwy zostały ustawione za pomocą IDE, więc oba pliki leżą u podstaw .ino.
Peter Bloomfield
Zaczynam nienawidzić jiggery pokery, jaką robi Arduino IDE. To, co dodaje łatwości użycia w stosunku do AVR, zabiera w łamaniu takich rzeczy.
Cybergibbons,

Odpowiedzi:

13

Nie można zadeklarować ani używać klas zadeklarowanych w jednym .pdepliku w innym .pdepliku z poziomu Arduino IDE.

Jednym obejściem jest przekształcenie drugiego pliku w plik źródłowy C ++ ( .cpp), a następnie dodanie #include "<filename>"dyrektywy na początku pierwszego pliku.


Ten kod kompiluje się poprawnie:

Zakładka 1:

#include "test.cpp"

TestClass obj;

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

void loop()
{
    //...
}

test.cpp:

class TestClass
{
public:
    void init()
    {
        //...
    }
};
asheeshr
źródło
Dzięki za obejście. Działa dla podstawowego przykładu, ale niestety nie działa, jeśli dodam jakieś wywołania specyficzne dla Arduino w pliku .cpp. Na przykład, jeśli TestClass::init()próbuje zadzwonić pinMode(), kompilator skarży się, że pinModenie został zadeklarowany w tym zakresie. Czy jest sposób na dostęp do funkcji Arduino w mojej klasie?
Peter Bloomfield
6
@ PeterR.Bloomfield Dodaj #include <Arduino.h>do góry .cpppliku.
asheeshr
1
Myślę, że nie warto uczyć innych, jak dołączać pliki źródłowe ( #include "test.cpp"). Działa, ale może hamować zrozumienie procesu łączenia. Należy dołączyć tylko pliki nagłówków.
Mars,
1
Zgadzam się z @Mars - lepszym rozwiązaniem jest umieszczenie deklaracji klasy w pliku .h, a definicji (implementacji) w pliku .cpp. Masz więc dwa dodatkowe pliki w projekcie. Jest to w rzeczywistości normalny sposób obsługi klas.
Nick Gammon
6

Sposób działania Arduino IDE polega na tym, że kompiluje on Twój kod (kod napisany w IDE) jako „główny” kod. Następnie pobiera kod ze wszystkich zaimportowanych bibliotek i kompiluje go wraz z kodem głównym. Robienie tego, co sugerujesz, wymagałoby utworzenia biblioteki dla Arduino.

Oto kilka informacji o bibliotekach Arduino:

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

A oto kilka sposobów tworzenia biblioteki:

http://arduino.cc/en/Hacking/LibraryTutorial // ten jest najłatwiejszy do zrozumienia imo
http://playground.arduino.cc/Code/Library
http://www.divilabs.com/2013/03/ write-your-own-arduino-library.html #

Oto przykładowa biblioteka, którą napisałem https://github.com/jamolnng/Arduino/tree/master/libraries/ShiftRegister, jak widać, nie ma problemu z wywoływaniem funkcji Arduino z pliku .cpp (wiem, mam przetestowałem bibliotekę)

Jesse Laning
źródło
3
Możliwe jest także tworzenie .hi tworzenie .cppplików w głównym projekcie bez konieczności tworzenia osobnej biblioteki.
microtherion