256dpi / arduino-mqtt

MQTT library for Arduino
MIT License
1.01k stars 232 forks source link

MQTTS on ESP32 via Ethernet #236

Closed nmaas87 closed 1 year ago

nmaas87 commented 3 years ago

Hello there,

thanks for the awesome library which I have been using for many years already. I just got a quick question: Is it possible to use it with an W5500 or ENC28J60 Ethernet SPI for wired communication on an ESP32 - as well with SSL/secure MQTT?

Thanks a lot :)!

nmaas87 commented 3 years ago

I just wanted to tell, there is an issue with using Arduino Ethernet and ESP32 as mentioned here: https://github.com/arduino-libraries/Ethernet/pull/107 - but one can just use the Ethernet.h from the pull request ( https://github.com/arduino-libraries/Ethernet/blob/81c2ce0c6922fc984703bf3adeacaf73bcc3f578/src/Ethernet.h ) and replace the own one with it. Afterwards I was able to connect a W5500 like this:

MISO = GPIO19 MOSI = GPIO23 RST = GPIO5 SCS = GPIO33 SCLK = GPIO18 GND = GND 3V3 = 3V3

and used this code to get it working:


#include <SPI.h>
#include <Ethernet.h>
#include <MQTT.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
byte ip[] = {192, 168, 4, 177};  // <- change to match your network

EthernetClient net;
MQTTClient client;

unsigned long lastMillis = 0;

void connect() {
  Serial.print("connecting...");
  while (!client.connect("arduino", "public", "public")) {
    Serial.print(".");
    delay(1000);
  }

  Serial.println("\nconnected!");

  client.subscribe("/hello4711");
  // client.unsubscribe("/hello");
}

void messageReceived(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);

  // Note: Do not use the client in the callback to publish, subscribe or
  // unsubscribe as it may cause deadlocks when other things arrive while
  // sending and receiving acknowledgments. Instead, change a global variable,
  // or push to a queue and handle it in the loop after calling `client.loop()`.
}

void setup() {
  Serial.begin(115200);
  Ethernet.init(33);
  Ethernet.begin(mac, ip);

  // Note: Local domain names (e.g. "Computer.local" on OSX) are not supported
  // by Arduino. You need to set the IP address directly.
  client.begin("public.cloud.shiftr.io", net);
  client.onMessage(messageReceived);

  connect();
}

void loop() {
  client.loop();
  delay(10);  // <- fixes some issues with WiFi stability

  if (!client.connected()) {
    connect();
  }

  // publish a message roughly every second.
  if (millis() - lastMillis > 1000) {
    lastMillis = millis();
    client.publish("/hello4711", "world");
  }
}

However, I do not know how to get the MQTTS version working via Ethernet yet...

TheRealDJ commented 3 years ago

I have not done this with Ethernet, just WiFi. I had to change ...

WiFiClient net;

to

WiFiClientSecure net;
const char* cacert = "...";
const char* ssl_key = "...";
const char* ssl_cert = "...";
net.setCACert(cacert);
net.setPrivateKey(ssl_key);
net.setCertificate(ssl_cert);

The client ssl_cert needs to be signed by the same CA as cacert if from. MQTT server also needs a cert signed by cacert. So if you are running your own MQTT server (like mosquitto), you will need to setup a CA to sign the certs.

All of this being said, I don't believe there is an EthernetClientSecure class.

256dpi commented 1 year ago

Closing as stale, please reopen if issue persists.