martin-ger / uMQTTBroker

MQTT Broker library for ESP8266 Arduino
MIT License
442 stars 105 forks source link

Unable to transmit data between uMQTTBroker and a client #54

Open Bick95 opened 3 years ago

Bick95 commented 3 years ago

Hello,

I took pretty much this example code to set up a MQTT broker on an ESP8266-01S.

To set up a client, I used pretty much this example code.

When I run the broker, it works in that it receives the messages it broadcasts/publishes itself. Thus, it receives the counter information published on topic /broker/counter.

Also, as far as I can tell from reading the messages printed to the Serial monitor, the broker recognizes that the client tries to connect to it when I start the client. However, when I print the clients being connected to the broker, the client that just tried to connect does not show up.

On the client side, the print statements shown in the Serial monitor don't look suspicious at all. However, no published information seems to arrive at the client side.

To demonstrate this, please find the Serial monitor output below:

Serial output for the broker:

AP started
IP address: 192.168.4.1
Starting MQTT broker
received topic '/broker/counter' with data '0'
Clients:
Clients End.
received topic '/broker/counter' with data '1'
Clients:
Clients End.
received topic '/broker/counter' with data '2'
Clients:
Clients End.
received topic '/broker/counter' with data '3'
Clients:
Clients End.
received topic '/broker/counter' with data '4'
Clients:
Clients End.
received topic '/broker/counter' with data '5'
Clients:
Clients End.
add 1
aid 1
station: 48:3f:da:79:48:3e join, AID = 1
received topic '/broker/counter' with data '6'
Clients:
Clients End.
received topic '/broker/counter' with data '7'
Clients:
Clients End.
received topic '/broker/counter' with data '8'
Clients:
Clients End.
received topic '/broker/counter' with data '9'
Clients:
Clients End.
received topic '/broker/counter' with data '10'
Clients:
Clients End.
received topic '/broker/counter' with data '11'
Clients:
Clients End.
received topic '/broker/counter' with data '12'
Clients:
Clients End.

Serial output of the client:

Connecting to ssid
scandone
.....scandone
state: 0 -> 2 (b0)
.state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt 

connected with ssid, channel 1
dhcp client start...
.ip:192.168.4.2,mask:255.255.255.0,gw:192.168.4.1
.
WiFi connected
IP address: 
192.168.4.2
Connecting to MQTT server
connect mqtt...
subscribe to topic...
Subscribed!

While the print statements would continue for the broker, no new output gets generated for the client after that shown above.

The concrete code I am using is the following:

Code for the broker:

/*
 * uMQTTBroker demo for Arduino (C++-style)
 * 
 * The program defines a custom broker class with callbacks, 
 * starts it, subscribes locally to anything, and publishs a topic every second.
 * Try to connect from a remote client and publish something - the console will show this as well.
 */

#include <ESP8266WiFi.h>
#include "uMQTTBroker.h"

/*
 * Your WiFi config here
 */
char ssid[] = "ssid";     // your network SSID (name)
char pass[] = "password"; // your network password
bool WiFiAP = true;      // Do yo want the ESP as AP?

/*
 * Custom broker class with overwritten callback functions
 */
class myMQTTBroker: public uMQTTBroker
{
public:
    virtual bool onConnect(IPAddress addr, uint16_t client_count) {
      Serial.println(addr.toString()+" connected");
      return true;
    }

    virtual void onDisconnect(IPAddress addr, String client_id) {
      Serial.println(addr.toString()+" ("+client_id+") disconnected");
    }

    virtual bool onAuth(String username, String password, String client_id) {
      Serial.println("Username/Password/ClientId: "+username+"/"+password+"/"+client_id);
      return true;
    }

    virtual void onData(String topic, const char *data, uint32_t length) {
      char data_str[length+1];
      os_memcpy(data_str, data, length);
      data_str[length] = '\0';

      Serial.println("received topic '"+topic+"' with data '"+(String)data_str+"'");
      //printClients();
    }

    // Sample for the usage of the client info methods

    virtual void printClients() {
      for (int i = 0; i < getClientCount(); i++) {
        IPAddress addr;
        String client_id;

        getClientAddr(i, addr);
        getClientId(i, client_id);
        Serial.println("Client "+client_id+" on addr: "+addr.toString());
      }
    }
};

myMQTTBroker myBroker;

/*
 * WiFi init stuff
 */
void startWiFiClient()
{
  Serial.println("Connecting to "+(String)ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");

  Serial.println("WiFi connected");
  Serial.println("IP address: " + WiFi.localIP().toString());
}

void startWiFiAP()
{
  WiFi.mode(WIFI_AP);
  WiFi.softAP(ssid, pass);
  Serial.println("AP started");
  Serial.println("IP address: " + WiFi.softAPIP().toString());
}

void setup()
{
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.println();
  Serial.println();

  // Start WiFi
  if (WiFiAP)
    startWiFiAP();
  else
    startWiFiClient();

  // Start the broker
  Serial.println("Starting MQTT broker");
  myBroker.init();

/*
 * Subscribe to anything
 */
  myBroker.subscribe("#");
}

int counter = 0;

void loop()
{
/*
 * Publish the counter value as String
 */
  myBroker.publish("/broker/counter", (String)counter++);
  Serial.println("Clients:");
  myBroker.printClients();
  Serial.println("Clients End.");

  // wait a second
  delay(1000);
}

Code for the client:

#include <ESP8266WiFi.h>
#include <MQTT.h>

void myDataCb(String& topic, String& data);
void myPublishedCb();
void myDisconnectedCb();
void myConnectedCb();

#define CLIENT_ID "client3"
#define TOPIC "/broker/counter"
#define UNIVERSAL_TOPIC "#"

// create MQTT
MQTT myMqtt(CLIENT_ID, "192.168.4.1", 1883);

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

//
void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  delay(1000);

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  Serial.println("Connecting to MQTT server");

  // setup callbacks
  myMqtt.onConnected(myConnectedCb);
  myMqtt.onDisconnected(myDisconnectedCb);
  myMqtt.onPublished(myPublishedCb);
  myMqtt.onData(myDataCb);

  Serial.println("connect mqtt...");
  myMqtt.connect();

  Serial.println("subscribe to topic...");
  myMqtt.subscribe(TOPIC);
  myMqtt.subscribe(UNIVERSAL_TOPIC);

  delay(10);
  Serial.println("Subscribed!");
}

//
void loop() {
}

/*
Callbacks:
*/
void myConnectedCb()
{
  Serial.println("connected to MQTT server");
}

void myDisconnectedCb()
{
  Serial.println("disconnected. try to reconnect...");
  delay(500);
  myMqtt.connect();
}

void myPublishedCb()
{
  Serial.println("published.");
}

void myDataCb(String& topic, String& data)
{

  Serial.print(topic);
  Serial.print(": ");
  Serial.println(data);
}

Do you have any idea on whether I am doing something wrong or what is causing the error I am experiencing?

Thank you very much in advance!

Bick95 commented 3 years ago

By the way, in case that this is relevant, I am using the following settings:

Board: Generic ESP8266 Module lwIP variant: v1.4 Higher Bandwidth

If you would like to know more, please let me know!

nguyentiendathus commented 1 year ago

hello, did you solve this problem ? I have this problem too Thank you

Bick95 commented 1 year ago

No, unfortunately not @nguyentiendathus. But admittedly I got pulled away from that problem at some point, so that I didn't look into it too much anymore.