..

Dependencies:   ESP8266Interface WIZnetInterface_namespace mbed-src

Dual Network Interface

Some our customers want dual network interface like below. /media/uploads/SteveKim/dual-nic-2.jpg

So, I decided to implement dual network interface with ESP8266(WiFi) and WIZwiki-W7500(Ethernet).

Implementation

But, I had some troubles because of the below.

  • There is no abstract class for all network interface
  • Same header file name in two library WIZnetInterface(EthernetInterface) and ESP8266Interface
  • Same class name in two library WIZnetInterface and ESP8266Interface

If I can modify Makefile, there will be better way to solve this problem. But, I couldn't modify Makefile in mbed.

So I solved this problem using namespace. Of course, there may be another way to change all class name and file name in the library. But, I wanted to minimize the changes of original library.

First, I changed the header file name in WIZnetInterface from <*.h> to <*.hpp>.

Declaration namespace in header file

// Endpoint.hpp
namespace wiznet_space {
   class Endpoint {
       friend class UDPSocket;
       ....................
   }
}

// Socket.hpp
namespace wiznet_space {

  class Socket {
  public:
       Socket();
  ..........................
  }
}
..........................
..........................

Using namespace in source file

// main.c
..........................

ESP8266Interface wifi(D1, D0, D2, "WizFiDemoAP","12345678",115200); // tx, rx for
wiznet_space::EthernetInterface eth;

bool InitializeWiznetEthernet()
{
    uint8_t mac_addr[6] = {0x00, 0x08, 0xDC, 0xFF, 0x11, 0x22};
 
    eth.init(mac_addr, "192.168.3.102", "255.255.255.0", "192.168.3.1"); //Use DHCP

    .......................................................................................................................    
}

bool InitializeESP8266()
{   
    wifi.init();

    .......................................................................................................................    
}

int main()
{
    ....................................................................

    // Ethernet : WIZnet hardwired TCP/IP in W7500
    if ( InitializeWiznetEthernet() )
    {
        // Send TCP/IP data via Ethernet
        ProcessDataViaEthernet();
    }    
    
    // WiFi : ESP8266
    if ( InitializeESP8266() )
    {
        // Send TCP/IP data via WiFi
        ProcessDataViaWiFi();
    }

    ....................................................................
}

// ProcessDataViaEthernet.cpp
void ProcessDataViaEthernet()
{
    wiznet_space::TCPSocketConnection eth_sock;
    
    eth_sock.connect("192.168.3.64", 6000);
    char send_data[] = "This is from Ethernet Interface\r\n";
    eth_sock.send_all(send_data, sizeof(send_data)-1);
    eth_sock.close();
}

// ProcessDataViaWiFi.cpp
void ProcessDataViaWiFi()
{
    ::TCPSocketConnection wifi_sock;
    
    wifi_sock.connect("192.168.3.64", 6000);    
    char send_data[] = "This is from WiFi Interface\r\n";
    wifi_sock.send_all(send_data, sizeof(send_data)-1);
    wifi_sock.close();
}

And, here are screenshots of this test. /media/uploads/SteveKim/esd01-2.jpg /media/uploads/SteveKim/esd01-3.jpg

Conclusion

I know that this way is a kind of work-around way. Best way is to design a new network-abstract-class and hierarchical network-interface-classes based on the network-abstract-class.

  • Ethernet : lwIP, WIZnet hardwired TCP/IP
  • WiFi : ESP8266, WiFly, WizFi250, CC3000, ....
  • Other interfaces(3G/4G, BT, .....)

I believe that mbed-team will release a new network classes based on a hierarchical architecture .

Until then, you can refer to the this code for dual network interface, temporarily.

Revision:
1:a79f264f321f
Parent:
0:0543bf604693
--- a/main.cpp	Mon Jun 29 09:42:11 2015 +0000
+++ b/main.cpp	Tue Jul 14 10:18:05 2015 +0000
@@ -1,170 +1,108 @@
 #include "mbed.h"
-#include "EthernetInterface.h"
-//#include "ESP8266Interface.h"
-
-#define MAC     "\x00\x08\xDC\xAA\xAA\xAA"
-#define IP      "192.168.3.110"
-#define MASK    "255.255.255.0"
-#define GATEWAY "192.168.3.1"
-
-int main() {
-    EthernetInterface eth;
 
-    ////////////////////////////////////////////////////////////////////////////////////    
-    // sekim XXXX
-    //eth.init(); //Use DHCP
-    //uint8_t mac_addr[6] = {0x00, 0x08, 0xDC, 0xFF, 0x11, 0x22};
-    //eth.init(mac_addr);
-    eth.init((uint8_t*)MAC,IP,MASK,GATEWAY);  //IP,mask,Gateway
-    eth.link();
-    ////////////////////////////////////////////////////////////////////////////////////
-    
-    eth.connect();
-    printf("\r\nIP address is %s\r\n", eth.getIPAddress());
-    
-    TCPSocketConnection sock;
-    sock.connect("google.com", 80);
-    
-    printf("XXX 200 : Connected\r\n");
-    
-    char http_cmd[] = "GET /hello.txt HTTP/1.0\n\n";
-    sock.send_all(http_cmd, sizeof(http_cmd)-1);
-    
-    char buffer[300];
-    int ret;
-    while (true) {
-        ret = sock.receive(buffer, sizeof(buffer)-1);
-        printf("XXX 210 : Recv(%d) \r\n", ret);
-        if (ret <= 0)
-            break;
-        buffer[ret] = '\0';
-        printf("Received %d chars from server:\n%s\r\n", ret, buffer);
-    }
-    
-    printf("XXX 220 : Closed\r\n");
-      
-    sock.close();
-    
-    eth.disconnect();
-    
-    while(1) {}
-}
+#include "ESP8266Interface.h"
+#include "EthernetInterface.hpp"
 
-/*
-
-
-
-
-
-
-
-
-
-
-
-
-#include "mbed.h"
-#include "EthernetInterface.h"
- 
-AnalogIn pot1(A0);
-AnalogIn pot2(A1);
- 
 DigitalOut led1(LED1);
 DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
- 
-EthernetInterface eth;
-TCPSocketConnection sock;
- 
-int main() 
+
+ESP8266Interface wifi(D1, D0, D2, "WizFiDemoAP","12345678",115200); // tx, rx for
+wiznet_space::EthernetInterface eth;
+
+RawSerial pc(USBTX, USBRX); // tx, rx
+
+extern void ProcessDataViaEthernet();
+extern void ProcessDataViaWiFi();
+
+// For monitoring data from ESP8266
+Timeout timer_buffer_debug;
+CircBuffer<char> buffer_ESP8266_recv(1024);
+
+void print_buffer_ESP8266()
 {
-    //uint8_t mac_addr[6] = {0x00, 0x08, 0xDC, 0x00, 0x01, 0x02}; 
+    char c=0;
+    while ( buffer_ESP8266_recv.available() ) {
+        buffer_ESP8266_recv.dequeue(&c);
+        pc.putc(c);
+    }
+    timer_buffer_debug.attach(&print_buffer_ESP8266, 0.1);
+}
+
+
+bool InitializeWiznetEthernet()
+{
     uint8_t mac_addr[6] = {0x00, 0x08, 0xDC, 0xFF, 0x11, 0x22};
-    char *MODEL = "mbed";
-    char *SERIAL_NUM = "input_your_serial_num"; 
-    float DEADBAND = 0.015;   
-    char* ip;
+ 
+    //eth.init(mac_addr); //Use DHCP
+    eth.init(mac_addr, "192.168.3.102", "255.255.255.0", "192.168.3.1"); //Use DHCP
     
-    int http_cmd_sz=800;
-    char http_cmd[http_cmd_sz];
-    int buffer_sz=300;  
-    char buffer[buffer_sz];  
-    int returnCode = 0;
- 
-     for (int i=0; i<5; i++) {
-        led1 = 1;
-        wait(0.2);
-        led1 = 0;
-        wait(0.2);
+    // Check Ethenret Link
+    if( eth.link()!=true )
+    {
+        printf("- Ethernet PHY Link- Fail\r\n");
+        return false;
+    }
+     
+    // Start Ethernet connecting: Trying to get an IP address using DHCP
+    if ( eth.connect() < 0 ){
+        printf("Fail - Ethernet Connecing");
+        return false;
     }
 
-    led1 = 1;
-    led2 = 1;
-    led3 = 1;
-    led4 = 1;
- 
-    printf("initializing Ethernet\r\n");
-    eth.init(mac_addr); //Use DHCP    
-    if ( returnCode == 0 )
-    {
-        printf(" - Ethernet ready\r\n");
-        led1 = returnCode;
-    }
-    else
-    {
-        printf(" - Could not initialize Ethernet - ending\r\n");
-        return 0;
+    //pc.printf("IP Address(Ethernet Interface) is %s\r\n", eth.getIPAddress());
+
+    return true;
+}
+
+bool InitializeESP8266()
+{   
+    // if you don't want to monitor ESP-module-data, remove below line.
+    //timer_buffer_debug.attach(&print_buffer_ESP8266, 0.5);    
+  
+    wifi.init();
+
+    bool result = wifi.connect();
+    if ( !result )  {
+        pc.printf("wifi.connect error\r\n");
+        return false;
     }
- 
-    eth.ethernet_link();
-    printf("eth.ethernet_link() %d \r\n", eth.ethernet_link());
+
+    //pc.printf("IP Address(WiFi Interface) is %s\r\n", wifi.getIPAddress());
+    return true;
+}
+
+
+int main()
+{
+    // Initialize LED
+    for (int i=0; i<20; i++)
+    {        
+        led1 = !led1;
+        led2 = !led2;
+        wait(0.05);
+    }
+
+    // Initialize UART
+    pc.baud(115200);
+    pc.printf("\r\nDual Network Interface Test.\r\n");
+
+    // Ethernet : WIZnet hardwired TCP/IP in W7500
+    if ( InitializeWiznetEthernet() )
+    {
+        ProcessDataViaEthernet();
+        pc.printf("WIZnet hardwired TCP/IP in W7500 Test Done.\r\n");
+    }    
     
-    printf("Ethernet.connecting \r\n");
-    returnCode = eth.connect();
- 
-    printf(" - connecting returned %d \r\n", returnCode);
-    led2 = returnCode != -1 ? 0: 1;
-    printf("Trying to get IP address..\r\n");
-    ip = eth.getIPAddress();
-    led3 = strlen(ip)<4 ? 1: 0;
-    printf("  -  IP address:%s\r\n", ip);
+    // WiFi : ESP8266
+    if ( InitializeESP8266() )
+    {
+        ProcessDataViaWiFi();
+        pc.printf("ESP8266 Test Done.\r\n");
+    }
     
-    float oil_level = 0.0;
-    float oil_level2= 0.0;
-    float oldPotVal = -2.0;
-    float oldPotVal2 = -2.0;
     
     while(1) {
-        oil_level = pot1.read();
-        oil_level2= pot2.read();
-        
-        if ( abs(oil_level - oldPotVal) < DEADBAND && abs(oil_level2 - oldPotVal2) < DEADBAND)
-        {
-            continue;   
-        }
-        else
-        {
-            led4 = 1;
-            oldPotVal = oil_level;
-            oldPotVal2 = oil_level2;
-            printf("Sending Value for well1 %.2f\n\r", oil_level);
-            printf("Sending Value for well2 %.2f\n\r", oil_level2);
-            sock.connect("toolbox-connect.axeda.com", 80);
- 
-            snprintf(http_cmd, http_cmd_sz,  "POST /ammp/data/1/%s!%s HTTP/1.1\r\nContent-Type: application/json\r\nContent-Length: 65\r\n\r\n{\"data\":[{\"di\":{\"oil_level\":%.2f, \"oil_level2\":%.2f}}]}\r\n\r\n", MODEL, SERIAL_NUM, oil_level, oil_level2);
-            sock.send_all(http_cmd, http_cmd_sz-1);
-    
-            while ( (returnCode = sock.receive(buffer, buffer_sz-1)) > 0)
-            {
-                buffer[returnCode] = '\0';
-                printf("Received %d chars from server:\n\r%s\n", returnCode, buffer);
-            }
-            led4 = returnCode;
-            sock.close();
-        }
- 
+        wait(1);
     }
- 
 }
- */
\ No newline at end of file
+