八、W5100S/W5500+RP2040之MicroPython开发<HTTP Server示例>

发布时间:2023年12月21日

1 前言

??随着云计算的推广和普及,越来越多的网络设备和服务需要连接到网络,这意味着需要更多的IP地址和其他网络配置信息。DHCP服务器可以动态地分配IP地址和其他配置信息,简化了网络配置管理,提高了网络设备的可用性和效率。

??W5100S/W5500是一款集成全硬件 TCP/IP 协议栈的嵌入式以太网控制器,同时也是一颗工业级以太网控制芯片。本教程将介绍W5100S/W5500以太网HTTP Server应用的基本原理、使用步骤、应用实例以及注意事项,帮助读者更好地掌握这一技术。

2. 相关网络信息

2.1 简介

在这里插入图片描述

??HTTP,全称为超文本传输协议(Hypertext Transfer Protocol),是一种应用最为广泛的网络传输协议,是用于从万维网服务器传输超文本到本地浏览器的传送协议,所有的WWW文件都必须遵守这个标准。它是一个基于TCP/IP通信协议来传递数据(HTML文件,图片文件,查询结果等)。

2.2 HTTP Server工作步骤

在这里插入图片描述

HTTP Server的原理步骤可以归纳为以下几点:

  1. 建立连接:Web浏览器与Web服务器建立连接,打开一个称为socket(套接字)的虚拟文件,此文件的建立标志着连接建立成功。
  2. 请求:Web浏览器通过socket向Web服务器提交请求。HTTP的请求一般是GET或POST命令(POST用于FORM参数的传递)。
  3. 服务器处理请求:一旦收到请求,服务器会根据请求类型和URL找到相应的资源,并读取文件内容。如果是POST请求,服务器还会解析表单数据。
  4. 响应:服务器将处理后的数据通过HTTP协议返回给客户端,包括HTTP头信息和HTML文件内容。
  5. 关闭连接:客户端和服务器之间的连接在完成数据交换后会被关闭。

2.3 HTTP Server的优点

??HTTP Server的优点包括:

  1. 简单灵活:HTTP协议简单,易于理解和实现,因此开发人员可以更快地构建和部署应用程序。
  2. 易于扩展:HTTP协议支持多种扩展,可以轻松地添加新功能和特性,以满足不断变化的需求。
  3. 无状态:HTTP协议无状态,这意味着服务器不会为每个请求保持状态。虽然这可能会导致一些问题,但无状态也使得HTTP协议更加灵活和可扩展。
  4. 支持跨平台:HTTP协议是一种通用的网络协议,可以在各种操作系统和设备上实现和使用。
  5. 支持多种编程语言:HTTP协议不限制使用的编程语言,因此可以使用各种编程语言来开发和部署应用程序。
  6. 良好的可维护性:HTTP协议规范明确,易于理解和维护,同时存在许多成熟的工具和库,使得开发人员可以更快地构建和部署应用程序。
  7. 支持多媒体内容:HTTP协议可以传输多种类型的数据,包括文本、图片、音频和视频等多媒体内容,使得开发人员可以轻松地构建多媒体应用程序。
  8. 支持缓存和压缩:HTTP协议支持缓存和压缩技术,可以减少网络传输的数据量,提高应用程序的性能和响应速度。

2.4 HTTP Server应用场景

??HTTP Server的应用场景非常广泛,以下是一些主要的场景:

  1. 文件共享:HTTP Server最广泛的用途就是允许在互联网上共享文件。通过使用HTTP Server,用户可以从服务器下载或上传文件。
  2. Web应用:大多数的网站和应用都离不开HTTP Server。HTTP Server能够处理客户端的请求,并且把处理的结果返回到客户端。
  3. 云服务:许多云服务都依赖于HTTP Server,比如Amazon的S3、Google Cloud Storage等。这些服务都提供了一个RESTful的API,使用HTTP进行交互。
  4. 大数据:Hadoop、Spark等大数据工具都支持通过HTTP Server来访问和处理数据。
  5. 物联网:在物联网领域,HTTP Server也发挥了很大的作用。比如,许多智能家居设备都使用HTTP Server来与手机应用或者网页进行交互。
  6. 流媒体:HTTP Server也被广泛用于流媒体服务,比如一些在线视频网站和音乐网站。
  7. 游戏开发:一些基于Web的游戏也使用了HTTP Server来进行客户端和服务器之间的通信。
  8. 远程管理:许多设备的远程管理界面就是一个简单的Web页面,通过HTTP Server接受用户的输入并返回结果。

3 WIZnet以太网芯片

WIZnet 主流硬件协议栈以太网芯片参数对比

ModelEmbedded CoreHost I/FTX/RX BufferHW SocketNetwork Performance
W5100STCP/IPv4, MAC & PHY8bit BUS, SPI16KB4Max.25Mbps
W6100TCP/IPv4/IPv6, MAC & PHY8bit BUS, Fast SPI32KB8Max.25Mbps
W5500TCP/IPv4, MAC & PHYFast SPI32KB8Max.15Mbps
  1. W5100S/W6100 支持 8bit数据总线接口,网络传输速度会优于W5500。
  2. W6100 支持IPv6,与W5100S 硬件兼容,若已使用W5100S的用户需要支持IPv6,可以Pin to Pin兼容。
  3. W5500 拥有比 W5100S更多的 Socket数量以及发送与接收缓存。

相较于软件协议栈,WIZnet的硬件协议栈以太网芯片有以下优点

  1. 硬件TCP/IP协议栈:WIZnet的硬件协议栈芯片提供了一种硬件实现的TCP/IP协议栈,这种硬件实现的协议栈比软件实现的协议栈具有更好的性能和稳定性。
  2. 不需要额外的嵌入式系统软件栈和内存资源:由于所有的以太网传输和接收操作都由独立的以太网控制器处理,因此不需要额外的嵌入式系统软件栈和内存资源。
  3. 抵抗网络环境变化和DDoS攻击:与易受网络环境变化和DDoS攻击影响的软件TCP/IP协议栈相比,硬件协议栈芯片能够提供更稳定的以太网性能。
  4. 适用于低规格的嵌入式系统:即使在低规格的嵌入式系统中,使用WIZnet的硬件协议栈芯片也可以比使用软件TCP/IP协议栈的高规格系统显示出更高效的互联网应用操作性能。

在这里插入图片描述

4 HTTP网络设置示例概述以及使用

4.1 流程图

??程序的运行框图如下所示:

在这里插入图片描述

4.2 准备工作核心

软件

  • Thonny

硬件

  • W5100SIO模块 + RP2040 树莓派Pico开发板 或者 Wiznet W5100S-EVB-Pico开发板
  • Micro USB 接口的数据线
  • 网线

4.3 连接方式

  • 通过数据线连接PC的USB口(主要用于烧录程序,也可以虚拟出串口使用)
  • 使用模块连接RP2040 进行接线时
    • RP2040 GPIO16 <----> W5100S MISO
    • RP2040 GPIO17 <----> W5100S CS
    • RP2040 GPIO18 <----> W5100S SCK
    • RP2040 GPIO19 <----> W5100S MOSI
    • RP2040 GPIO20 <----> W5100S RST
  • 通过PC和设备都通过网线连接路由器LAN口

4.4 主要代码概述

??我们直接打开http_server.py文件。
第一步:可以看到在w5x00_init()函数中,进行了SPI的初始化。以及将SPI相关引脚和复位引脚注册到库中,后续则是激活网络,并使用DHCP配置网络地址信息,当DHCP失败时,则配置静态网络地址信息。当未配置成功时,会打印出网络地址相关寄存器的信息,可以帮助我们更好的排查问题。

第二步:设置socket号,绑定服务器ip和端口号。

第三步:监听,等待客户端连接。

第四步:设置网页界面,对客户端的请求做出解析,以此来控制灯的开关。同时窗口打印出灯的状态和客户端的IP信息

''' HTTP Server example.
    date: 2023-11-27
'''
from usocket import socket
from machine import Pin,SPI
import time, network


''' LED init
'''
led = Pin(25, Pin.OUT)

''' static netinfo
'''
ip = '192.168.1.11'
sn = '255.255.255.0'
gw = '192.168.1.1'
dns= '8.8.8.8'

netinfo=(ip, sn, gw, dns)

localip = ''
localport = 8000
listen_info = (localip, localport)

    
def w5x00_init():
    global localip
    ''' spi0 init
        baudrate: 2000000
        mosi pin: gpio19
        miso pin: gpio16
        sck  pin: gpio18
        cs   pin: gpio17
        rst  pin: gpio20
    '''
    spi=SPI(0,2_000_000, mosi=Pin(19),miso=Pin(16),sck=Pin(18))
    nic = network.WIZNET5K(spi,Pin(17),Pin(20))
    nic.active(True)
    # use dhcp, if fail use static netinfo
    try:
        nic.ifconfig('dhcp')
    except:
        nic.ifconfig(netinfo)
    localip = nic.ifconfig()[0]
    print('ip :', nic.ifconfig()[0])
    print('sn :', nic.ifconfig()[1])
    print('gw :', nic.ifconfig()[2])
    print('dns:', nic.ifconfig()[3])
    
    while not nic.isconnected():
        time.sleep(1)
#         print(nic.regs())
        print('no link')
        uart.write('no link\r\n')

''' web page info
'''
def web_page():
    if  led.value()==1:
        led_state="ON"
    else:
        led_state="OFF"
        
    html = """
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Raspberry Pi Pico Web server - WIZnet W5100S</title>
    </head>
    <body>
    <div align="center">
    <H1>Raspberry Pi Pico Web server & WIZnet Ethernet HAT</H1>
    <h2>Control LED</h2>
    PICO LED state: <strong>""" + led_state + """</strong>
    <p><a href="/?led=on"><button class="button">ON</button></a><br>
    </p>
    <p><a href="/?led=off"><button class="button button2">OFF</button></a><br>
    </p>
    </div>
    </body>
    </html>
    """
    return html

def main():
    global localip
    w5x00_init()
    s = socket()
    s.bind((localip, 80))
    s.listen(5)
    
    while True:
        conn, addr = s.accept()
        print('Connect from %s' % str(addr))
        request = conn.recv(1024)
        request = str(request)
        #print('Content = %s' % request)
        led_on = request.find('/?led=on')
        led_off = request.find('/?led=off')
        if led_on == 6:
            print("LED ON")
            led.value(1)
        if led_off == 6:
            print("LED OFF")
            led.value(0)
        response = web_page()
        conn.send('HTTP/1.1 200 OK\n')
        conn.send('Connection: close\n')
        conn.send('Content-Type: text/html\n')
        conn.send('Content-Length: %s\n\n' % len(response))
        conn.send(response)
        conn.close()


if __name__ == "__main__":
    main()




4.5 结果演示

在这里插入图片描述

第一步:打开thonny选择环境为Raspberry Pi Pico将程序复制到Thonny中,然后点击运行。

第二步:打开浏览器输入服务器ip,进入到网页。

第三步:选择灯的状态进行控制。点击浏览器界面控制灯的状态之后Thonny上的窗口会打印灯的状态和客户端ip。

注意:因为MicroPython的print函数是启用了stdout缓冲的,所以有时候并不会第一时间打印出内容。

5 注意事项

  • 如果采用的是Wiznet的W5500来实现本章的示例,则只需烧录W5500的固件并运行示例程序即可。

6 相关链接

WIZnet官网

本章例程链接

想了解更多,评论留言哦!

文章来源:https://blog.csdn.net/WIZnet2012/article/details/135084470
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。