..
Dependencies: ESP8266Interface WIZnetInterface_namespace mbed-src
Dual Network Interface
Some our customers want dual network interface like below.
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.
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.
Diff: main.cpp
- Revision:
- 1:a79f264f321f
- Parent:
- 0:0543bf604693
diff -r 0543bf604693 -r a79f264f321f main.cpp --- 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 +