WIZnet Developer Forum

Wiz550io Mbed Matlab bidirectional communication

I am trying to transfer data from Matlab running on a PC and Mbed Nucleo F401RE using wiz550io module. I am only able to send data one way from Matlab to Mbed board. Could someone please help me with the transfer of data from f401re to Matlab? My objective is that Matlab sends some data fetching commands to f401re which then responds to the commands by sending data to Matlab eg. data could be a decimal or floating point number. I am using the following code: Thanks

Nucleo code:

    SPI spi2(PC_12, PC_11, PC_10); // mosi, miso, sclk
    EthernetInterface eth(&spi2, PC_6, PB_8);
    wait(1); // 1 second for stable state

    // late binding
    TCPSocketServer svr;
    TCPSocketConnection client;

    ledTick.attach(&ledTickfunc,2);

    // as your env. change to real IP address and so on.
    int     ret = eth.init(MY_IP, MY_NETMASK, MY_GATEWAY);
    if (!ret) {
        serial.printf("Initialized, MAC: %s\n\r", eth.getMACAddress());
        serial.printf("Connected, IP: %s, MASK: %s, GW: %s\n\r",
                      eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
    } else {
        serial.printf("Error eth.init() - ret = %d\n\r", ret);
        return -1;
    }

    //setup tcp socket
    if(svr.bind(PORT)< 0) {
        serial.printf("tcp server bind failed.\n\r");
        return -1;
    } else {
        serial.printf("tcp server bind successed.\n\r");
        serverIsListened = true;
    }

    if(svr.listen(1) < 0) {
        serial.printf("tcp server listen failed.\n\r");
        return -1;
    } else {
        serial.printf("tcp server is listening...\n\r");
    }
    
    char buffer[1024] = {};
    //listening for http GET request
    while (serverIsListened) {
        //blocking mode(never timeout)      
        
        if(svr.accept(client)<0) {
            serial.printf("failed to accept connection.\n\r");
        } else {
            serial.printf("connection success!\n\rIP: %s\n\r",client.get_address());
            clientIsConnected = true;
   
            while(clientIsConnected) {
                switch(client.receive(buffer, 1023)) {
                    case 0:
                        serial.printf("recieved buffer is empty.\n\r");
                        clientIsConnected = false;
                        client.close();
                        break;
                    case -1:
                        serial.printf("failed to read data from client.\n\r");
                        clientIsConnected = false;
                        client.close();
                        break; 
                    default:
                        serial.printf("Recieved Data: %d\n\r\n\r%.*s\n\r",strlen(buffer),strlen(buffer),buffer);
                        if(buffer[0] == 'G' && buffer[1] == 'E' && buffer[2] == 'T' ) {
                            serial.printf("GET request incomming.\n\r");
                            wait(1);
                            //sprintf(buffer,"14.5\n\r",strlen(buffer));
                            client.send(buffer,strlen(buffer));
                            clientIsConnected = false;
                            serial.printf("echo back done.\n\r");
                        } 
                        for(int i =0; i < 1023; i++) buffer[i] = '\0';
                        clientIsConnected = false;   // *** 
                        client.close(); // ***
                        break;
                } // switch(client.receive(buffer, 1023))
                client.close(); // ***
            } // while(clientIsConnected)
            serial.printf("close connection here.\n\rtcp server is listening...\n\r");
            client.close();
        } //if(svr.accept(client)<0)
    } //while (serverIsListened)

Matlab Code

try
%Create a client interface and open it.
t = tcpip('163.1.6.228', 8080, 'NetworkRole', 'client');
fopen(t);
% Write the waveform to the server session.
fwrite(t, 'GET10.55')
disp('1 Success!');
fclose(t);
catch
    disp('1 Failed!');
    fclose(t);
end

try
%Create a server interface and open it.
t = tcpip('163.1.6.228', 8080, 'NetworkRole', 'server');
fopen(t);
data = fread(t, t.BytesAvailable)
disp('2 Success!');
fclose(t);
catch
    disp('2 Failed!');
    fclose(t);
end

More information is needed from you. I see you have some debug output in the code. You need to tell us HOW you are unable to send data. Where process fails. Which error messages you have. Do you use same communication session for data exchange (server connects W5500 module, sends info to it, and then waits to get data reply back)? Or W5500 module is expected to contact server independently and flush its data to server?

Thanks for the reply. I am printing messages to a hyperterminal/Uart/teraTerm interface to see the progress of the code. I am new to this field, but here is my understanding:

Well Matlab (code attached) is not reading any data and it times out.

At present, a simple code is used such that when Matlab sends a commands GET10.55, wiz5500 should reply with the same message. Wiz550 is receiving this command as I am printing it to a hyperterminal of a PC. On the other side, matlab is not displaying data received but displays “2 Failed!”, and this message is only possible (I believe) if TCP on the matlab side times out.

In your W5500 code it is not seen which settings you use. Gateway address is a valid address of the gateway? MAC address? Source port? Destination port (should be 8080)?

Thanks, all these settings are correct as I am receiving data from Matlab or PC. However, in the other direction: there is some issue either with the wiz550 code or Matlab code.

We can be sure that you have correct and enough setting for W5500 to receive data. But you have problems with sending, and what you currently have is not enough to perform this operation - either from configuration or software points of view. I asked for specific information, if you do not provide it I can not help.

Thank you! It took a little while to succeed with bidirectional communication, but the code is continuously polling which blocks the while loop. But, as expected I am missing data most of the time.

Is it possible to have an ISR for transferring the data? My progress with ISR has been slow, but I am attaching my code if you would like to view all the information, as you suggested in your last reply.

Thank you once again!
MatlabToFromNucleo_gcc_arm_nucleo_f401re.zip (527 KB)

Where is this code (the project you attached is big one, please point to the specific code).
In general YOU write or adjust the code according to your requirements. If you need real bidirectional communication, then there should be a loop which will check both channels - receive channel, and thus if there’s anything in there get the data from it and instruct W5500 continue receiving using RECV command, and sending - if application needs to send something your W5500 driver should check for free send buffer, place data there and issue SEND command.

You use TCP, you simply can not miss data which have been communicated :slight_smile:
Your task, as I said above, is to regularly check for both receive and send “tasks”.

Interrupts will add another layer of complexity to your design - I think you better make things work in as simple as possible way.

Here is the code that I have been working with, but I am not including any wiznet libraries which are available at https://developer.mbed.org/teams/EthernetInterfaceW5500-makers/code/W5500Interface/.

Initially, I tried this https://developer.mbed.org/users/bingdo/code/frdm_Ethernet_WIZ550io/file/11f7f413e10d/main.cpp
However, it blocks the while loop, hence any other (non Ethernet related) code cannot be executed. Therefore, I am trying the possibility of using an interrupt which will set a flag that will be used to read the new data and send data as required. My current code is attached.

As I am understanding from your comments: The wiz550io device will continue to fill incoming data to its eight sockets then perhaps overlaps. I can read data from these sockets any time? Is this correct?
main.cpp (10.2 KB)

No. For TCP when you start connection with remote device and it sends some data, W5500 receives this data until its RX buffer is full. Then W5500 sends special packet to remote device to suspend communication. Remote device will not send anything else until W5500 sends another special packet to it instructing it to continue sending. This packet sending is triggered by “RECV” command which informs W5500 about freed RX buffer, and makes W5500 sending that special packet to remote host.
My explanation probably is not completely correct, but it gives you idea how it works.

With incoming data you should do two actions: read data which W5500 received, and reset TX RD pointer to the end of data which you have read. This will inform W5500 that there’s free space in RX buffer now; then you issue RECV command, and it continues communication until (a) RX buffer is full again, or (b) remote host has disconnected.

You do not need interrupt to set flags. Flags are already there - either you use IR interrupt register, or you regularly check socket pointers (e.g RX_RSR for received size). ISR is usually used to perform the job flushing from or putting data into W5500 socket buffers and perform data transfers.

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.