Using PubSubClient with Ethernet shield

Hello everyone,

I have an ESP32 that I am using the Arduino ethernet shield on. I am creating a LED controller that can accept commands via Ethernet. I am using the WiFi to configure the Ethernet settings.

I am also setting up a MQTT server and using the PubSubClient library to handle MQTT communications.

What is happening right now is that I am not connecting to the MQTT server from my ESP32. However, I am able to ping it from my laptop and the ESP32 Ethernet is on the same network.

Just a quick question, I am wondering if the PubSubClient library defaults to using the WiFi instead of the Ethernet. Would this be the case?

PubSubClient uses a provided Client object

Thank you. I see that the Ethernet class is used in the Client object.

In that case, I am sort confused on why my board is unable to connect. I am able to ping the server. What are some debug steps that I can take to find the solution to the problem?

can you show us some code you use?

No problem. Actually, I want to back up a bit. I realized that the dev board I was using does not properly reflect the chip that I will use in my final application. I was using the first version of the Ethernet Shield. I updated my schield to use rev 2 which has the W5500 chip on it (the chip I will use in my application)

Now however, I am unable to get my ESP to connect to the Ethernet controller. Here is my setup code which I am running

void setup()
{
    delay(1000);
    pinMode (RST_PIN, OUTPUT);
    digitalWrite(RST_PIN, HIGH);
    delay(1000);
    digitalWrite(RST_PIN, LOW);

    memset(StaticRoomArray, 0, ROOM_ARRAY_SIZE * sizeof(ChannelObject));

    pinMode(LEVEL_TRANSLATOR_OE_PIN, OUTPUT);
    

    digitalWrite(LEVEL_TRANSLATOR_OE_PIN, HIGH);
    //digitalWrite(RST_PIN, HIGH);

    Serial.begin(115200);

    Wire.begin();
    //wifiSetup();

    Serial.println(F("-------- New Program Running --------"));

   /*****************************************************************
    * NOTE: FOR THE ESP32 WITH LEVEL TRANSLATORS, IT IS RECOMMENDED *
    * TO SET THE FREQUENCY OF SPI TO 8 MHZ INSTEAD OF THE DEFAULT.  *
    * DO NOT FORGET TO DO THIS                                      *
    *****************************************************************/
    digitalWrite(15, HIGH);
    delay(5000);

    esp_reset_reason_t reset_reason = esp_reset_reason();
    Serial.println("reset reson:");
    Serial.println(reset_reason);

    if(reset_reason == ESP_RST_POWERON){
        ESP.restart();
    }

    SPI.begin(SCLK_PIN, MISO_PIN, MOSI_PIN, SS_PIN);

    pinMode(SD_CARD_CS, OUTPUT);
    digitalWrite(SD_CARD_CS, HIGH);

    pinMode(Ethernet_CS_PIN, OUTPUT);
    digitalWrite(Ethernet_CS_PIN, HIGH);

   // parseNetworkConfigFile();
    Serial.println("Enableing DHCP");
    Ethernet.init(Ethernet_CS_PIN);// Technically, in this function, the SPI is initilized. On the development computer, this was commented out and placed above. Need testing to see if program will still function with SPI being initilized in Ethernet init function

    if(dhcpEnabled)
        Ethernet.begin(mac, ip);
        //Serial.println(Ethernet.begin(mac, ip));
    else
        Ethernet.begin(mac, ip, dns, gateway, subnet);

    Serial.println("Connection Setup w/ IP Address:");
    Serial.println(Ethernet.localIP());

    //digitalWrite(Ethernet_CS_PIN, HIGH);

    if (Ethernet.hardwareStatus() == EthernetNoHardware){
        #ifdef ENABLE_SERIAL_DEBUG
        Serial.println(F("Ethernet Hardware not connected"));
        #endif
    }
    else if (Ethernet.hardwareStatus() == EthernetW5500)
    {
        #ifdef ENABLE_SERIAL_DEBUG
        Serial.println(F("Ethernet connected"));
        #endif

        udp.begin(localPort);
        ethernetHardwareConnected = true;
    }

     if (Ethernet.linkStatus() == LinkOFF)
         Serial.println(F("No cable connected"));
     else if (Ethernet.linkStatus() == LinkON)
         Serial.println(F("Link status up and communicating"));
     else
         Serial.println(F("Ethernet hardware not connected"));

    // Open file of SD Card file logic here and read into a string
    readLEDConfigFile();

    // Set the MQTT server to the server stated above 
    Serial.println("Connecting to MQTT server");
   // mqttClient.connect(serverIP, 1883);
    mqttClient.setServer(server, 1883);   
    if(mqttClient.connect("board-1231231231231")){
        Serial.println("Connection established");
        mqttClient.setCallback(subscribeReceive);
    } else {
        Serial.println("Connection not established");
    }

    computeLargestLED();

    associateLEDStrips();

    InitLEDStates();
	
	InitLEDDataArray();

    esp_task_wdt_init(5, true); //enable panic so ESP32 restarts
    esp_task_wdt_add(NULL); //add current thread to WDT watch
    ethernetTime = millis();
}

In the Ethernet library, I edited the isW5500 function:

uint8_t W5100Class::isW5500(void)
{
	chip = 55;
	Serial.println("w5100.cpp: detect W5500 chip");
	if (!softReset()) return 0;
	Serial.println("Writeing MR 0x08");
	writeMR(0x08);
	uint8_t MRValue = readMR();
	Serial.println("MR Value: " + String(MRValue));
	if (readMR() != 0x08) return 0;
	Serial.println("Writeing MR 0x10");
	writeMR(0x10);
	if (readMR() != 0x10) return 0;
	Serial.println("Writeing MR 0x00");
	writeMR(0x00);
	if (readMR() != 0x00) return 0;
	int ver = readVERSIONR_W5500();
	Serial.print("version=");
	Serial.println(ver);
	if (ver != 4) return 0;
	Serial.println("chip is W5500");
	return 1;
}

This is the output that I get:

-------- New Program Running --------
reset reson:
3
Enableing DHCP
w5100 init
mr=0
w5100.cpp: detect W5500 chip
mr=0
Writeing MR 0x08
MR Value: 0
mr=0
Connection Setup w/ IP Address:
0.0.0.0
Ethernet Hardware not connected
w5100 init
mr=0
w5100.cpp: detect W5500 chip
mr=0
Writeing MR 0x08
MR Value: 0
mr=0
w5100 init
mr=0
w5100.cpp: detect W5500 chip
mr=0
Writeing MR 0x08
MR Value: 0
mr=0
Ethernet hardware not connected
Got Value:
2
LED Config Set
Sending over the data:
LEDConfiguration 2 /
Connecting to MQTT server
Connection not established
Exiting Setup

Ethernet.begin(mac, ip); is not DHCP Ethernet.begin(mac); is DHCP.

The esp32 now can integrate W5500 as a network interface for the WiFi library. arduino-esp32/libraries/Ethernet/examples/ETH_W5500_Arduino_SPI/ETH_W5500_Arduino_SPI.ino at master · espressif/arduino-esp32 · GitHub

Hello Thank you for your feedback. I do want to do DHCP, I have that code in there because I was debugging some communication issue with my router.

Thank you for the code snippet! I will take a look at it.

Just to check I am using the WiFi on the ESP32 as an AP for ESP32 device configuration. Will there be any interference from my WiFi settings?

So looking through it, that code only appears in the preview 3.0 version. I set my platform and platform_packages to master (I am using platform.io) and this is the error I am getting

KeyError: 'framework-arduinoespressif32-libs':
  File "C:\Users\Phillip\.platformio\penv\Lib\site-packages\platformio\builder\main.py", line 173:
    env.SConscript("$BUILD_SCRIPT")
  File "C:\Users\Phillip\.platformio\packages\tool-scons\scons-local-4.5.2\SCons\Script\SConscript.py", line 598:
    return _SConscript(self.fs, *files, **subst_kw)
  File "C:\Users\Phillip\.platformio\packages\tool-scons\scons-local-4.5.2\SCons\Script\SConscript.py", line 285:
    exec(compile(scriptdata, scriptname, 'exec'), call_stack[-1].globals)
  File "C:\Users\Phillip\.platformio\platforms\espressif32@src-c9ee9fd137fb075309142d83ce51f0bc\builder\main.py", line 346:
    target_elf = env.BuildProgram()
  File "C:\Users\Phillip\.platformio\packages\tool-scons\scons-local-4.5.2\SCons\Util\envs.py", line 242:
    return self.method(*nargs, **kwargs)
  File "C:\Users\Phillip\.platformio\penv\Lib\site-packages\platformio\builder\tools\piobuild.py", line 61:
    env.ProcessProgramDeps()
  File "C:\Users\Phillip\.platformio\packages\tool-scons\scons-local-4.5.2\SCons\Util\envs.py", line 242:
    return self.method(*nargs, **kwargs)
  File "C:\Users\Phillip\.platformio\penv\Lib\site-packages\platformio\builder\tools\piobuild.py", line 121:
    env.BuildFrameworks(env.get("PIOFRAMEWORK"))
  File "C:\Users\Phillip\.platformio\packages\tool-scons\scons-local-4.5.2\SCons\Util\envs.py", line 242:
    return self.method(*nargs, **kwargs)
  File "C:\Users\Phillip\.platformio\penv\Lib\site-packages\platformio\builder\tools\piobuild.py", line 342:
    SConscript(env.GetFrameworkScript(name), exports="env")
  File "C:\Users\Phillip\.platformio\packages\tool-scons\scons-local-4.5.2\SCons\Script\SConscript.py", line 662:
    return method(*args, **kw)
  File "C:\Users\Phillip\.platformio\packages\tool-scons\scons-local-4.5.2\SCons\Script\SConscript.py", line 598:
    return _SConscript(self.fs, *files, **subst_kw)
  File "C:\Users\Phillip\.platformio\packages\tool-scons\scons-local-4.5.2\SCons\Script\SConscript.py", line 285:
    exec(compile(scriptdata, scriptname, 'exec'), call_stack[-1].globals)
  File "C:\Users\Phillip\.platformio\platforms\espressif32@src-c9ee9fd137fb075309142d83ce51f0bc\builder\frameworks\arduino.py", line 41:
    SConscript(
  File "C:\Users\Phillip\.platformio\packages\tool-scons\scons-local-4.5.2\SCons\Script\SConscript.py", line 662:
    return method(*args, **kw)
  File "C:\Users\Phillip\.platformio\packages\tool-scons\scons-local-4.5.2\SCons\Script\SConscript.py", line 598:
    return _SConscript(self.fs, *files, **subst_kw)
  File "C:\Users\Phillip\.platformio\packages\tool-scons\scons-local-4.5.2\SCons\Script\SConscript.py", line 285:
    exec(compile(scriptdata, scriptname, 'exec'), call_stack[-1].globals)
  File "C:\Users\Phillip\.platformio\packages\framework-arduinoespressif32\tools\platformio-build.py", line 40:
    FRAMEWORK_LIBS_DIR = platform.get_package_dir("framework-arduinoespressif32-libs")
  File "C:\Users\Phillip\.platformio\penv\Lib\site-packages\platformio\platform\_packages.py", line 32:
    pkg = self.get_package(name)
  File "C:\Users\Phillip\.platformio\penv\Lib\site-packages\platformio\platform\_packages.py", line 29:
    return self.pm.get_package(spec or self.get_package_spec(name))
  File "C:\Users\Phillip\.platformio\penv\Lib\site-packages\platformio\platform\_packages.py", line 21:
    owner=self.packages[name].get("owner"),

yes it is only on version 3 and that version is still under heavy development.

sorry, but I don't understand what is the problem with the Ethernet library you have

Hello Juraj,

After much exploring, I don't think that the version 3 route will hold up as Espressif is dropping suppot for Platform.IO (my IDE) and it is not clear on how I can get the library to work with Arduino.

There are reports that the standard ethernet library should work with the ESP32 but I am not sure.

The issue that I am having is in here:

uint8_t W5100Class::isW5500(void)

{

chip = 55;

Serial.println("w5100.cpp: detect W5500 chip");

if (!softReset()) return 0;

writeMR(0x08);

int someValue = readMR();

Serial.println(String(someValue));

if (someValue != 0x08) return 0;

writeMR(0x10);

if (readMR() != 0x10) return 0;

writeMR(0x00);

if (readMR() != 0x00) return 0;

int ver = readVERSIONR_W5500();

//Serial.print("version=");

//Serial.println(ver);

if (ver != 4) return 0;

//Serial.println("chip is W5500");

return 1;

}

The variable someValue is reading back as 0 when it should be 0x08

the Ethernet library works with esp32.
use the the default SPI pins (18,19,23,5 for classic esp32).
the Ethernet library calls SPI.begin().

How are you initializing the mqttClient?

Hello,

Thank you for your feedback, I am currently using pins:

MOSI - 23
MISO - 19
SCK - 18
Ethernet_CS - 5

I am also using the ESP32 DevKitC

so I have the dev mdule with a w5500 on a breadboard right here. but it has the w5500 wired to the other set of SPI pins because that is default for the ETH library and simpler to wire on a breadboard with the dev module leaving only one contacts row on one side of the module.
so I configured SPI.begin for the pin 12, 13,, 14 and CS 27 and it worked too with the Ethernet library.

@Juraj
Thanks, this link here is the Dev kit that I have:

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-devkitc.html

Here is a link for the pinout:


Here is the link to particular section of the schematic. I have a 3.3 - 5 V level translator. Like I said before, everything works fine with R1 of the dev board:

and here is a code snippet for the section in question:

Serial.println("Enabling SPI");
    SPI.begin(18, 19, 23, 0);
    Ethernet.init(0);
    Ethernet.begin(mac, ip);

    if(Ethernet.hardwareStatus() == EthernetW5500){
        Serial.println("Working");
    } else {
        Serial.println("NOt working");
    }

Please tell me if there is anything that I am missing?

I should also note that in the SPI, I reduced the clock frequency down to 8 MHz just in case. I also hardcoded my pin values for the SPI.begin that is found in the ethernet library

you have now io 0 as CS?

Yeah, I think that i had a typo in my original message. I thought that it was IO5 but instead it is IO0

I think that it shouldn't matter because I am forcing the CS pin to be IO0 correct?