Библиотека Arduino WiFi101 - Передача WiFi и WiFiClient в детские классы - PullRequest
0 голосов
/ 26 января 2019

Я постепенно приступаю к работе над проектом IoT с участием WiFi-клиента, использующего библиотеки Adafruit ItsyBitsy M4, ATWINC1500 и WiFi101.Все прекрасно работает в одном наброске, но это быстро становится неуправляемо длинным.Я перешел на среду PlatformIO и переписываю с использованием CPP.

Я хочу иметь возможность модульно кодировать мой код по назначению в классы, которые по большей части были успешными.Затем я могу передать указатели (*) подключенного оборудования (например, NeoPixel и Uart для последовательных портов) в метод "set" классов.Хотя я не смог сделать это с классами WiFiClass и WiFiClient.

Я попытался передать WiFi и WiFiClient моим классам в качестве указателя (см. Код ниже), так же, как я успешно сделал это с Uart Classe для моих последовательных портов.(хотя я должен использовать ->, а не . для методов).Проблема заключается в том, что, хотя я могу определить (каким я считаю) текущий статус клиента, в моем цикле никогда не возвращаются никакие данные ().У меня есть методы 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");
}

1 Ответ

0 голосов
/ 27 января 2019

WiFi - это глобальный объект, объявленный в WiFi101.h и определенный в WiFi.cpp (в конце обоих файлов).Чтобы использовать его, включите WiFi101.h или передайте ссылку на параметр или поле типа WiFiClass& (ссылка на WiFiClass).

Из вашего кода не ясно, что вы хотите сделать с клиентским объектом.У вас это глобально, и я не вижу, где он подключается к серверу.Вы устанавливаете указатель на глобальный объект на объект networkInterface, сохраняете указатель, но тип возвращаемого значения функции getter не является указателем, а локальная переменная myClient тоже не является указателем.

Если вы хотите работать суказатель, измените функцию получения, чтобы вернуть указатель.Но тогда оригинальный объект должен где-то существовать (теперь он глобальный).

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

Но класс WiFiClient является только оболочкой и имеет оператор =, перегруженный как копия.Если скопировано, это все еще ссылается на тот же основной сокет TCP.Таким образом, вы можете назначить его без указателя или ссылки.

WiFiClient _networkClient;
byte setNetworkInterface(WiFiClient &client) {
  _networkClient = client; // copy data about TCP socket
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...