Page 1 of 1

OOP in ESP-WROOM-32

Posted: Sun Oct 11, 2020 6:00 pm
by redplane
Hi,
I'm using ESP32 for my personal project.
Currently, I'm making a WIFI manager using a class to scan & save the scanned WIFI network then display the network list on the TFT Screen with pagination (4 items per page).

I'm using a class WirelessNetworkManager to store the scanned network & use them later.
This is my code:

Code: Select all

#include "../.pio/libdeps/esp32dev/LinkedList/LinkedList.h"
#include "WirelessNetwork.h"

class WirelessNetworkManager {

private:

    // Available networks that have been searched.
    LinkedList<WirelessNetwork> _availableNetworks;

    // Network which have been selected.
    WirelessNetwork *_selectedNetwork;

    // The last time when networks are scanned.
    float _lastScanTime;

    // Id of network which item will be retrieved previously.
    int _previousPageId;

    // Id of network from which item will be retrieved
    int _pageId;

public:

    WirelessNetworkManager();

    // Get list of available networks.
    LinkedList<WirelessNetwork> *getAvailableNetworks();

    // Get list of wireless networks by using page id & maximum records per page.
    LinkedList<WirelessNetwork> *getAvailableNetworks(int pageId, int maxRecords);

    // Get the id of page.
    int getPageId() const;

    // Get the selected network.
    WirelessNetwork *getSelectedNetwork();

    // Select wireless network by specifying its index.
    void selectWirelessNetwork(int index);

    // Disconnect to from the connect network (if any)
    static void disconnect() ;

    // Mark page to be loaded.
    void markPageLoaded();

    // Whether network records must be updated.
    bool shouldRecordsRefreshed() const;

    // Go to next network page
    void goForward();

    // Go to previous network page
    void goBackward();
};

Code: Select all

#include <WirelessNetworkManager.h>
#include <WiFi.h>

//#region Constructor

WirelessNetworkManager::WirelessNetworkManager() {
    this->_lastScanTime = -1.0f;
    this->_selectedNetwork = nullptr;
    this->_availableNetworks = LinkedList<WirelessNetwork>();
    this->_pageId = 0;
    this->_previousPageId = -1;
}

//#endregion

//#region Methods

LinkedList<WirelessNetwork> *WirelessNetworkManager::getAvailableNetworks() {

    LinkedList<WirelessNetwork> *allNetworks = nullptr;

    // Clear the previous loaded network.
    this->_availableNetworks.clear();
    this->_previousPageId = -1;
    this->_pageId = 0;

    // Clear the selected network.
    this->_selectedNetwork = nullptr;

    // WiFi.scanNetworks will return the number of networks found
    int iDiscoveredNetworks = WiFi.scanNetworks();
    delay(20);

    // No network is discovered.
    if (iDiscoveredNetworks == 0) {
        return &this->_availableNetworks;
    }

    LinkedList<WirelessNetwork> availableNetworks;

    for (int iNetworkIndex = 0; iNetworkIndex < iDiscoveredNetworks; iNetworkIndex++) {
        String ssid(WiFi.SSID(iNetworkIndex));
        char iSignalStrength = WiFi.RSSI(iNetworkIndex);
        bool bIsProtected = WiFi.encryptionType(iNetworkIndex) != WIFI_AUTH_OPEN;

        // Enlist the available networks.
        WirelessNetwork availableNetwork = WirelessNetwork(ssid.c_str(), iSignalStrength, bIsProtected);
        availableNetworks.add(availableNetwork);
    }

    this->_availableNetworks = availableNetworks;

    allNetworks = &this->_availableNetworks;
    return allNetworks;
}

LinkedList<WirelessNetwork> *WirelessNetworkManager::getAvailableNetworks(int pageId, int maxRecords) {


    if (this->_availableNetworks.size() < 1) {
        return new LinkedList<WirelessNetwork>();
    }

    // Update the page id.
    this->_pageId = pageId;

    // Get the records which must be skipped.
    int skippedRecords = this->_pageId * maxRecords;
    int endRecordId = skippedRecords + maxRecords;
    if (endRecordId > this->_availableNetworks.size()) {
        endRecordId = this->_availableNetworks.size();
    }

    LinkedList<WirelessNetwork> *availableNetworks = new LinkedList<WirelessNetwork>();

    Serial.print("Items = ");
    Serial.println(this->_availableNetworks.size());

    Serial.print("Skipped records = ");
    Serial.println(skippedRecords);

    Serial.print("End records = ");
    Serial.println(endRecordId);

    for (int i = skippedRecords; i < endRecordId; i++) {

        Serial.print("Id ");
        Serial.println(i);

        char szItemTitle[128] = "";
        char szValue[10] = "";
        char szNetworkName[128] = "";
        const bool bIsProtected = this->_availableNetworks.get(i).getProtected();

        strcat(szItemTitle, " ");
        strcpy(szNetworkName, this->_availableNetworks.get(i).getName());
        strcat(szItemTitle, szNetworkName);
        strcat(szItemTitle, !bIsProtected ? " " : "*");

        Serial.print("Drawn network = ");
        Serial.println(szItemTitle);

        WirelessNetwork availableNetwork(this->_availableNetworks.get(i));
        availableNetworks->add(availableNetwork);
    }

    return availableNetworks;
}

int WirelessNetworkManager::getPageId() const {
    return this->_pageId;
}

WirelessNetwork *WirelessNetworkManager::getSelectedNetwork() {
    return this->_selectedNetwork;
}

void WirelessNetworkManager::selectWirelessNetwork(int index) {

    if (index < 0 || index > this->_availableNetworks.size() - 1) {
        return;
    }

    WirelessNetwork selectedNetwork = this->_availableNetworks.get(index);
    this->_selectedNetwork = &selectedNetwork;
}

void WirelessNetworkManager::disconnect() {
    WiFi.disconnect();
}

void WirelessNetworkManager::markPageLoaded() {
    this->_previousPageId = this->_pageId;
}

bool WirelessNetworkManager::shouldRecordsRefreshed() const {
    return this->_pageId != this->_previousPageId;
}

void WirelessNetworkManager::goForward() {
    // TODO: Check if page can be gone forward or not.
    this->_pageId++;
}

void WirelessNetworkManager::goBackward() {
    // TODO: Check if page can be gone backward or not.
    if (this->_pageId < 2) {
        return;
    }

    this->_pageId--;
}

//#endregion
And here is my main file:

Code: Select all

void setup() {

    // Open serial connection.
    Serial.begin(115000);
    nexInit();

    // Set WiFi to station mode and disconnect from an AP if it was previously connected
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();

    // Screen activation callback.
    m_SplashScreen.attachPop(OnSplashScreenActivated);
    m_MainView.attachPop(OnMainViewActivated);
    m_NetworkView.attachPop(OnNetworkViewActivated);
    m_WifiPasswordView.attachPop(OnWifiPasswordViewActivated);
}

void loop() {

    String message;

    // Run loop
    nexLoop(m_WatchedControls);
    
    
    // In network page.
    if (m_iActivatedScreen == NETWORK_VIEW_ID) {
        int iMaxNetworkItems = sizeof(m_NetworkItems) / sizeof(m_NetworkItems[0]);
        int iMaxNetworkIcons = sizeof(m_NetworkIconItems) / sizeof(m_NetworkIconItems[0]);

        // Networks must be loaded.
        if (m_bMustLoadWifiNetworks) {
            // Display loading message.
            m_NetworkLoadingMessage.setText(MSG_SEARCHING_WIFI);
            m_NetworkLoadingMessage.setVisible(true);

            // Hide network item & icon.
            for (int iNetworkIndex = 0; iNetworkIndex < iMaxNetworkItems; iNetworkIndex++) {
                m_NetworkItems[iNetworkIndex]->setVisible(false);
                m_NetworkIconItems[iNetworkIndex]->setVisible(false);
            }

            m_bMustLoadWifiNetworks = false;
            m_NetworkProcessStatus = NETWORK_STATUS_LOADING;

            // Scan for available networks.
            LinkedList<WirelessNetwork> *availableNetworks = m_WirelessNetworkManager->getAvailableNetworks();

            // No network is discovered.
            if (availableNetworks->size() < 1) {
                m_NetworkProcessStatus = NETWORK_STATUS_LOADED;

                m_NetworkLoadingMessage.setText(MSG_NO_WIFI);
                m_NetworkLoadingMessage.setVisible(true);
                return;
            }

            for (int i = 0; i < availableNetworks->size(); i++) {
                char szItemTitle[128] = "";
                char szValue[10] = "";
                char szNetworkName[128] = "";
                const bool bIsProtected = availableNetworks->get(i).getProtected();

                strcat(szItemTitle, " ");
                strcat(szNetworkName, availableNetworks->get(i).getName());
                strcat(szItemTitle, szNetworkName);
                strcat(szItemTitle, !bIsProtected ? " " : "*");

                Serial.println(szItemTitle);
            }

            m_NetworkProcessStatus = NETWORK_STATUS_LOADED;

            if (availableNetworks->size() > 0)
                m_NetworkLoadingMessage.setVisible(false);
            else
                m_NetworkLoadingMessage.setText(MSG_NO_WIFI);
        }

        // Wifi already loaded.
        if (m_NetworkProcessStatus == NETWORK_STATUS_LOADED && m_WirelessNetworkManager->shouldRecordsRefreshed()) {

            int pageId = m_WirelessNetworkManager->getPageId();

            // Get the available networks which have been paginated.
            LinkedList<WirelessNetwork> *paginatedNetworks = m_WirelessNetworkManager->getAvailableNetworks(pageId, m_iMaxNetworkPageItems);

            for (int iNetworkIndex = 0; iNetworkIndex < paginatedNetworks->size(); iNetworkIndex++) {

                // Get the available network.
                WirelessNetwork availableNetwork = paginatedNetworks->get(iNetworkIndex);

                char szItemTitle[128] = "";
                char szValue[10] = "";
                char szNetworkName[128] = "";
                const bool bIsProtected = availableNetwork.getProtected();

                strcat(szItemTitle, " ");
                strcat(szNetworkName, availableNetwork.getName());
                strcat(szItemTitle, szNetworkName);
                strcat(szItemTitle, !bIsProtected ? " " : "*");

                m_NetworkItems[iNetworkIndex]->setText(szItemTitle);
                m_NetworkItems[iNetworkIndex]->setVisible(true);
                m_NetworkIconItems[iNetworkIndex]->setVisible(true);
            }

            // Free allocated memory.
            delete paginatedNetworks;

            m_WirelessNetworkManager->markPageLoaded();
        }
    }
}
When I run the application and scan for network page. This is what I saw on Serial Monitor:

Code: Select all


AH-6 Overwatch*
PHUONG THAO*
Tuta 518*
VIETTEL-E450*

Items = 8
Skipped records = 0
End records = 4
Id 0
Drawn network =  AH-6 Overwatch*
Id 1
Drawn network =  AH-6 Overwatch*
Id 2
Drawn network =  AH-6 Overwatch*
Id 3
Drawn network =  AH-6 Overwatch*
Every time the first WIFI is returned, even I already stored the scanned list inside WirelessNetworkManager. Am I doing anything wrong ?

Thank you,