Arduino WiFi101图书馆-将WiFi和WiFiClient传递给儿童课程

Arduino WiFi101 Library - Pass WiFi and WiFiClient to child classes

本文关键字:WiFiClient 图书馆 WiFi101 WiFi Arduino      更新时间:2023-10-16

我正在慢慢着手一个物联网项目,该项目涉及使用Adafruit ItsyBitsy M4、ATWINC1500和WiFi101库的WiFi客户端。在一个草图中,所有的效果都很好,但这很快就变得难以控制。我已经切换到PlatformIO环境,正在使用CPP进行重写。

我希望能够根据代码的用途将其模块化为类,这在很大程度上是成功的。然后,我可以将连接硬件(即串行端口的NeoPixel和Uart)的指针(*)传递给类"set"方法。不过,对于WiFiClassWiFiClient类,我一直无法做到这一点。

我尝试过将WiFiWiFiClient作为指针传递给我的类(请参阅下面的代码),就像我成功地使用Uart Classe作为串行端口一样(尽管方法必须使用->而不是.)。问题是,虽然我能够确定(我认为是什么)当前客户端状态,但我的loop()中从未返回任何数据。我有getter和setter方法来获取/设置WiFiClient指针,但使用它们时没有数据。

当草图开始时,WiFiClass(WiFi对象)似乎也是自动创建的,这让我感到不舒服,因为我在任何地方都没有声明它。

我的问题:

  1. 有没有任何方法可以显式声明WiFiClass并初始化自定义WiFi101连接,而不是使用库提供的默认WiFi类?为了清晰起见,我喜欢看到事物的初始化位置,而不仅仅是接受它们已经初始化
  2. 我是否真的可以将WiFiClient类传递给我自己的类,并让所有类通过指针在main.cpp中使用同一个实例

以下是我迄今为止尝试的内容:

NetworkInterface类

(最初设计用于容纳整个实例化的WiFi类,但目前仅使用WiFiClient):

// network-interface.cpp:
WiFiClient NetworkInterface::getNetworkClient() {
return *_networkClient;
}
byte NetworkInterface::setNetworkInterface(WiFiClient *newNetworkInterface, interfacetype_t mode) {
if (mode >= 0 && mode <= 3) {
networkMode = mode;
} else {
networkMode = -1; // TODO: Use enum
return -1;
}
_networkClient = newNetworkInterface;
return mode;
}

// .header file:
#ifndef NETWORKINTERFACE_H
#define NETWORKINTERFACE_H_
#include "Arduino.h"
typedef enum {
INTERFACETYPE_WIFI = 0,
INTERFACETYPE_ETH = 1,
INTERFACETYPE_BT = 2,
INTERFACETYPE_UNSUPPORTED = -1
} interfacetype_t;
class NetworkInterface {
public:
bool connectToSSID(byte ssid[], byte password[]);
bool getConnectionStatus();
bool disconnectFromNetwork();
interfacetype_t getNetworkMode();    
WiFiClient getNetworkClient();
byte setNetworkInterface(WiFiClient *newNetworkInterface, interfacetype_t mode);  // 26.01.2019 - LIMITED TO WiFICLIENT, UNSURE ABOUT WiFiClass
private:
interfacetype_t networkMode;
WiFiClient *_networkClient;
};
#endif

主要类别:

// main.cpp:
#include <SPI.h>
#include <WiFi101.h>
#include "arduino_secrets.h"
#include "network-interface.h"
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;            // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
char server[] = "www.google.com";    // name address for Google (using DNS)
WiFiClient client;
NetworkInterface networkInterface;

void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial);
Serial.println("= = = Simple Client-Server Test = = = ");
WiFi.setPins(A5, A4, A3, A2);
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
while (true);
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait for connection 
delay(2000);
}
Serial.println("Connected to wifi");
printWiFiStatus();
Serial.println("nStarting connection to server...");
/*
Pass the network client (and hopefully soon WiFi class with hardware connection data) to NetworkInterface class
TODO: IMPLEMENT ENUM FOR INTERFACE TYPES
*/
networkInterface.setNetworkInterface(&client, 0); 
...
}
void loop() {
// if there are incoming bytes available
// from the server, read them and print them:
WiFiClient myClient = networkInterface.getNetworkClient();
if (myClient.available()) {
Serial.print("n==================================n");
Serial.print("| REMOTE :: Server Has Responded: |");
Serial.print("n----------------------------------n");
while (myClient.available()) {
char c = myClient.read();
Serial.write(c);
}
Serial.print("n==================================n");
}
// if the server's disconnected, stop the myClient:
if (!myClient.connected()) {
Serial.println();
Serial.println("CLIENT :: Disconnecting");
myClient.stop();
// do nothing forevermore:
while (true);
}
}

void makeTestCallToPusher() {
char serverURLTest[] = "192.168.2.4";
WiFiClient myClient = networkInterface.getNetworkClient();
if (myClient.connect(serverURLTest, 80)) {
Serial.print("CLIENT :: Connected - ");Serial.print(serverURLTest);Serial.print("n");
myClient.println("GET /test HTTP/1.1");
myClient.println("Upgrade: WebSocket");
myClient.println("Connection: Upgrade");
myClient.println("Origin: ARDUINO_TEST");
myClient.println("Host: eu");
myClient.println("Connection: close");
myClient.println();
}
}

void printWiFiStatus() {
// print the SSID of the network you're attached to:
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);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}

WiFi是在WiFi101.h中声明并在WiFi.cpp中定义的全局对象(位于两个文件的末尾)。要使用它,请包含WiFi101.h或传递对类型为WiFiClass&的参数或字段的引用(对WiFiClass的引用)。

从您的代码来看,您不清楚要对客户端对象执行什么操作。您有全局性的,我看不出它连接到服务器的位置。您将指向全局对象的指针设置为networkInterface对象,存储指针,但getter函数的返回类型不是指针,本地变量myClient也不是指针。

如果要使用指针,请更改getter函数以返回指针。但是,原始对象必须存在于某个地方(现在它是全局的)。

WiFiClient* myClient = networkInterface.getNetworkClient();
if (myClient->available()) {

但是WiFiClient类只是一个包装器,并且将=运算符重载为副本。如果复制,它仍然引用相同的底层TCP套接字。因此,您可以在没有指针或引用的情况下分配它。

WiFiClient _networkClient;
byte setNetworkInterface(WiFiClient &client) {
_networkClient = client; // copy data about TCP socket
}