How to use w5500 on SPI1 /and/ keep Cellular?

And -

void setup() {
    startSerialX();                                                  
    setupTCP();
    setupParticleCloud()                                       // For Particle funcs, vars to cloud
}

void loop() {
    if (Particle.connected() == false) {
        Particle.connect();
    }
    loopTCP();
}

Along with -

#include "TCP.h"

unsigned long lastLogT = 0;                              
unsigned long tcpRead = 5000;                              // 5, 10, etc. ms           

EthernetClient eClient;
byte mac[] = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed };
IPAddress servIP(10,1,1,39);
int servPort = 1701;


void setupTCP() 
{
    lastLogT = millis();
    if (Ethernet.begin(mac) == 0) {
        Log.info("Failed to config Eth using DHCP");
    }
    Log.info("Eth IP addr is: %s", Ethernet.localIP().toString().c_str());
}

void loopTCP()
{
    if (millis() - lastLogT >= tcpRead) {
        lastLogT = millis();
        if (!eClient.connected()) {
            if (eClient.connect(servIP, servPort, 1)){
                Log.info("Connected to serv");
                eClient.println("user1");
            } else {
                Log.info("Could not cnx to serv");
            }
        }

        if (eClient.connected() && eClient.available() > 0) {
            while (eClient.available() > 0){
                Log.info((const char*)eClient.read());
            }
        }
    }
}

Noting I throttled the TCP loop so it's easier to debug and doesn't run amok if I put the wrong address or something :joy:

Since you don't connect to the cloud until loop() I'd guess that something called from setup() is blocking. I'd just keep adding serial debug statements until you figure out what.

Ok see that's another thing, not getting any serial debug statements, even tho 'particle serial monitor' connects fine... and even tho I'm using Log.info (avoid Serial.Println that may block).

And you think Particle.connect() should go up in Setup()?
Coz I have it in Loop() so that my setupParticleCloud() has time to run in Setup();

Believe you / the docs said that Particle.function and Particle.variable should be put at end of Setup() such that -

  1. any user code can register with the cloud, and
  2. still has to happen quickly so that cloud actually registers (doesn't timeout)

In fact that's the only reason (I can recall) to do SYSTEM_MODE(SEMI_AUTOMATIC) and SYSTEM_THREAD(ENABLED), so that Particle.connect() can be run manually again (even tho it's prob run automatically earlier, no?)

And,

Not entirely sure what could block, like wrong MAC (does it even matter)? DHCP didn't issue? etc.

Do you have the serial log handler enabled? This should be a global.

SerialLogHandler logHandler;

I'd do Particle.function and Particle.variable, then call Particle.connect() after those are done.

Yessir,
I prob should have mentioned but yet it's been working great before this -

SerialLogHandler logHandler(115200, LOG_LEVEL_INFO);                // Default is Log.info, but can do trace, can 'overload' w/ specifics

Ok, and no need to re-run Particle.connect() in Loop(), because of SYSTEM_MODE(SEMI_AUTOMATIC)?

Correct. Just call Particle.connect() once in SEMI_AUTOMATIC mode, assuming you don't manually disconnect, of course.

Ok, thanks.

And suppose that setupTCP() call is also blocking the global SerialLogHandler ?


EDIT
Yes, this line seems to block both (logs and cellular) -

     if (Ethernet.begin(mac) == 0) {
         Log.info("Failed to config Eth using DHCP");
     }

Back to 1st part,
What's the trick to get w5500 working on SPI1?

Aside from that above (change - pin assignment from A2 to D5; SPI to SPI1 in libs w5500.h, Ethernet.h; uncomment SPI1.beginTransaction)

Noting this is a bit cleaner -

void loopTCP()
{
    if (millis() - lastLogT >= tcpRead) {
        lastLogT = millis();

        if (!cnxT) {
            Log.info("Trying Eth.begin");
            Ethernet.begin(mac, locIP, locIP, locIP);
            Log.info("Eth IP addr is: %s", Ethernet.localIP().toString().c_str());
        }

        if (!eClient.connected()) {
            if (eClient.connect(servIP, servPort, 1)){
                Log.info("Connected to serv");
            } else {
                Log.info("Could not cnx to serv");
            }
        } else {
            eClient.println("user1");

            if (eClient.available() > 0) {
                while (eClient.available() > 0){
                    Log.info((const char*)eClient.read());
                }
            }
        }
    }
}

Also note

  1. Gen2 running OS 3.0.0
  2. Going thru a switch (to auto MDIX, so don't have to worry about crossover cable)
  3. Can confirm socket on server w/ telnet program

Which Ethernet library are you using? You'd have to search there, as the Electron does not support the Ethernet class that's described in the docs and I've never used Ethernet on Gen 2.

This one in community libs -

And the repo -

Not sure what that mean.. Even if it leverages the same spark_wiring_'xyz' libs?

That's using the class Ethernet in the NCD_Ethernet_Overlay library in the file Ethernet.h in the library.

The definition of the Ethernet class in spark_wiriing_ethernet.h isn't used because the header file is protected with #if test and Wiring_Ethernet is 0 for Gen 2 devices including the Electron.

Forgive my ignorance,

So I do have the NCD_ lib in Workbench -
image

And you're saying don't call Ethernet.begin but rather EthernetClass.begin (more specifically, eClass.begin, below) as defined in the NCD lib (vs the other / default / incompatible Ethernet lib)?
So then -

EthernetClass eClass;
EthernetClient eClient;
byte mac[] = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed };
IPAddress locIP(10,1,1,102);                            
IPAddress servIP(10,1,1,39);
int servPort = 1701;


void setupTCP() 
{
    lastLogT = millis();

}

void loopTCP()
{
    if (millis() - lastLogT >= tcpRead) {
        lastLogT = millis();

        if (!cnxT) {
            Log.info("Trying Eth.begin");
            eClass.begin(mac, locIP, locIP, locIP);
            Log.info("Eth IP addr is: %s", eClass.localIP().toString().c_str());
        }

        if (!eClient.connected()) {
            if (eClient.connect(servIP, servPort, 1)){
                Log.info("Connected to serv");
            } else {
                Log.info("Could not cnx to serv");
            }
        } 
    }
}

Noting the repeat locIP is just repeating the same IP as a default value for the local w5500, before it connects to remote (server) TCP socket.

And that I don't really want to alter the NCD lib, just use as-is and then further implement read, write in my own TCP file.


EDIT
And following the lib chain -
image

That <Ethernet.h> above resolves to NCD_Ethernet_Overlay (and so forth) -
image

No, Ethernet.begin() is correct. EthernetClass is the C++ class name, Ethernet is the single instance of that class (scroll down to the bottom of the Ethernet.h file to see it).

But in looking at W5500.cpp, the problem is that the library does not work with SPI1. Every call to SPI is hardcoded to SPI to you'd need to modify the library to use SPI1.

Ah yes thanks

Yes exactly! Tried to show that in screenshots above, but doesn't seem to open a client..

You'll have to dig in farther then. I'd add serial print statement when it reads a register. If it's coming back all 0xff or 255, then the W5500 is not responding, which could be a connection issue.

Hm ok,

I did also uncomment the SPI1.beginTransaction statements in w5500.cpp / .h, going by other forum threads where I believe you said the beginTransaction is important for traffic on SPI bus

Using SPI1.beginTransaction() is required if you have more than one device on the SPI1 bus. It's a good idea to always enable it.

Ok happy to report sorting out some pins 'almost' got it working.
Many thanks rickkas7.

Note, made Electron OUTPUT_OPEN_DRAIN on interrupt-pin and OUTPUT, HIGH on reset-pin.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.