使用Aruino Ethernet使ESP32具有以太网通讯能力

Arduino的Ethernet库

Arduino很早就支持Ethernet通讯。硬件主要是支持W5100,W5200和W5500以太网通讯模块通过SPI接口与ESP32通讯。在Arduino 1.8.19版本以前,Arduino不支持库的引用位置。比如,在例子中说调用Ethernet.h,但如果想看程序中的头文件,不知道这个库放在那个目录中,查找起来非常麻烦,用VSCODE可以看到调用的库在那个目录,可以直接打开库的位置,但让VSCODE运行Arduino也运行也并不是一件容易的事情。好在现在的Arduino 1.8.20可以解决这个问题了。我的库按照在Arduino-1.8.19\library\src\ehternet. 有许多的例子说明库是使用。下面介绍一下这些库的应用情况。

Ethernet库

一般的应用都会调用Ethernet.h文件。调用这个文件就会调用其他的两个关键的库,Client.h 和Server.h库。如下:

#include <Arduino.h>
#include "Client.h"
#include "Server.h"
#include "Udp.h"

在ESP32中如果不对Server.h文件修改的话就会报错。许多网友使用这个库时会报错,我的博客中对此有解决方法。按此修改了Server.h后,应该是无法正常使用无线网了,具体的解决方法好没有找到。

下面介绍库里面的函数:

库函数介绍

enum EthernetLinkStatus {
	Unknown,
	LinkON,
	LinkOFF
};

枚举EthernerLinkStatus,以太网模块的连接状态。

enum EthernetHardwareStatus {
	EthernetNoHardware,
	EthernetW5100,
	EthernetW5200,
	EthernetW5500
};

以太网硬件,有三种模块,分别为W5100,W5200和W5500. 现在大部分使用的是W5500,通过速度100/10 MHz自动切换,最多可以建立8个连接。

主要的类定义:

class EthernetClass {
private:
	static IPAddress _dnsServerAddress;
	static DhcpClass* _dhcp;
public:
	// Initialise the Ethernet shield to use the provided MAC address and
	// gain the rest of the configuration through DHCP.
	// Returns 0 if the DHCP configuration failed, and 1 if it succeeded
	static int begin(uint8_t *mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);
	static int maintain();
	static EthernetLinkStatus linkStatus();
	static EthernetHardwareStatus hardwareStatus();

	// Manaul configuration
	static void begin(uint8_t *mac, IPAddress ip);
	static void begin(uint8_t *mac, IPAddress ip, IPAddress dns);
	static void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway);
	static void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
	static void init(uint8_t sspin = 10);

	static void MACAddress(uint8_t *mac_address);
	static IPAddress localIP();
	static IPAddress subnetMask();
	static IPAddress gatewayIP();
	static IPAddress dnsServerIP() { return _dnsServerAddress; }

	void setMACAddress(const uint8_t *mac_address);
	void setLocalIP(const IPAddress local_ip);
	void setSubnetMask(const IPAddress subnet);
	void setGatewayIP(const IPAddress gateway);
	void setDnsServerIP(const IPAddress dns_server) { _dnsServerAddress = dns_server; }
	void setRetransmissionTimeout(uint16_t milliseconds);
	void setRetransmissionCount(uint8_t num);

	friend class EthernetClient;
	friend class EthernetServer;
	friend class EthernetUDP;
private:
	// Opens a socket(TCP or UDP or IP_RAW mode)
	static uint8_t socketBegin(uint8_t protocol, uint16_t port);
	static uint8_t socketBeginMulticast(uint8_t protocol, IPAddress ip,uint16_t port);
	static uint8_t socketStatus(uint8_t s);
	// Close socket
	static void socketClose(uint8_t s);
	// Establish TCP connection (Active connection)
	static void socketConnect(uint8_t s, uint8_t * addr, uint16_t port);
	// disconnect the connection
	static void socketDisconnect(uint8_t s);
	// Establish TCP connection (Passive connection)
	static uint8_t socketListen(uint8_t s);
	// Send data (TCP)
	static uint16_t socketSend(uint8_t s, const uint8_t * buf, uint16_t len);
	static uint16_t socketSendAvailable(uint8_t s);
	// Receive data (TCP)
	static int socketRecv(uint8_t s, uint8_t * buf, int16_t len);
	static uint16_t socketRecvAvailable(uint8_t s);
	static uint8_t socketPeek(uint8_t s);
	// sets up a UDP datagram, the data for which will be provided by one
	// or more calls to bufferData and then finally sent with sendUDP.
	// return true if the datagram was successfully set up, or false if there was an error
	static bool socketStartUDP(uint8_t s, uint8_t* addr, uint16_t port);
	// copy up to len bytes of data from buf into a UDP datagram to be
	// sent later by sendUDP.  Allows datagrams to be built up from a series of bufferData calls.
	// return Number of bytes successfully buffered
	static uint16_t socketBufferData(uint8_t s, uint16_t offset, const uint8_t* buf, uint16_t len);
	// Send a UDP datagram built up from a sequence of startUDP followed by one or more
	// calls to bufferData.
	// return true if the datagram was successfully sent, or false if there was an error
	static bool socketSendUDP(uint8_t s);
	// Initialize the "random" source port number
	static void socketPortRand(uint16_t n);
};
extern EthernetClass Ethernet;

其中有用的函数:

linkStatus(); 	// 显示当前的连接状态,返回是前面枚举:
  • Unknown,0
  • LinkON,1
  • LinkOFF,2
    程序例子:
  auto link = Ethernet.linkStatus();
  Serial.print("Link status: ");
  switch (link) {
    case Unknown:
      Serial.println("Unknown");
      break;
    case LinkON:
      Serial.println("ON");
      break;
    case LinkOFF:
      Serial.println("OFF");
      break;
  }

通过这个程序可以判断网线是否连接了模块。

	hardwareStatus();		// 返回安装硬件的模块

这个在实际使用中意义不大,对于实验,判断模块是否正常有用,返回的也是前面定义的枚举:

  • EthernetNoHardware, 0
  • EthernetW5100, 1
  • EthernetW5200, 2
  • EthernetW5500 3

例子:

	auto hardStatus = Ethernet.hardwareStatus();
	switch (hardStatus)
    {
        case EthernetNoHardware:
          Serial.println("Ethernet No Hardware");
          break;
        case EthernetW5100:
          Serial.println("Ethernet W5100");
          break;
        case EthernetW5200:
          Serial.println("Ethernet W5200");
          break;
        case EthernetW5500:
          Serial.println("Ethernet W5500");
          break;
    }
	Ethernet.maintain(); // 更新DHCP的地址

描述:
允许续订 DHCP 租约。当通过 DHCP 分配 IP 地址时,以太网设备将在该地址上租约一段时间。使用 Ethernet.maintain(),可以从 DHCP 服务器请求续订。根据服务器的配置,您可能会收到相同的地址、新地址或根本没有。

您可以根据需要随时调用此函数,它只会在需要时重新请求 DHCP 租约(在所有其他情况下返回 0)。最简单的方法是在每次 loop() 调用时调用它,但少一点也没关系。不调用此函数(或每秒调用它明显少于一次)将阻止在 DHCP 协议需要时续订租约,而是继续使用过期的租约(这不会直接中断连接,但如果 DHCP 服务器将同一地址租给其他人,事情可能会中断)。

还有一个比较需要强调一下的函数,这个函数是在Client类中的函数:

	virtual uint8_t connected();   // client已经连接了server.

例子:

if (!client.connected() && alreadyConnected)
        {
            Serial.println("TCP connection closed!");
            alreadyConnected = false;
        }

用上面的程序可以检测到TCP断开了连接。

总结

用ESP32做服务器,外部的设备做客户端,可与通过TCP建立modbusTCP进行通讯。也可以接收多个TCP连接,但服务器程序需要可以接收多个客户端。可以参考例子程序中的AdvicedChatSever。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
ESP32是一款高性能、低功耗的系统级芯片。它集成了WiFi、蓝牙和以太网等多种通信方式,支持多种协议,包括TCP、UDP、HTTP等。其中以太网通信可以通过SPI接口实现。ESP32具有非常广泛的应用领域,比如智能家居、物联网、无人机等等。它在以太网通信方面有着很高的性能和稳定性,可靠性也很高。 使用ESP32进行以太网通信,需要一个支持以太网通信的模块,同时需要一定的硬件和软件开发能力。用户需要根据实际需求选择合适的开发板和以太网模块,然后进行对应的软件开发,涉及到以太网通信协议、网络配置、物理层接口等方面的技术。ESP32在开发方面提供了非常丰富的API和示例代码,用户可以通过参考这些代码来进行开发。 在开发过程中,用户需要注意以太网通信的稳定性和性能。为了提高稳定性,可以采用专业的以太网模块、合理的网络拓扑结构和强大的错误处理机制。为了提高性能,可以采用高速的以太网通信协议和优化的网络堆栈。同时,实际应用中需要考虑到数据安全和隐私保护等问题,要采用加密和身份认证等技术手段来保障数据的安全性。 总体来说,ESP32以太网通信是一项技术含量较高的工作,需要多方面的技术知识和实践经验。但是,它有着广阔的应用前景和实际的商业价值,可以为各种智能设备和物联网应用提供高效、可靠的通信支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值