Mbed library for ENC28J60 Ethernet modules. Full support for TCP/IP and UDP Server, Client and HTTP server (webserver). DHCP and DNS is included.

Dependents:   mBuino_ENC28_MQTT Nucleo_Web_ENC28J60 Nucleo_Web_ENC28J60_ADC Serial_over_Ethernet ... more

Library for ENC28J60 Ethernet modules.

/media/uploads/hudakz/enc28j60_module01.jpg

Ported to mbed from Norbert Truchsess's UIPEthernet library for Arduino. Thank you Norbert!

  • Full support for persistent (streaming) TCP/IP and UDP connections Client and Server each, ARP, ICMP, DHCP and DNS.
  • Works with both Mbed OS 2 and Mbed OS 5.

Usage:

  • Import the library into your project.
  • Add #include "UipEthernet.h" to main.cpp
  • Create one instance of the UipEthernet class initialized with the MAC address you'd like to use and SPI pins of the connected Mbed board.

Example programs:

Import programWebSwitch_ENC28J60

HTTP Server serving a simple webpage which enables to remotely turn a digital output on/off. Compile, download, run and type 'IP_address/secret/' (don't forget the last '/') into your web browser and hit ENTER.

Import programHTTPServer_Echo_ENC28J60

A simple HTTP server echoing received requests. Ethernet connection is over an ENC28J60 board. Usage: Type the server's IP address into you web browser and hit <ENTER>.

Import programTcpServer_ENC28J60

Simple TCP/IP Server using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programTcpClient_ENC28J60

Simple TCP/IP Client using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programUdpServer_ENC28J60

Simple UDP Server using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programUdpClient_ENC28J60

Simple UDP Client using the UIPEthernet library for ENC28J60 Ethernet boards.

Import programMQTT_Hello_ENC28J60

MQTT Client example program. Ethernet connection is via an ENC28J60 module.

Revision:
15:53715cc81c63
Parent:
9:a156d3de5647
Child:
17:1123c3fe86ca
--- a/DhcpClient.cpp	Tue Sep 03 09:16:55 2019 +0000
+++ b/DhcpClient.cpp	Sat Sep 07 17:42:42 2019 +0000
@@ -2,6 +2,7 @@
 // Author: Jordan Terrell - blog.jordanterrell.com
 #include <string.h>
 #include <stdlib.h>
+#include "UipEthernet.h"
 #include "DhcpClient.h"
 #include "utility/util.h"
 
@@ -44,54 +45,78 @@
 //return:0 on error, 1 if request is sent and response is received
 int DhcpClient::requestDhcpLease()
 {
+#ifdef UIPETHERNET_DEBUG_UDP
+    printf("requestDhcpLease(): begin\r\n");
+#endif
     uint8_t messageType = 0;
+    Timer           timer;
+
+    timer.reset();
+    timer.start();
 
     // Pick an initial transaction ID
-    srand(time(NULL));
+    srand(time(NULL)+ 1);
     _dhcpTransactionId = (rand() % 2000UL) + 1;
     _dhcpInitialTransactionId = _dhcpTransactionId;
 
     _dhcpUdpSocket.stop();
     if (_dhcpUdpSocket.begin(DHCP_CLIENT_PORT) == 0) {
         // Couldn't get a socket
+#ifdef UIPETHERNET_DEBUG_UDP
+        printf("requestDhcpLease(): Couldn't get a socket\r\n");
+#endif
         return 0;
     }
 
     presendDhcp();
 
     volatile int    result = 0;
-    time_t          startTime = time(NULL);
 
     while (_dhcp_state != STATE_DHCP_LEASED) {
         if (_dhcp_state == STATE_DHCP_START) {
+#ifdef UIPETHERNET_DEBUG_UDP
+            printf("_dhcp_state: STATE_DHCP_START\r\n");
+#endif
             _dhcpTransactionId++;
 
-            sendDhcpMessage(DHCP_DISCOVER, (time(NULL) - startTime));
+            sendDhcpMessage(DHCP_DISCOVER, (timer.read_ms() / 1000 + 1));
             _dhcp_state = STATE_DHCP_DISCOVER;
         }
         else
         if (_dhcp_state == STATE_DHCP_REREQUEST) {
+#ifdef UIPETHERNET_DEBUG_UDP
+            printf("_dhcp_state: STATE_DHCP_REREQUEST\r\n");
+#endif
             _dhcpTransactionId++;
-            sendDhcpMessage(DHCP_REQUEST, (time(NULL) - startTime));
+            sendDhcpMessage(DHCP_REQUEST, (timer.read_ms() / 1000 + 1));
             _dhcp_state = STATE_DHCP_REQUEST;
         }
         else
         if (_dhcp_state == STATE_DHCP_DISCOVER) {
+#ifdef UIPETHERNET_DEBUG_UDP
+            printf("_dhcp_state: STATE_DHCP_DISCOVER\r\n");
+#endif
             uint32_t    respId;
             messageType = parseDhcpResponse(_responseTimeout, respId);
             if (messageType == DHCP_OFFER) {
                 // We'll use the transaction ID that the offer came with,
                 // rather than the one we were up to
                 _dhcpTransactionId = respId;
-                sendDhcpMessage(DHCP_REQUEST, (time(NULL) - startTime));
+                sendDhcpMessage(DHCP_REQUEST, (timer.read_ms() / 1000 + 1));
                 _dhcp_state = STATE_DHCP_REQUEST;
             }
         }
         else
         if (_dhcp_state == STATE_DHCP_REQUEST) {
+#ifdef UIPETHERNET_DEBUG_UDP
+            printf("_dhcp_state: STATE_DHCP_REQUEST\r\n");
+#endif
             uint32_t    respId;
             messageType = parseDhcpResponse(_responseTimeout, respId);
             if (messageType == DHCP_ACK) {
+#ifdef UIPETHERNET_DEBUG_UDP
+                printf("messageType: DHCP_ACK\r\n");
+#endif
                 _dhcp_state = STATE_DHCP_LEASED;
                 result = 1;
 
@@ -115,23 +140,37 @@
                 _rebindInSec = _dhcpT2;
             }
             else
-            if (messageType == DHCP_NAK)
+            if (messageType == DHCP_NAK) {
+ #ifdef UIPETHERNET_DEBUG_UDP
+                printf("messageType: DHCP_NAK\r\n");
+#endif
                 _dhcp_state = STATE_DHCP_START;
+            }
         }
 
         if (messageType == 255) {
+#ifdef UIPETHERNET_DEBUG_UDP
+            printf("DHCP_NAK: 255\r\n");
+#endif
             messageType = 0;
             _dhcp_state = STATE_DHCP_START;
         }
 
-        if ((result != 1) && ((time(NULL) - startTime) > _timeout))
+        if ((result != 1) && ((timer.read_ms() / 1000) > _timeout)) {
+#ifdef UIPETHERNET_DEBUG_UDP
+            printf("requestDhcpLease(): timeout\r\n");
+#endif
             break;
+        }
     }
 
     // We're done with the socket now
     _dhcpUdpSocket.stop();
     _dhcpTransactionId++;
 
+#ifdef UIPETHERNET_DEBUG_UDP
+    printf("requestDhcpLease(): %d\r\n", result);
+#endif
     return result;
 }
 
@@ -182,17 +221,17 @@
     // yiaddr: already zeroed
     // siaddr: already zeroed
     // giaddr: already zeroed
-    //put data in W5100 transmit buffer
+    //put data in ENC28J60 transmit buffer
     _dhcpUdpSocket.write(buffer, 28);
 
     memset(buffer, 0, 32);                      // clear local buffer
     memcpy(buffer, _dhcpMacAddr, 6);            // chaddr
-    //put data in W5100 transmit buffer
+    //put data in ENC28J60 transmit buffer
     _dhcpUdpSocket.write(buffer, 16);
 
     memset(buffer, 0, 32);                      // clear local buffer
     // leave zeroed out for sname && file
-    // put in W5100 transmit buffer x 6 (192 bytes)
+    // put in ENC28J60 transmit buffer x 6 (192 bytes)
     for (int i = 0; i < 6; i++) {
         _dhcpUdpSocket.write(buffer, 32);
     }
@@ -222,7 +261,7 @@
     printByte((char*) &(buffer[26]), _dhcpMacAddr[4]);
     printByte((char*) &(buffer[28]), _dhcpMacAddr[5]);
 
-    //put data in W5100 transmit buffer
+    //put data in ENC28J60 transmit buffer
     _dhcpUdpSocket.write(buffer, 30);
 
     if (messageType == DHCP_REQUEST) {
@@ -242,7 +281,7 @@
         buffer[10] = _dhcpDhcpServerIp[2];
         buffer[11] = _dhcpDhcpServerIp[3];
 
-        //put data in W5100 transmit buffer
+        //put data in ENC28J60 transmit buffer
         _dhcpUdpSocket.write(buffer, 12);
     }
 
@@ -256,7 +295,7 @@
     buffer[7] = dhcpT2value;
     buffer[8] = endOption;
 
-    //put data in W5100 transmit buffer
+    //put data in ENC28J60 transmit buffer
     _dhcpUdpSocket.write(buffer, 9);
 
     _dhcpUdpSocket.endPacket();
@@ -272,11 +311,12 @@
 {
     volatile uint8_t    type = 0;
     uint8_t             opt_len = 0;
+    Timer               timer;
 
-    unsigned long       startTime = time(NULL);
+    timer.start();
 
     while (_dhcpUdpSocket.parsePacket() <= 0) {
-        if ((time(NULL) - startTime) > responseTimeout) {
+        if (timer.read() > responseTimeout) {
             return 255;
         }