How to pass variable to external file.

I am developing web server on ESP8266

void handleRoot() {
    server.send(200, "text/plain", "hello from esp8266!");
}

void setup(void){
    server.on("/", handleRoot);
    server.begin();
}

It is very shortly. Of course, there is another code but this is all I need to make a question.

Now I want to make handleRoot function external file.

pages.h

#ifndef pages_h

#define pages_h

class pclass
{
    private:
        
    public:
        pclass();
        void pageHome();
        
};

extern pclass pages;

#endif

and

#include "pages.h"
#include <ESP8266WebServer.h>

pclass::pclass(){}

void pclass::pageHome() {
    server.send(200, "text/plain", "Home page");
}

How can I pass server variable to that function? It highlights it as an error.

I was thinking to make some sort of void SETUP(ESP8266WebServer &server) in my pages class and pass server variable there by reference and store it somewhere in class property. And then use that property infunction.

I am sorry it is my first CPP code, I just learn .h .cpp concept. Come from JS.

Do I think right or how that simple task should be handled?

Have your 'pclass' store a pointer to the "server" object. And make a method in your 'pclass' to pass that server object. For example in the constructor.

But with snippets I'm not able to help more.

Question with other words. Let's say I have Serial.begin(9600) in my setup. Then I call some library function library.doSOmething(). How can I use Serial.print() in that function? Should I pass serial there or should I start Serial.begin() in my library? If I start what happens with serial.begin() in my setup?

My point is that this is a dumb question. Because I do not know how variables are passed from one file to another. The most basic. Do not go far.

Serhioromano:
How can I use Serial.print() in that function?

Serial is a bit of a tricky choice because it's a Arduino HAL function. It's type is also not the same for all Arduino's.

Serhioromano:
Should I pass serial there or should I start Serial.begin() in my library?

I would call the Serial.begin() in setup and pass the reference to the library. I would use a reference to the Stream class because all Serial's (whatever it's type) should have that as a parent. But Stream has no .begin() method.

Serhioromano:
My point is that this is a dumb question. Because I do not know how variables are passed from one file to another. The most basic. Do not go far.

Simply said, they are not! You can pass a reference/pointer to a variable to a function (/method) call during runtime.

And when you don't use .cpp and .h files but simply a new tab (.ino), the IDE simple makes one big file in the background before compiling. It is the simplest method but it does come with it's limitations.

I use h and cpp.

But I cannot figure out how to set variable to property. Let’s say I have class

class M2MServer
    {
        private:
            ESP8266WebServer &_server;
            
        public:
            M2MServer();
            void begin(ESP8266WebServer &server);
            void pageHome();
            void handleClient();
            
    };

In main code I want

#include <ESP8266WebServer.h>
#include "M2MServer.h"

ESP8266WebServer server(80);
M2MServer ms();

void setup() {
    ms.begin(&server)
}

Then I want to set server to private _server property of M2MServer class by reference and in my all other class methods access it thgouh this->_server.

Right now I have program

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include "m2mserver.h"

const char *ssid = "Automation";
const char *password = "ryobitools";

const int WiFiMode = 1; // WiFi mode. LOW - AP, HIGH - STA

IPAddress local_IP(192, 168, 1, 144);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

ESP8266WebServer server(80);

void setup(void)
{
    Serial.begin(115200);
    Serial.println("Start configuration");

    WiFi.mode(WIFI_AP);

    WiFi.softAPConfig(local_IP, gateway, subnet);
    if (WiFi.softAP("Automation_Iot", "12345678"))
    {
        Serial.println("AP Started");
        Serial.println(WiFi.softAPIP());
    }

    if (MDNS.begin("esp8266"))
    {
        Serial.println("MDNS responder started");
    }
    
    server.on("/", []() {
        server.send(200, "text/plain", "Home page");
    });
    
    server.begin();
    
    Serial.println("HTTP server started");
}

void loop(void)
{
    server.handleClient();
    MDNS.update();
}

I want to call

server.on("/", []() {
    server.send(200, "text/plain", "Home page");
});
    
server.begin();

in a library.

private:
            ESP8266WebServer &_server;

You make a reference which needs to be assigned when created. Which in this case happens when an object of your class is created. So you have to assign it with the constructor.

If you want to initiate it in a begin() function, use a pointer.

pseudo code:

ESP8266WebServer *_server;

void myClass::begin(ESP8266WebServer *s){
  _server = s;
}

void myClass::someFunction(){
  _server->send();
}

And call like:

ESP8266WebServer server(80);
MyClassms();

void setup() {
    ms.begin(server)
    ms.someFunction()
}

You can do it with a reference and in the constructor.

Again, pseudo code:

ESP8266WebServer  &_server;

Myclass(ESP8266WebServer &s) : _server(s){
}

void Myclass:someFunction(){
  _server.send();
}

And call like:

ESP8266WebServer server(80);
MyClass ms(server);

void setup() {
    ms.someFuntion();
}

septillion:
And call like:

ESP8266WebServer server(80);

MyClassms();

void setup() {
   ms.begin(server)
   ms.someFunction()
}

When using the pointer method, probably need to pass server's address:
ms.begin(**&**server)

Uh, of course correct :slight_smile: My fault!

h file

#ifndef m2m_dpg
    #define m2m_dpg

    #include <ESP8266WebServer.h>

    class M2MServer
    {
        private:
            ESP8266WebServer& _server;
            
        public:
            M2MServer(ESP8266WebServer &server);
            void begin();
            void pageHome();
            void handleClient();
            
    };
#endif

and cpp

#include "m2mserver.h"
#include <ESP8266WebServer.h>

M2MServer::M2MServer(ESP8266WebServer &server) : _server(server) {}

void M2MServer::begin() {
    _server.on("/", this->pageHome);
    
    _server.on("/test", this->pageHome);
    
    _server.begin();
}

void M2MServer::pageHome() {
    _server.send(200, "text/plain", "Home page");
}

void M2MServer::handleClient() {
    _server.handleClient();
}

in my arduino file

ESP8266WebServer server(80);
M2MServer ms(server);

void setup(void)
{
    Serial.begin(115200);
    Serial.println("Start configuration");

    WiFi.mode(WIFI_AP);

    WiFi.softAPConfig(local_IP, gateway, subnet);
    if (WiFi.softAP("Automation_Iot", "12345678"))
    {
        Serial.println("AP Started");
        Serial.println(WiFi.softAPIP());
    }

    if (MDNS.begin("esp8266"))
    {
        Serial.println("MDNS responder started");
    }

    ms.begin();
    
    Serial.println("HTTP server started");
}

void loop(void)
{
    ms.handleClient();
    MDNS.update();
}

Does not work. What is wrong here?

When I delete from cpp

_server.on("/", this->pageHome);
_server.on("/test", this->pageHome);

then at least upload starts

Because the on() function needs a global function not a class member function.

Try to make your pageHome() a static method.

static void pageHome();

Yeah, you can’t use an object method as a handler.

Small edit t the .h

#ifndef m2m_dpg
    #define m2m_dpg

    #include "Arduino.h"
    //#include <ESP8266WebServer.h>
    class ESP8266WebServer;


    class M2MServer
    {
        private:
            ESP8266WebServer& _server;
           
        public:
            M2MServer(ESP8266WebServer &server);
            void begin();
            void pageHome();
            void handleClient();
           
    };
#endif