Доступ к экземпляру класса из другого класса

Добрый. Возможно я не первый, и не последний. Я достаточно не плохо знаю JS но с++ не знаю от слова совсем. 2й день в 100 строчках кода извели меня полностью. Прошу Вашего совета или решения.
В общем есть ESP8266. Надо подружить его с WIFI и Websocket. Необходим для передачи информации от автоматов( кнопок ) на комп по WebSocket.
Подружить - я подружил. Один файл .ino. К вайфаю коннектится, данные пересылает.
Сделал реализацию класса кнопки. По кнопке отрабатывает писанину в Сериал.

До сих пор не пойму зачем мне создавать класс в отдельном файле ( .h ), а Реализацию в .cpp Но скетч компилироваться без этого не хотел.

Встал вопрос о передаче информации по WebSocket. Но я никак не могду получить доступ к уже проинициализированному экземпляру класса WEBSOCKET.

Подскажите, как мне из класса Кнопки получить доступ к экземпляру класса WEBSOCKET? Даже если я его передаю как параметр при инициализации класса кнопки, объект вебсокета в объекте кнопки является пустым.

Пытался сделать SocketIO глобальным - тоже не получилось. Прошу помощи.
Ниже выкладываю свое извращение.

==WS TEST==

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#include <ArduinoJson.h>

#include <WebSocketsClient.h>
#include <SocketIOclient.h>

#include <Hash.h>
#include <D:\INSTALL\NodeMCU\ws_test_2\btn.h>

ESP8266WiFiMulti WiFiMulti;
SocketIOclient socketIO;

#define USE_SERIAL Serial

/// КУЧА ХЛАМА ... ОН НЕ НУЖЕН ///


  unsigned long messageTimestamp = 0;

  boolean wifiLedStatus = false;

void setup() {
    USE_SERIAL.begin( 9600 );
    USE_SERIAL.setDebugOutput( true );

    USE_SERIAL.println();
    USE_SERIAL.println();
    USE_SERIAL.println();

      for(uint8_t t = 4; t > 0; t--) {
          USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
          USE_SERIAL.flush();
          delay(1000);
      }

    // disable AP
    if ( WiFi.getMode() & WIFI_AP ) { WiFi.softAPdisconnect(true); }

    WiFiMulti.addAP("blablabla", "NODE.jsIsTheBest");
    while( WiFiMulti.run() != WL_CONNECTED ) { delay(100); }
    String ip = WiFi.localIP().toString();
    USE_SERIAL.printf( "[SETUP] WiFi Connected %s\n", ip.c_str() );
    socketIO.begin( "192.168.88.2", 3089, "/esp/?EIO=4" );
    socketIO.onEvent( socketIOEvent );
    USE_SERIAL.print( "SocketIO is connected:" );
    USE_SERIAL.print( socketIO.isConnected() );
}


btn inletPumpButton( 5, "INLET_PUMP", socketIO );

void loop() {
    socketIO.loop();

    uint64_t now = millis();

    if ( now - messageTimestamp > 2000 ) {
        messageTimestamp = now;
        inletPumpButton.sendEvent( "hi", "there" );
     }

}

=== btn.h ===

#include "WString.h"
#ifndef btn_h
#define btn_h
#include "Arduino.h" 
#include <ArduinoJson.h>
#include <WebSocketsClient.h>
#include <SocketIOclient.h>

class btn {
  public:
    btn( int pin, String name, SocketIOclient socketIO );
    // btn( int pin, String name );
    int getPin();
    String getName();
    void sendEvent( String event_p, String state_p );
  private: 
    int _pin;  
    String _name;
    JsonArray _signal;
    JsonObject _payload;
    JsonDocument _buttonEvent;
    String _JSON;
    SocketIOclient _socketIO;
};

#endif

=== btn.cpp ===

// LED.cpp
#include "btn.h"
#include <ArduinoJson.h>

btn::btn( int pin, String name, SocketIOclient socketIO ) {
// btn::btn( int pin, String name ) {
  _pin = pin;
  _name = name;
  _signal = _buttonEvent.to<JsonArray>();
  _signal.add( "button" );
  _payload = _signal.add<JsonObject>();
  _socketIO = socketIO;
}

int btn::getPin() {
  return _pin;
}

String btn::getName() {
  return _name;
}

void btn::sendEvent( String event_p, String state_p ) {
  _payload[ "time" ] = millis();
  serializeJson( _buttonEvent, _JSON );

  _socketIO.sendEVENT( _JSON );

  Serial.print( _socketIO.isConnected() );
  Serial.print( " :: " );
  Serial.print( _JSON );
  Serial.print( " :: " );
  Serial.print( event_p );
  Serial.print( " :: " );
  Serial.println( state_p );
}

создай глобальную переменную как указатель того же типа. в момент инициализации экземпляра вебсокета, присваивай переменной значение = созданный указатель. в дальнейшем образайся к этому указателю и его свойствам. из любого места.

Это в общем виде решение. код твой не читал, извини.

(сообщение удалено автором)

Очень прошу, если не сложно, либо пример, либо где почитать… Голова уже пухнет.
Я не пойму как сделать глобальную переменную.

1 лайк

я бы с удовольствием, но я тоже ненастоящий ардуинщик, подожди может ктонить из гуру придет осчастливит тебя.

вывсёврёти!

1 лайк

Интересно в чем ?

в JS нет понятия глобальных переменных?

1 лайк

Так Вы его неправильно передаёте. Такие объекты по значению не передаются.

В строке №11 файла btn.h и в строке №5 файла btn.cpp поставьте амперсанд ( & ) после слова SocketIOclient .

1 лайк

Да, не надо Вам это. Зачем? Сделайте, что я Вам сказал и забудьте о перхоти.

2 лайка

чтио то мне кажется, что я не правильно определяю переменную _socketIO в btn.h( 23 строка ) и не правильно присваиваю ей объект в btn.cpp ( 12 строка. ). Все, что компилятор пропускает без ошибок, показывает, то объект _socketIO не имеет инициализации. ( Serial.print( _socketIO.isConnected() ); отрабатывает как 0 )

Есть… и опрелеяются они типа globalThis.ioESP = new Server( server, { path: ‘/esp’ } );
И Работаю как от низ ожидаешь… Я наверно просто со своей колокольни смотрю. Я давно просто сижу под JS и уже голова работает на этом ЯП

Конечно, неправильно.

И это неправильно.

Вернее, если быть точным, то нельзя сказать правильно или неправильно, если не знать, что Вы хотели сделать в этих строках (а это Вы как раз забыли сказать (или написать в комментариях)). Но, по моим предположениям о том, что Вы хотели сделать, да, неправильно.

Так… Тогда вопрос по логике и реализации. Есть ESP есть скетч.
Я в Главном скетче определяю WIFI и socketIO. И если я начинаю писать что либо в void Loop() то все работает. Данные передаются на сервер по socketIO.
Но как только я пытаюсь получить доступ к Экземпляру класса socketIO из экземпляра класса btn у меня получается непоределенный экземпляр socketIO. как мне получить доступ из экземляра класса btn к готовому ( рабочему. проинициализированному ) экземпляру класса socketIO. Я

Я бьюсь с этим уже целый день. Вот и прошу помощи. Если Я как то не так выражаюсь, простите.

btn( int pin, String name, SocketIOclient &socketIO )

Да, бестолку, он там дальше его локальному объекту присваивает. Там в каждой строчке ошибка.

Ну тогда подскажите как правильно передавать дальше данный объект. Я же не просто так помощи прошу. Либо подскажите примеры, где уже есть готовое рещение моего вопроса.

Про указатели почитайте. Самый простой вариант:

btn.h:

строка 11

btn( int pin, String name, SocketIOclient *socketIO );

строка 23

SocketIOclient *_socketIO;

btn.cpp
строка 5

btn::btn( int pin, String name, SocketIOclient *socketIO ) {

При этом учитывать некоторые особенности работы с указателями на объекты

строка 27…29

  _socketIO->sendEVENT( _JSON );

  Serial.print( _socketIO->isConnected() );

WS TEST

строка 54

btn inletPumpButton( 5, "INLET_PUMP", &socketIO );
1 лайк

ТС, дорогой. С++ не совсем настоящий ООП язык. В отличии от Java или JS.
Чтобы было похоже на то, к чему ты привык, НЕ ПЕРЕДАВАЙ объект никуда, и не заводи объект в классе кнопки. Только ссылки, как тебе ЕП выше написал.
Просто прочти про ссылки в сети. вместо T myobj используй T &refToMyobj и все станет похоже на Джаву или Джваскрипт.