简体   繁体   English

您可以继承 HttpClient 并创建自己的自定义 Arduino 库吗?

[英]Can you inherit HttpClient and create your own custom Arduino library?

I used some example code to create a working sketch of a HttpClient sending JSON from a Uno rv2 to a C# api.我使用了一些示例代码来创建 HttpClient 的工作草图,该草图将 JSON 从 Uno rv2 发送到 C# api。 All good.都好。

Next was planning to add this to a sketch to send same JSON using the Sparkfun weather shield.接下来计划将此添加到草图中,以使用 Sparkfun 天气盾发送相同的 JSON。 I thought to keep the shield code cleaner I'd create a custom library inheriting the HttpClient and just pass the WifiClient, serverName, port and wifi credentials in at the constructor.我想保持屏蔽代码更干净,我会创建一个继承 HttpClient 的自定义库,并在构造函数中传递 WifiClient、serverName、端口和 wifi 凭据。

I haven't done a lot of C, C++ for 20 odd years.我已经有 20 多年没有做过很多 C、C++ 了。 Is what I'm trying to do possible?我正在尝试做的可能吗? Or am I just very rusty and haven't figured it out yet.或者我只是很生疏,还没有弄清楚。 (Probably should have picked something simpler for my first try at a custom library) (我第一次尝试自定义库时可能应该选择更简单的东西)

If it is possible I'm guessing I've buggered up the constructors and have tried many variations on a theme with no result.如果可能的话,我猜我已经搞砸了构造函数,并在一个主题上尝试了许多变体,但没有结果。

Appreciate any insights.欣赏任何见解。

UPDATE: So I have made some changes buit I'm still getting compile errors I was told to add virtual methods of inherited class (HttpClient) which I've done but I'm still getting compile issues.更新:所以我做了一些更改,但我仍然遇到编译错误 我被告知要添加我已经完成的继承类(HttpClient)的虚拟方法,但我仍然遇到编译问题。 Errors attached.错误附加。

Here's my header.这是我的标题。

#ifndef SPARKFUN_WIFI
#define SPARKFUN_WIFI

#include <ArduinoJson.h>
#include <b64.h>
#include <HttpClient.h>
#include <URLEncoder.h>
#include <WebSocketClient.h>
#include <WiFiNINA.h>
#include "arduino.h"
#include <ArduinoHttpClient.h>

class SparkfunWifi : public HttpClient { 

    public:
    // Contructor
    
    /** Connect to the server and start to send a GET request.
        @param serverName The server name to conect to.
        @param port The port number.
        @param ssid The network ssid.
        @param pass The network password.
    */
    SparkfunWifi(Client& client, char* serverName, char* port, char* ssid, char* pass);
    
    // Methods

    /** Connect to the server and start to send a GET request.
        @return true if connection successful
    */
    bool connectWifi();

    /** Sends HTTP weather POST to weather.api.
        @return 200 if successful response from api.
    */
    int sendWeather();

    virtual bool endOfStream() { return endOfBodyReached(); };
    virtual bool completed() { return endOfBodyReached(); };

    // Inherited from HttpClient which inherited them from Print
    // Note: 1st call to these indicates the user is sending the body, so if need
    // Note: be we should finish the header first
    virtual size_t write(uint8_t aByte) { if (iState < eRequestSent) { finishHeaders(); }; return iClient-> write(aByte); };
    virtual size_t write(const uint8_t *aBuffer, size_t aSize) { if (iState < eRequestSent) { finishHeaders(); }; return iClient->write(aBuffer, aSize); };
    // Inherited from Stream
    virtual int available();
    /** Read the next byte from the server.
      @return Byte read or -1 if there are no bytes available.
    */
    virtual int read();
    virtual int read(uint8_t *buf, size_t size);
    virtual int peek() { return iClient->peek(); };
    virtual void flush() { iClient->flush(); };

    // Inherited from Client
    virtual int connect(IPAddress ip, uint16_t port) { return iClient->connect(ip, port); };
    virtual int connect(const char *host, uint16_t port) { return iClient->connect(host, port); };
    virtual void stop();
    virtual uint8_t connected() { return iClient->connected(); };
    virtual operator bool() { return bool(iClient); };
    virtual uint32_t httpResponseTimeout() { return iHttpResponseTimeout; };
    virtual void setHttpResponseTimeout(uint32_t timeout) { iHttpResponseTimeout = timeout; };
    
    private:

    int _serverName;
    int _status;
    char* _ssid;
    char* _pass;

};
#endif

And the .cpp和 .cpp

// inlcludes
#include "arduino.h"
#include "SparkfunWifi.h"

// constructor
SparkfunWifi::SparkfunWifi(Client& client, char* serverName, int port, char* ssid, char* pass)
    : client(client), serverName(serverName), serverAddress(), serverPort(port),
   iConnectionClose(true), iSendDefaultRequestHeaders(true)
{
    _ssid = ssid;
    _pass = pass;
    _status != WL_CONNECTED;
}

bool SparkfunWifi::connectWifi(){
    Serial.begin(9600);
    int times = 1;
    while (_status != WL_CONNECTED) {
        times++;
        if (times <= 5){
            // attempt to connect 5 times
            Serial.println("Attempting to connect to Network named: ");
            Serial.println(_ssid);   // print the network name (SSID);
            Serial.println("Attempt:");   // print the network name (SSID);
            Serial.println(times);   // print the network name (SSID);
        
            // Connect to WPA/WPA2 network:
            _status = WiFi.begin(_ssid, _pass);
            Serial.print("SSID: ");
            Serial.println(WiFi.SSID());
            // print your WiFi shield's IP address:
            IPAddress ip = WiFi.localIP();
            Serial.print("IP Address: ");
            Serial.println(ip);
            return true;
        }
        else 
        {
            Serial.print("Could not connect on 5th attempt to: ");
            Serial.println(_ssid);   // print the network name (SSID);
            return false;
        }
    }
}

int SparkfunWifi::sendWeather() {
    Serial.println("making POST request to " + _serverName);
    client.beginRequest();
    StaticJsonDocument<500> doc; // create a JSON document
    doc["temp"] = "33.2";  // add the temperature elememnt and value                                  
    doc["humidity"] = "95.2";  // add the humidity elememnt and value                                  
    client.post("/addWeather"); // call the weather api post operation
    client.sendHeader("Content-Type", "application/json"); // send content type and legnth headers 
    client.sendHeader("Content-Length", measureJsonPretty(doc));
    client.beginBody(); // send the JSON 
    serializeJsonPretty(doc, Serial);
    serializeJsonPretty(doc, client);
    client.endRequest(); // end http request

    // read the status code and body of the response
    int statusCode = client.responseStatusCode();
    String response = client.responseBody();
 
    return statusCode;
}

Finally my sketch .ino最后我的草图 .ino

// inlcludes
#include "arduino_secrets.h"
#include "SparkfunWifi.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
/////// Wifi Settings ///////
char* ssid = SECRET_SSID;
char* pass = SECRET_PASS;

char serverName[] = "dionysus";  // server address
int port = 5000; // port number

WiFiClient wifi;
SparkfunWifi client(wifi, serverName, port, ssid, pass);

void setup() {
    client.connectWifi();
}

void loop() {
  Serial.println("Send weather...");
  client.sendWeather();
  Serial.println("Wait five seconds");
  delay(5000);
}

Here's the error output这是错误输出

SparkfunWifi.cpp:6:1: error: prototype for 'SparkfunWifi::SparkfunWifi(arduino::Client&, char*, int, char*, char*)' does not match any in class 'SparkfunWifi'

 SparkfunWifi::SparkfunWifi(Client& client, char* serverName, int port, char* ssid, char* pass)

 ^~~~~~~~~~~~

In file included from sketch\SparkfunWifi.cpp:3:0:

SparkfunWifi.h:13:7: error: candidates are: SparkfunWifi::SparkfunWifi(SparkfunWifi&&)

 class SparkfunWifi : public HttpClient {

       ^~~~~~~~~~~~

SparkfunWifi.h:13:7: error: SparkfunWifi::SparkfunWifi(const SparkfunWifi&)

SparkfunWifi.h:24:5: error: SparkfunWifi::SparkfunWifi(arduino::Client&, char*, char*, char*, char*)

     SparkfunWifi(Client& client, char* serverName, char* port, char* ssid, char* pass);

     ^~~~~~~~~~~~

sketch\SparkfunWifi.cpp: In member function 'int SparkfunWifi::sendWeather()':

SparkfunWifi.cpp:48:5: error: 'client' was not declared in this scope

     client.beginRequest();

     ^~~~~~

sketch\SparkfunWifi.cpp:48:5: note: suggested alternative: 'Client'

     client.beginRequest();

     ^~~~~~

     Client

exit status 1
[Error] Exit with code=1

I managed to get this working with the following...我设法让这个工作与以下...

.h 。H

#ifndef SPARKFUN_WIFI
#define SPARKFUN_WIFI

#include "arduino.h"
#include "ArduinoJson.h"
#include "HttpClient.h"
#include "ArduinoHttpClient.h"
#include "WiFiNINA.h"
#include "WeatherData.h"

class SparkfunWifi : public HttpClient { 

public:
// Contructor

/** Create a new Sparkwifi class inheriting HttpClient.
    @param wifi The wifi client.
    @param port The port number.
    @param ssid The network ssid.
    @param pass The network password.
*/
SparkfunWifi(Client& wifi, String& serverName, uint16_t port, char* ssid, char* pass);

// Methods

/** Connect to the server and start to send a GET request.
    @return true if connection successful
*/
bool connectWifi();

/** Sends HTTP weather POST to weather.api.
    @return 200 if successful response from api.
*/
int sendWeather(WeatherData weatherData);

private:
int _status;
char* _ssid;
char* _pass;
String _serverName; 


};
#endif

` .cpp `.cpp

` // inlcludes #include "arduino.h" #include "SparkfunWifi.h" #include "WeatherData.h" ` // 包含 #include "arduino.h" #include "SparkfunWifi.h" #include "WeatherData.h"

// constructor
 SparkfunWifi::SparkfunWifi(Client& wifi, String& serverName, uint16_t port, char* 
    ssid, char* pass)
 : (wifi, serverName, port)
 {
 _ssid = ssid;
 _pass = pass;
 _status != WL_CONNECTED;
 _serverName = serverName;
 }

bool SparkfunWifi::connectWifi(){
Serial.begin(9600);
int times = 1;
while (_status != WL_CONNECTED) {
    times++;
    if (times <= 5){
        // attempt to connect 5 times
        Serial.println("Attempting to connect to Network named: ");
        Serial.println(_ssid);   // print the network name (SSID);
        Serial.println("Attempt:");   // print the network name (SSID);
        Serial.println(times);   // print the network name (SSID);
    
        // Connect to WPA/WPA2 network:
        _status = WiFi.begin(_ssid, _pass);
        Serial.print("SSID: ");
        Serial.println(WiFi.SSID());
        // print your WiFi shield's IP address:
        IPAddress ip = WiFi.localIP();
        Serial.print("IP Address: ");
        Serial.println(ip);
        return true;
    }
    else 
    {
        Serial.print("Could not connect on 5th attempt to: ");
        Serial.println(_ssid);   // print the network name (SSID);
        return false;
    }
 }
}

int SparkfunWifi::sendWeather(WeatherData weatherData) {
beginRequest();
DynamicJsonDocument doc(500); 
doc["temp"] = weatherData.getTemp();  
doc["humidity"] = weatherData.getHumidity(); 
doc["windDir"] = weatherData.getWindDir();  
doc["windSpeed"] = weatherData.getWindSpeed();
doc["windGust"] = weatherData.getWindGust(); 
doc["windGustDir"] = weatherData.getWindGustDir();  
doc["windSpeedAvg2m"] = weatherData.getWindSpeedAvg2m();  
doc["windDirAvg2m"] = weatherData.getWindDirAvg2m(); 
doc["windGustAvg10m"] = weatherData.getWindGustAvg10m();  
doc["windGustDirAvg10m"] = weatherData.getWindGustDirAvg10m(); 
doc["dailyRain"] = weatherData.getDailyRain();
doc["pressure"] = weatherData.getPressure();  
doc["batteryLevel"] = weatherData.getBatteryLevel();
doc["lightLevel"] = weatherData.getLightLevel();  
post("/addWeather"); 
sendHeader("Content-Type", "application/json");
sendHeader("Content-Length", measureJsonPretty(doc));
beginBody(); // send the JSON 
serializeJsonPretty(doc, Serial);
serializeJsonPretty(doc, (*iClient));
endRequest(); // end http request

// read the status code
int statusCode = responseStatusCode();
Serial.println(statusCode);

return statusCode;

} ` }`

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 JS 中,您可以继承 class 的方法和父 class 实例的属性吗? - In JS can you inherit methods from your class and properties from an instance of your parent class? 如何创建从外部库中的sqlalchemy模型继承的自定义类 - How to create custom classes that inherit from sqlalchemy models in external library 您是否可以继承自继承普通表格的自定义表格 - Can You Inherit from a Custom Form that Inherits a Normal Form 有没有办法将 PyTypeObject 从 Python 库继承到 CPython 中的自定义类型中? - Is there a way to inherit a PyTypeObject from a Python library into a custom type in CPython? 如何使用.Net中的反射继承密封类? - How can you inherit from a sealed class using reflection in .Net? 为什么不能从构造函数是私有的类继承? - Why can you not inherit from a class whose constructor is private? 为什么要从C ++接口继承 - Why can you inherit from interfaces in C++ 你能在Javascript中创建一个不从Object继承的对象吗? - Can you make an object in Javascript which does NOT inherit from Object? 您可以从编译时不可用的objc中的类继承吗? - Can you inherit from a class in objc not available at compile time? 如何使一个小部件从另一个小部件继承? -颤振 - How can you make a widget inherit from another widget? - Flutter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM