I need help with coding an Arduino Nano with an W5500 STM32 and bm019

Right so, I'm using an Arduino Nano ESP32, RPI5, and BM019. In short this code reads a rfid tag and sends that data to the rpi via WiFi. However, there isn't enough range between the Arduino and RasPi on WiFi with a USB antenna. I figured that I'd slap on an Ethernet attachment and bobs your uncle, all good. But that is not the case. I think the issue is that I need to tell the Arduino to:
activate the BM019
read the chip
store the data
deactivate BM019
activate the Ethernet
wait for connection
send data
deactivate the Ethernet
activate the BM019
repeat.
Now I am able to ping the nano. So I'm pretty sure its connected to the rpi. Oh I should mention that the RPI is creating an Ethernet connection with:

sudo ip addr add 10.0.0.1/8 dev eth0
sudo ip link set eth0 up

Eventually, I'll config this to auto start but for now I'm just doing this.
So in summary, I was able to use the Arduino Nano to read data from a BM019 and set it to a python program on a raspi5 over WiFi. When I tried to add a Ethernet chip I ran into a few issues I don't know how to fix. I think the solution is to activate and deactivate each chip because only one can be used at a time but I'm not sure how to do that.

I've attached my Ethernet code and my WiFi code for the Arduino as well as the WiFi part of the Python code. The rest is related to other software but I just need the text string from the BM019. I've also attached images of my setup.
Thank you for the help.

W5500 STM32

W5500 STM32 back

nano a

nano b


Ethernet:

/*
 NFC Communication with the Solutions Cubed, LLC BM019
 and an Arduino Nano ESP32. The BM019 is a module that
 carries ST Micro's CR95HF, a serial to NFC converter.

 Wiring:
 Arduino          BM019
 IRQ: Pin 9       DIN: pin 2
 SS: pin 10       SS: pin 3
 MOSI: pin 11     MOSI: pin 5
 MISO: pin 12     MISO: pin4
 SCK: pin 13      SCK: pin 6

 W5500 Wiring:
 Arduino          W5500
 SS: pin 5        SS
 MOSI: pin 11     MOSI
 MISO: pin 12     MISO
 SCK: pin 13      SCK
 */

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

// Ethernet configuration for direct connection
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10, 0, 0, 2);       // ESP32 static IP
IPAddress serverIp(10, 0, 0, 1); // Raspberry Pi IP
const int serverPort = 5000;

EthernetClient client;

const int SSPin = 10;  // Slave Select pin for BM019
const int EthCSPin = 5; // Slave Select pin for W5500
const int IRQPin = 9;  // Sends wake-up pulse
byte TXBuffer[40];    // transmit buffer
byte RXBuffer[40];    // receive buffer
byte NFCReady = 0;  // used to track NFC state

void setup() {
    pinMode(IRQPin, OUTPUT);
    digitalWrite(IRQPin, HIGH);
    pinMode(SSPin, OUTPUT);
    digitalWrite(SSPin, HIGH);
    pinMode(EthCSPin, OUTPUT);
    digitalWrite(EthCSPin, HIGH);

    Serial.begin(115200);
    
    // Initialize SPI
    SPI.begin();
    SPI.setDataMode(SPI_MODE0);
    SPI.setBitOrder(MSBFIRST);
    SPI.setClockDivider(SPI_CLOCK_DIV32);

    // Start Ethernet with static IP
    Ethernet.init(EthCSPin);
    Ethernet.begin(mac, ip);
    
    // No need for DHCP in direct connection
    Serial.print("Ethernet IP address: ");
    Serial.println(Ethernet.localIP());

    // Check Ethernet hardware
    if (Ethernet.hardwareStatus() == EthernetNoHardware) {
        Serial.println("Ethernet shield was not found.");
        while (true);
    }
    
    // Give some time for Ethernet to initialize
    delay(1000);

    // BM019 wakeup pulse
    delay(10);
    digitalWrite(IRQPin, LOW);
    delayMicroseconds(100);
    digitalWrite(IRQPin, HIGH);
    delay(10);
}


/* SetProtocol_Command programs the CR95HF for
 I *SO/IEC 15693 operation.

 This requires three steps.
 1. send command
 2. poll to see if CR95HF has data
 3. read the response

 If the correct response is received the serial monitor is used
 to display successful programming.
 */
void SetProtocol_Command()
{
    byte i = 0;

    // step 1 send the command
    digitalWrite(SSPin, LOW);
    SPI.transfer(0x00);  // SPI control byte to send command to CR95HF
    SPI.transfer(0x02);  // Set protocol command
    SPI.transfer(0x02);  // length of data to follow
    SPI.transfer(0x01);  // code for ISO/IEC 15693
    SPI.transfer(0x0D);  // Wait for SOF, 10% modulation, append CRC
    digitalWrite(SSPin, HIGH);
    delay(1);

    // step 2, poll for data ready

    digitalWrite(SSPin, LOW);
    while(RXBuffer[0] != 8)
    {
        RXBuffer[0] = SPI.transfer(0x03);  // Write 3 until
        RXBuffer[0] = RXBuffer[0] & 0x08;  // bit 3 is set
    }
    digitalWrite(SSPin, HIGH);
    delay(1);

    // step 3, read the data
    digitalWrite(SSPin, LOW);
    SPI.transfer(0x02);   // SPI control byte for read
    RXBuffer[0] = SPI.transfer(0);  // response code
    RXBuffer[1] = SPI.transfer(0);  // length of data
    digitalWrite(SSPin, HIGH);

    if ((RXBuffer[0] == 0) & (RXBuffer[1] == 0))  // is response code good?
    {
        Serial.println("Protocol Set Command OK");
        NFCReady = 1; // NFC is ready
    }
    else
    {
        Serial.println("Protocol Set Command FAIL");
        NFCReady = 0; // NFC not ready
    }
}

/* Inventory_Command chekcs to see if an RF
 t *ag is in range of the BM019.

 This requires three steps.
 1. send command
 2. poll to see if CR95HF has data
 3. read the response

 If the correct response is received the serial monitor is used
 to display the the RF tag's universal ID.
 */
void Inventory_Command()
{
    byte i = 0;

    // step 1 send the command
    digitalWrite(SSPin, LOW);
    SPI.transfer(0x00);  // SPI control byte to send command to CR95HF
    SPI.transfer(0x04);  // Send Receive CR95HF command
    SPI.transfer(0x03);  // length of data that follows is 0
    SPI.transfer(0x26);  // request Flags byte
    SPI.transfer(0x01);  // Inventory Command for ISO/IEC 15693
    SPI.transfer(0x00);  // mask length for inventory command
    digitalWrite(SSPin, HIGH);
    delay(1);

    // step 2, poll for data ready
    // data is ready when a read byte
    // has bit 3 set (ex:  B'0000 1000')

    digitalWrite(SSPin, LOW);
    while(RXBuffer[0] != 8)
    {
        RXBuffer[0] = SPI.transfer(0x03);  // Write 3 until
        RXBuffer[0] = RXBuffer[0] & 0x08;  // bit 3 is set
    }
    digitalWrite(SSPin, HIGH);
    delay(1);


    // step 3, read the data
    digitalWrite(SSPin, LOW);
    SPI.transfer(0x02);   // SPI control byte for read
    RXBuffer[0] = SPI.transfer(0);  // response code
    RXBuffer[1] = SPI.transfer(0);  // length of data
    for (i=0;i<RXBuffer[1];i++)
        RXBuffer[i+2]=SPI.transfer(0);  // data
        digitalWrite(SSPin, HIGH);
    delay(1);

    if (RXBuffer[0] == 128)  // is response code good?
    {
        Serial.println("Inventory Command OK");
        NFCReady = 2;
    }
    else
    {
        Serial.println("Inventory Command FAIL");
        NFCReady = 0;
    }
}

/* Write Memory writes data to a block of memory.
 T *his code assumes the RF tag has less than 256 blocks
 of memory and that the block size is 4 bytes.  The block
 written to increments with each pass and if it exceeds
 20 it starts over. Data is also changed with each write.

 This requires three steps.
 1. send command
 2. poll to see if CR95HF has data
 3. read the response
 */

void loop() {
    if (NFCReady == 0) {
        delay(100);
        SetProtocol_Command();
    } else if (NFCReady == 1) {
        delay(100);
        Inventory_Command();
    } else {
        delay(100);
        Read_Memory();
    }
    delay(2000);
}

void Read_Memory() {
    byte i = 0;
    byte block = 0;
    byte totalBlocks = 28;
    String chipData = "chip_data:";

    for (block = 0; block < totalBlocks; block++) {
        digitalWrite(SSPin, LOW);
        SPI.transfer(0x00);
        SPI.transfer(0x04);
        SPI.transfer(0x03);
        SPI.transfer(0x02);
        SPI.transfer(0x20);
        SPI.transfer(block);
        digitalWrite(SSPin, HIGH);
        delay(1);

        digitalWrite(SSPin, LOW);
        while (RXBuffer[0] != 8) {
            RXBuffer[0] = SPI.transfer(0x03);
            RXBuffer[0] = RXBuffer[0] & 0x08;
        }
        digitalWrite(SSPin, HIGH);
        delay(1);

        digitalWrite(SSPin, LOW);
        SPI.transfer(0x02);
        RXBuffer[0] = SPI.transfer(0);
        RXBuffer[1] = SPI.transfer(0);
        for (i = 0; i < RXBuffer[1]; i++) {
            RXBuffer[i + 2] = SPI.transfer(0);
        }
        digitalWrite(SSPin, HIGH);
        delay(1);

        if (RXBuffer[0] == 128) {
            for (i = 0; i < 4; i++) {
                byte dataByte = RXBuffer[3 + i];
                if (dataByte < 0x10) {
                    chipData += "0";
                }
                chipData += String(dataByte, HEX);
                if (block != totalBlocks - 1 || i != 3) {
                    chipData += ":";
                }
            }
        } else {
            Serial.println("Read Memory Block Command FAIL");
            return;
        }
    }

    // Ethernet connection to Raspberry Pi
    if (client.connect(serverIp, serverPort)) {
        client.println(chipData);
        client.stop();
        Serial.println("Data sent to Raspberry Pi");
    } else {
        Serial.println("Failed to connect to Raspberry Pi!");
    }
}

python

# Constants
#SERVER_IP = '0.0.0.0'
SERVER_IP = '10.0.0.2'  # Pi's Class A IP
#SERVER_IP = '192.168.1.100'
SERVER_PORT = 5000
...
def handle_client(client_socket):
    try:
        while True:
            data = client_socket.recv(4096).decode('utf-8')
            if not data:
                break
            if data.startswith("chip_data:"):
                chip_queue.put(data[len("chip_data:"):].strip())  # Add chip data to the queue
            else:
                logging.warning("Invalid data received.")
    except Exception as e:
        logging.error(f"Error handling client: {e}")
    finally:
        client_socket.close()

def start_server():
    try:
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.bind((SERVER_IP, SERVER_PORT))
        server_socket.listen(1)
        logging.info(f"Listening for connections on {SERVER_IP}:{SERVER_PORT}...")

        while True:
            client_socket, client_address = server_socket.accept()
            logging.info(f"Connection from {client_address}")
            threading.Thread(target=handle_client, args=(client_socket,)).start()
    except Exception as e:
        logging.error(f"Error starting server: {e}")
    finally:
        server_socket.close()

No need to 'activate' one chip at a time. Try posting a picture of a hand-drawn wiring diagram. The pictures are not 100% readable. Only post code you are using.

Yeah do you have a recommendation for software I could use to make the diagram. At the moment I just wrote everything down in a table to keep track.

Hand drawn, NO software needed. We want to see the ACTUAL connections. Try to label everything as well.

I assume the 3.3v and G are connected to the rails, which are then connected to the power supply.
Are you going to use Ethernet or wifi?
Once you decide that you should be good to go.
EXCEPT when I looked for their website it was 404 so that might be a clue.
I don't read Python, so I probably can't help much more.
Good luck.

Ethernet and oh my god that might be it I forgot to connect the ground and power back to the rails.

Okay I added the power to the rails. But still nothing. I'm going to try to go back to the original code I found on the wayback machine.

okay so the base code works. I'm going to add in a serial print to see if the bm019 and w5500 still work and maybe there's a networking error.

okay so two things 1. I added a Serial.println(chipData); to line 277 just above the code that sends the data to the raspi. 2. I noticed that "Inventory Command FAIL" keeps triggering. So that's where I'm gonna start looking.

However, before I start I think the devices are having SPI conflicts. I'm not sure how to fix that, if this is the case. This code is pretty new to me.

Okay well, I'm gonna take a break. I have a WIZ550io so I'm going to try that later.

Yeah so I've been trying with the WIZ550io and now its just not outputting anything to the serial monitor. I'm not sure whats wrong wiring or my code but I'm going to try a different Arduino that operates at 3.3v logic or a teensy 4.1. I'm sorry to anyone that comes across this form in the future.