2017-05-17 37 views
0

我想讓我的Arduino類返回帶有各種記錄信息的String消息。有了大量的試驗和錯誤,我設法將對日誌記錄功能的引用傳遞給類,但只能得到一個char *而不是一個字符串,並且我希望能夠發送字符串,以便更容易地發回所有字符串各種數據。Arduino:傳遞函數給類,返回字符串

我已經有第一部分工作了。 草圖:

#include <Test.h> 
#include <string.h> 

void setup() { 
    Serial.begin(115200); 
    Test t; 
    t.setLogging(writeLog); 
    writeLog("Test message!" + String(" .... ")); 
    t.doSomething("This is useful."); 
    t.doSomething("This as well.\n"); 
    t.doSomething("This is even more useful.\n"); 
    bool b = true; 

} 

void loop() { 
} 

void writeLog (char* message) { 
    Serial.print("char function: "); 
    Serial.print(message); 
} 

void writeLog (String message) { 
    Serial.print("String function: "); 
    Serial.println(message); 
} 

頭文件:

#ifndef TEST_h 
#define TEST_h 

class Test 
{ 
    public: 
    Test();  // The constructor. 
    void setLogging(void (*)(char*)); // Takes function setting where to log. 
    void doSomething(char*); 
}; 

#endif 

類:

#include <Test.h> 

typedef void (*LogFunction)(char*); 
LogFunction writeLog; 

Test::Test() { 
} 

void Test::doSomething (char* s) { 

    // Do something useful and log the result. 
    writeLog(s); 
} 

void Test::setLogging (void (*f)(char*)) { 
    writeLog = f; 
    return; 
} 

現在我想我的同班同學能夠做的就是發送信息這樣的,因爲字符串,而不是char *(我還沒有找到一種簡單的方式將「anything」轉換爲char *,然後連接兩個或多個字符串):

writeLog ("HydroMonitorECSensor::setCalibration Receiving calibration - haveCalibration = " + String(haveCalibration)); 
writeLog ("HydroMonitorECSensor::setCalibration calibratedSlope = " + String(calibratedSlope)); 
writeLog ("HydroMonitorECSensor::setPins capPos set to " + String(capPos)); 

haveCalibrationbool(其作爲字符串變爲:「真」或「假」),calibratedSlopedoublecapPosint。這樣我就可以輕鬆乾淨地將完整的線路發送到記錄器。主要內容非常有效 - 不是來自課堂。

我試圖簡單地將char*更改爲String並將#include <string.h>添加到庫文件,但它不起作用。

在Test.cpp的我然後得到void Test::setLogging (void (*f)(String)) {和Test.h void setLogging(void (*)(String));,現在我得到的錯誤信息:

In file included from /home/wouter/Arduino/libraries/Test/Test.cpp:1:0: 
/home/wouter/Arduino/libraries/Test/Test.h:10:29: error: expected ',' or '...' before '(' token 
    void setLogging(void (*)(String)); // Takes function setting where to log. 
          ^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:40: error: variable or field 'setLogging' declared void 
void Test::setLogging (void (*f)(String)) { 
             ^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:31: error: 'f' was not declared in this scope 
void Test::setLogging (void (*f)(String)) { 
          ^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:34: error: 'String' was not declared in this scope 
void Test::setLogging (void (*f)(String)) { 
           ^
exit status 1 
Error compiling for board NodeMCU 1.0 (ESP-12E Module). 

建議?

附加信息,也許很重要:我使用Arduino IDE並編譯爲ESP8266。

回答

2

您正在使用Arduino提供的String類,但在您的test.h頭文件中未包含Arduino.h標頭。這會導致它找不到String類,編譯失敗。

以下工作:

main.cpp

#include <Arduino.h> 
#include <test.hpp> 

void writeLog (char* message); 
void writeLog (String message); 

void setup() { 
    Serial.begin(115200); 
    Test t; 
    t.setLogging(writeLog); 
    writeLog("Test message!" + String(" .... ")); 
    t.doSomething("This is useful."); 
    t.doSomething("This as well.\n"); 
    t.doSomething("This is even more useful.\n"); 
    bool b = true; 

} 

void loop() { 
} 

void writeLog (char* message) { 
    Serial.print("char function: "); 
    Serial.print(message); 
} 

void writeLog (String message) { 
    Serial.print("String function: "); 
    Serial.println(message); 
} 

test.hpp

#ifndef TEST_h 
#define TEST_h 

#include <Arduino.h> //for "String" class 

//Typdef for the log function. Takes a String, returns nothing 
typedef void (*LogFunction)(String); 

class Test 
{ 
    public: 
    Test();  // The constructor. 
    // void setLogging(void (*)(char*)); // Takes function setting where to log. 
    void setLogging(LogFunction); //use the typedef here 
    void doSomething(char*); 
}; 

#endif 

test.cpp

#include <test.hpp> 


LogFunction writeLog; 

Test::Test() { 
} 

void Test::doSomething (char* s) { 

    // Do something useful and log the result. 
    writeLog(s); 
} 

//void Test::setLogging (void (*f)(char*)) { 
void Test::setLogging (LogFunction f) { //also use typedef here 
    writeLog = f; 
    return; 
} 
+0

是的,這個工程!實際上我曾嘗試添加Arduino.h include,但一定是做了其他的錯誤,因爲它不起作用。在我的主要草圖中,我也沒有包括但它仍然編譯,從來不需要這個Arduino.h,不知道如何工作...感謝您的快速回答。 – Wouter

+0

想一想,我可能沒有嘗試包含'Arduino.h',不太確定,因爲我嘗試了很多,最後感到完全失望,試圖這樣做,沒有任何工作,但我肯定嘗試過包含'string.h'。後者畢竟是我在普通草圖中需要的,以便能夠使用'String'類型。 – Wouter

0

在可能出現的其他事情中,編譯器告訴您它無法解析標識符String。 這可能有幾個原因:首先,你寫String,而不是string(注意寫作時的大寫字母)。其次,如果您編寫的是string而不是std::string,則除非您聲明using namespace std(由於多種原因,這不是首選變體)或using std::string,否則無法解析。第三,類std::string在標頭<string>中聲明,與<string.h>不同。

所以我會寫#include <string>然後使用std::string

+2

這將使用Arduino的'String'類,不是'std :: string'。 –

+1

這是標準C/C++和Arduino之間的區別(發佈的代碼在Arduino IDE中編譯得很好)。字符串是Arduino版本,std :: string是C版本,兩者不兼容。我其實試過std :: string並沒有得到它的工作。 – Wouter

+0

@Maximilian Gerhardt:好的;我認爲OP的目標是C++ - 字符串類。 +1指出了這一點。順便說一句:爲什麼不會std :: string不起作用? –