665|1

222

帖子

1

TA的资源

一粒金砂(高级)

楼主
 

【得捷电子Follow me第4期】任务综合帖(从入门任务到终极任务) [复制链接]

 

任务演示视频

 


 

 

第四期我购买了下面三个模块,分别是:

W5500-EVB-Pico,一片四色墨水屏(2.66" EPD, SPECTRA B/W/R/Y, W.IT),墨水屏驱动板(EXT3 - EPD EXTENSION BOARD).

  1. W5500-EVB-Pico:这可能是一款基于W5500芯片的开发板。W5500是一款以太网控制器,通常用于嵌入式系统,以便这些系统能够连接到局域网或广域网。EVB(Evaluation Board)通常是评估板的意思,用于评估芯片的性能或功能。Pico可能指的是这款开发板的尺寸较小,适合用在空间有限的应用场景中。

  2. 四色墨水屏(2.66" EPD, SPECTRA B/W/R/Y, W.IT)

    • 2.66" EPD:EPD(Electronic Paper Display)是电子纸显示器的缩写,是一种模仿纸张显示效果的技术。这种屏幕在显示内容时不消耗电力,只有在刷新内容时才需要电力。2.66"指的是这种屏幕的尺寸。
    • SPECTRA B/W/R/Y:这可能指的是这款墨水屏能够显示黑白红黄四种颜色。传统的EPD通常是黑白的,但近年来,彩色EPD也开始出现,它们能够显示更多的颜色。
    • W.IT:这可能是墨水屏制造商或品牌的标识,但具体含义需要查看相关的产品文档或资料。
  3. 墨水屏驱动板(EXT3 - EPD EXTENSION BOARD):这是一个用于驱动和控制墨水屏的电路板。它通常包含必要的电路和元件,以便与微处理器或微控制器通信,并控制墨水屏的显示内容。EXT3可能是这款驱动板的型号或标识。

 下面是这三个实物图片,后面外加一个OLED(0.96寸)。

从上至下,第一个是墨水屏,中间的是墨水屏驱动板,第三个是W5500+RP2040主板。

下面开始了解模块与资料。

先从主板开始,功能引脚定义:

 

 

 
 

原理图:

下面正式开始任务:

 

入门任务:驱动墨水屏

思路:

  1. 硬件连接
    • 首先,墨水屏的驱动板(EXT3 - EPD EXTENSION BOARD)与RP2040之间的接口连接。SPI(Serial Peripheral Interface)接口用于数据传输,以及电源和地线连接。
    • 电源线(如VCC, GND, VCOM等)都已正确连接,并根据墨水屏规格书的要求提供适当的电压。
  2. 软件开发
    • 编写用于RP2040的驱动程序。使用C语言,并可能使用MicroPython(嵌入式编程环境。
    • 驱动程序实现与墨水屏通信的协议,通常是SPI协议。需要发送正确的命令和数据序列来初始化屏幕、设置显示模式、传输图像数据等。

使用的环境是Arduino,安装好相对应的驱动与库。

软件界面:

 

 

代码:

#include <Arduino.h>
#include "PDLS_EXT3_Basic_BWRY.h"
//#include "hV_HAL_Peripherals.h"
//#include "hV_Configuration.h"

Screen_EPD_EXT3 myScreen(eScreen_EPD_EXT3_266_BWRY, boardRaspberryPiPico_RP2040);
void displayPaletteBWRY()
{
  uint16_t y = 20;
  myScreen.setOrientation(ORIENTATION_LANDSCAPE);
  myScreen.selectFont(Font_Terminal16x24);

  myScreen.gText(30, y, "DJ Hell World!", myColours.yellow);
  y += myScreen.characterSizeY()+20;
  myScreen.selectFont(Font_Terminal12x16);
  myScreen.gText(30, y, "EEWORLD Follow me 4.", myColours.red);
  y += myScreen.characterSizeY()+12;
  y += myScreen.characterSizeY();

  myScreen.selectFont(Font_Terminal12x16);
  myScreen.gText(30, y, "EEWORLD,DigiKey!");
  y += myScreen.characterSizeY();
  myScreen.flush();
}

void setup()
{
  Serial.begin(115200);
  delay(500);
  pinMode(LED_BUILTIN, OUTPUT);
  myScreen.begin();
  Serial.println("DISPLAY_PALETTE_BWRY... ");
  myScreen.clear();
  displayPaletteBWRY();
}

void loop()
{
  //digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  //delay(1000);                      // wait for a second
 // digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
 // delay(1000);                      // wait for a second
}

视频:

硬件连接介绍,与驱动显示FM4的介绍:

硬件连接:

f179052801721548125e22f663e30c14

驱动得捷FM4英文:

a3ea901faeca822d8947be94f894b0a5

下面是墨水屏整体视频:

得捷第四期Fm4驱动墨水屏

 

任务一:

以下是实现这一任务的基本步骤和考虑点:

1. W5500初始化与静态IP配置

首先,需要对W5500进行初始化,并为其配置一个静态IP地址。这通常涉及以下几个步骤:

  • 上电复位:确保W5500在上电后处于已知状态。
  • 设置Socket模式:配置W5500的工作模式,通常是TCP/IP模式。
  • 配置静态IP:为W5500设置一个静态IP地址、子网掩码、默认网关和DNS服务器地址。
  • 设置MAC地址:如果需要,也可以配置W5500的MAC地址。

配置通过串行通信提供的库函数来完成。

2. 实现局域网内电脑与W5500的相互ping通

一旦W5500配置完成,能够在局域网内的电脑上ping通W5500的IP地址,并且W5500也能响应ping请求。验证网络连接的基本功能。

3. W5500 ping通互联网站点

要测试W5500是否能够访问互联网,尝试让它ping一个公共的IP地址或域名。将验证W5500是否能够通过默认网关访问互联网。

遇到的超时问题点:

 

后面通过终于弄通了。

代码:

#include <SPI.h>
#include <Ethernet.h>

// 网卡mac地址
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xE1, 0xF2, 0xE3 };

// 静态ip地址、DNS服务、网关、子网掩码
// byte ip[] = { 192, 168, 1, 168 };
IPAddress ip(192, 168, 1, 168);
IPAddress myDns(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

void setup() {
  // 配置串口
  Serial.begin(115200);
  while (!Serial) {
    ;  // 等待串口连接
  }

  // 静态IP设置
  Serial.println("Ethernet Begin");
  Ethernet.init(17);
  Ethernet.begin(mac, ip, myDns, gateway, subnet);

  // 输出网卡mac地址、IP地址、子网掩码、DNS、网关
  Serial.print("My Mac address: ");
  byte macBuffer[6];               // 设置mac地址存储buff
  Ethernet.MACAddress(macBuffer);  // 读取mac地址
  for (byte octet = 0; octet < 6; octet++) {
    Serial.print(macBuffer[octet], HEX);
    if (octet < 5) {
      Serial.print('-');
    }
  }
  Serial.println("");

  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());

  Serial.print("My subnet: ");
  Serial.println(Ethernet.subnetMask());

  Serial.print("My DNS address: ");
  Serial.println(Ethernet.dnsServerIP());

  Serial.print("My GateWay address: ");
  Serial.println(Ethernet.gatewayIP());
}

void loop() {
}

 

任务二: 

先在百度中找步骤与参考方向如下:

  1. 在W5500上建立TCP服务器
    • 配置W5500的Socket以监听指定的端口(这里使用的是8888)。
    • 设置Socket为TCP模式,并绑定到相应的IP地址和端口。
    • 使Socket进入监听状态,等待客户端的连接请求。
  2. 编写TCP服务器处理程序
    • 当客户端连接时,接受连接请求。
    • 读取客户端发送的数据。
    • 发送“Hello, client!”字符串作为对客户端的响应。
    • 将接收到的数据通过串口输出,并在OLED显示屏上显示。
  3. 编写TCP客户端应用程序
    • 在局域网内的PC上编写一个TCP客户端应用程序。
    • 让客户端连接到W5500的IP地址和端口8888。
    • 发送数据到服务器,并接收来自服务器的响应。
  4. 使用抓包软件分析交互报文
    • 配置抓包软件(如Wireshark)以捕获与W5500相关的网络流量。
    • 运行TCP客户端应用程序并触发与服务器的交互。
    • 在抓包软件中查看和分析TCP握手过程、数据传输以及服务器和客户端之间的通信报文。

 输出结果:

 

 

代码:

#include <Ethernet.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xE1, 0xF2, 0xE3};
IPAddress ip(192, 168, 1, 168);
IPAddress myDns(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

EthernetServer server(8888);
bool alreadyConnected = false; // whether or not the client was connected previously

void printConnectionInformation()
{
    Serial.print("[INFO] IP Address: ");
    Serial.println(Ethernet.localIP());
    Serial.print("[INFO] Subnet Mask: ");
    Serial.println(Ethernet.subnetMask());
    Serial.print("[INFO] Gateway: ");
    Serial.println(Ethernet.gatewayIP());
    Serial.print("[INFO] DNS: ");
    Serial.println(Ethernet.dnsServerIP());
}

void setup()
{
    Serial.begin(115200);
    delay(5000);
    Serial.println("System is begin!");
    Ethernet.init(17);
    if (Ethernet.begin(mac) == 0) // 看看DHCP是否能动态分配ip给Arduino
    {
        Serial.println("connt get ip by dhcp!");
        Ethernet.begin(mac, ip, myDns, gateway, subnet); // DHCP不能动态分配,就静态设置ip给Arduino
    }

    // Ethernet.init(17);
    // Ethernet.begin(mac, ip, myDns, gateway, subnet);

    // Check for Ethernet hardware present
    if (Ethernet.hardwareStatus() == EthernetNoHardware)
    {
        Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
        while (true)
        {
            delay(1); // do nothing, no point running without Ethernet hardware
        }
    }
    while (Ethernet.linkStatus() == LinkOFF)
    {
        Serial.println("Ethernet cable is not connected.");
        delay(500);
    }

    // give the Ethernet shield a second to initialize:
    // delay(1000);
    printConnectionInformation();
    server.begin();
}

void loop()
{
    EthernetClient client = server.available();
    // when the client sends the first byte, say hello:
    if (client)
    {
        if (!alreadyConnected)
        {
            // clear out the input buffer:
            client.flush();
            Serial.println("We have a new client");
            client.println("Hello, client!");
            alreadyConnected = true;
        }

        if (client.available() > 0)
        {
            // read the bytes incoming from the client:
            char thisChar = client.read();
            // echo the bytes back to the client:
            server.write(thisChar);
            // echo the bytes to the server as well:
            Serial.write(thisChar);
        }
    }
}

 

 

进阶任务从NTP服务器(注意数据交互格式的解析)同步时间,获取时间送显示屏(串口)显示。

继续参考步骤:

要从NTP服务器同步时间并在显示屏上显示,你首先需要使用UDP协议与NTP服务器通信。NTP协议使用的是UDP端口123。NTP消息格式是复杂的,但幸运的是,我们只需要关注其中的时间戳字段来获取时间。

以下是一个简化的步骤,描述如何从一个NTP服务器同步时间,并将时间转换为本地时间(假设你所在的时区是UTC+8),然后通过串口发送到显示屏:

  1. 初始化UDP客户端
    • 设置UDP Socket。
    • 配置W5500的IP地址和子网掩码。
    • 设置目标NTP服务器的IP地址和端口号(time.nist.gov的IP地址和端口123)。
  2. 发送NTP请求
    • 创建一个NTP请求数据包,它通常是一个48字节的消息,前16个字节是NTP头,后面跟着32字节的填充。
    • 发送这个请求到NTP服务器。
  3. 接收NTP响应
    • 等待并接收来自NTP服务器的响应。
    • 解析响应数据包,获取时间戳字段。
  4. 转换时间
    • NTP时间戳是自1900年1月1日以来的秒数,我们需要将其转换为人类可读的格式(年、月、日、时、分、秒)。
    • 考虑到NTP服务器返回的是UTC时间,我们需要将时间转换为本地时间(UTC+8)。
  5. 通过串口发送时间
    • 将转换后的本地时间格式化为字符串。
    • 通过串口发送这个字符串到显示屏。

硬件连接:

开发平台是以 Visual Studio Code开发。

软件界面截图:

 

#include <SPI.h>
#include <Ethernet.h>
#include <U8x8lib.h>
#define U8LOG_WIDTH 16
#define U8LOG_HEIGHT 8
uint8_t u8log_buffer[U8LOG_WIDTH * U8LOG_HEIGHT];
U8X8LOG u8x8log;
U8X8_SSD1306_128X64_NONAME_4W_SW_SPI u8x8(10, 11, 40, 9, 8);

byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02};
IPAddress staticIP(192, 168, 1, 18);
IPAddress myDns(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

unsigned int localPort = 8888;             // local port to listen for UDP packets
const char timeServer[] = "time.nist.gov"; // time.nist.gov NTP server
const int NTP_PACKET_SIZE = 48;            // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE];        // buffer to hold incoming and outgoing packets
EthernetUDP Udp;

void printConnectionInformation()
{
  Serial.print("[INFO] IP Address: ");
  Serial.println(Ethernet.localIP());
  Serial.print("[INFO] Subnet Mask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("[INFO] Gateway: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("[INFO] DNS: ");
  Serial.println(Ethernet.dnsServerIP());

  u8x8log.print("ip=");
  u8x8log.println(Ethernet.localIP());
  u8x8log.print("Mask=");
  u8x8log.println(Ethernet.subnetMask());
  u8x8log.print("DNS=");
  u8x8log.println(Ethernet.dnsServerIP());
}

void setup()
{
  Serial.begin(115200);
  u8x8.begin();
  u8x8.setFont(u8x8_font_chroma48medium8_r);

  u8x8log.begin(u8x8, U8LOG_WIDTH, U8LOG_HEIGHT, u8log_buffer);
  u8x8log.setRedrawMode(1); // 0: Update screen with newline, 1: Update screen for every char

  if (Ethernet.begin(mac) == 0) // 看看DHCP是否能动态分配ip给Arduino
  {
    Ethernet.begin(mac, staticIP, myDns, gateway, subnet); // DHCP不能动态分配,就静态设置ip给Arduino
  }

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware)
  {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true)
    {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  while (Ethernet.linkStatus() == LinkOFF)
  {
    Serial.println("Ethernet cable is not connected.");
    delay(500);
  }

  // give the Ethernet shield a second to initialize:
  delay(1000);
  printConnectionInformation();
  Udp.begin(localPort);
}
// send an NTP request to the time server at the given address
void sendNTPpacket(const char *address)
{
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011; // LI, Version, Mode
  packetBuffer[1] = 0;          // Stratum, or type of clock
  packetBuffer[2] = 6;          // Polling Interval
  packetBuffer[3] = 0xEC;       // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12] = 49;
  packetBuffer[13] = 0x4E;
  packetBuffer[14] = 49;
  packetBuffer[15] = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  Udp.beginPacket(address, 123); // NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}

void loop()
{
  int hour, min, sec;
  char cur_time[9];
  sendNTPpacket(timeServer); // send an NTP packet to a time server
  // wait to see if a reply is available
  delay(1000);
  if (Udp.parsePacket())
  {
    // We've received a packet, read the data from it
    Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
    // the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, extract the two words:

    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;
    Serial.print("Seconds since Jan 1 1900 = ");
    Serial.println(secsSince1900);

    // now convert NTP time into everyday time:
    Serial.print("Unix time = ");
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;
    // print Unix time:
    Serial.println(epoch);

    // print the hour, minute and second:
    hour = (epoch % 86400L) / 3600+8;
    min = (epoch % 3600) / 60;
    sec = epoch % 60;
    sprintf(cur_time, "%02d:%02d:%02d", hour, min, sec);
    Serial.println(cur_time);
    u8x8log.print("Time=");
    u8x8log.println(cur_time);
    delay(10000);
    Ethernet.maintain();
  }
}

 

视频:

7bcfe85c6009bcad03cfd5765d8708d8

 

 

终级任务

二选一,本次是使用的是外部存储器,组建简易FTP文件服务器,并能正常上传下载文件,选择了任务2,建立ftp服务器。

开发平台是

  1. MicroPython环境搭建

    • 在你的硬件平台上刷入MicroPython固件。
    • 使用一个串口终端连接到你的硬件平台。
    • 确认MicroPython环境正常工作。

使用THonny软件程序给开发上传程序软件:

代码:

import socket
import network
import uos
import gc
from time import localtime
from machine import Pin,SPI
import time

def w5x00_init():
    #spi init
    spi=SPI(0,2_000_000, mosi=Pin(19),miso=Pin(16),sck=Pin(18))
    nic = network.WIZNET5K(spi,Pin(17),Pin(20)) #spi,cs,reset pin
    nic.active(True)#network active
    nic.ifconfig(('192.168.1.10','255.255.255.0','192.168.1.1','8.8.8.8'))#Set static network address information
    while not nic.isconnected():
        time.sleep(1)
        print(nic.regs())#Print register information
        
    #Print network address information
    print("IP Address:",nic.ifconfig()[0])
    print("Subnet Mask:",nic.ifconfig()[1])
    print("Gateway:",nic.ifconfig()[2])
    print("DNS:",nic.ifconfig()[3])
    return nic

month_name = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

def send_list_data(path, dataclient, full):
    try: # whether path is a directory name
        for fname in uos.listdir(path):
            dataclient.sendall(make_description(path, fname, full))
    except: # path may be a file name or pattern
        pattern = path.split("/")[-1]
        path = path[:-(len(pattern) + 1)]
        if path == "": path = "/"
        for fname in uos.listdir(path):
            if fncmp(fname, pattern) == True:
                dataclient.sendall(make_description(path, fname, full))
                
def make_description(path, fname, full):
    if full:
        stat = uos.stat(get_absolute_path(path,fname))
        file_permissions = "drwxr-xr-x" if (stat[0] & 0o170000 == 0o040000) else "-rw-r--r--"
        file_size = stat[6]
        tm = localtime(stat[7])
        if tm[0] != localtime()[0]:
            description = "{}    1 owner group {:>10} {} {:2} {:>5} {}\r\n".format(
                file_permissions, file_size, month_name[tm[1]], tm[2], tm[0], fname)
        else:
            description = "{}    1 owner group {:>10} {} {:2} {:02}:{:02} {}\r\n".format(
                file_permissions, file_size, month_name[tm[1]], tm[2], tm[3], tm[4], fname)
    else:
        description = fname + "\r\n"
    return description
    
def send_file_data(path, dataclient):
    with open(path, "r") as file:
        chunk = file.read(512)
        while len(chunk) > 0:
            dataclient.sendall(chunk)
            chunk = file.read(512)

def save_file_data(path, dataclient, mode):
    with open(path, mode) as file:
        chunk = dataclient.read(512)
        while len(chunk) > 0:
            file.write(chunk)
            chunk = dataclient.read(512)

def get_absolute_path(cwd, payload):
    # Just a few special cases "..", "." and ""
    # If payload start's with /, set cwd to / 
    # and consider the remainder a relative path
    if payload.startswith('/'):
        cwd = "/"
    for token in payload.split("/"):
        if token == '..':
            if cwd != '/':
                cwd = '/'.join(cwd.split('/')[:-1])
                if cwd == '': 
                    cwd = '/'
        elif token != '.' and token != '':
            if cwd == '/':
                cwd += token
            else:
                cwd = cwd + '/' + token
    return cwd

# compare fname against pattern. Pattern may contain
# wildcards ? and *.
def fncmp(fname, pattern):
    pi = 0
    si = 0
    while pi < len(pattern) and si < len(fname):
        if (fname[si] == pattern[pi]) or (pattern[pi] == '?'):
            si += 1
            pi += 1
        else:
            if pattern[pi] == '*': # recurse
                if (pi + 1) == len(pattern):
                    return True
                while si < len(fname):
                    if fncmp(fname[si:], pattern[pi+1:]) == True:
                        return True
                    else:
                        si += 1
                return False
            else:
                return False
    if pi == len(pattern.rstrip("*"))  and si == len(fname):
        return True
    else:
        return False
    
def ftpserver():
    DATA_PORT = 13333
    ftpsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    datasocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    ftpsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    datasocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    ftpsocket.bind(socket.getaddrinfo("0.0.0.0", 21)[0][4])
    datasocket.bind(socket.getaddrinfo("0.0.0.0", DATA_PORT)[0][4])

    ftpsocket.listen(1)
    datasocket.listen(1)
    datasocket.settimeout(10)

    msg_250_OK = '250 OK\r\n'
    msg_550_fail = '550 Failed\r\n'
    try:
        dataclient = None
        fromname = None
        while True:
            cl, remote_addr = ftpsocket.accept()
            cl.settimeout(300)
            cwd = '/'
            try:
                # print("FTP connection from:", remote_addr)
                cl.sendall("220 Hello, this is the ESP8266.\r\n")
                while True:
                    gc.collect()
                    data = cl.readline().decode("utf-8").rstrip("\r\n")
                    if len(data) <= 0:
                        print("Client disappeared")
                        break
                    
                    command = data.split(" ")[0].upper()
                    payload = data[len(command):].lstrip()

                    path = get_absolute_path(cwd, payload)
                    
                    print("Command={}, Payload={}, Path={}".format(command, payload, path))
                    
                    if command == "USER":
                        cl.sendall("230 Logged in.\r\n")
                    elif command == "SYST":
                        cl.sendall("215 UNIX Type: L8\r\n")
                    elif command == "NOOP":
                        cl.sendall("200 OK\r\n")
                    elif command == "FEAT":
                        cl.sendall("211 no-features\r\n")
                    elif command == "PWD":
                        cl.sendall('257 "{}"\r\n'.format(cwd))
                    elif command == "CWD":
                        try:
                            files = uos.listdir(path)
                            cwd = path
                            cl.sendall(msg_250_OK)
                        except:
                            cl.sendall(msg_550_fail)
                    elif command == "CDUP":
                        cwd = get_absolute_path(cwd, "..")
                        cl.sendall(msg_250_OK)
                    elif command == "TYPE":
                        # probably should switch between binary and not
                        cl.sendall('200 Transfer mode set\r\n')
                    elif command == "SIZE":
                        try:
                            size = uos.stat(path)[6]
                            cl.sendall('213 {}\r\n'.format(size))
                        except:
                            cl.sendall(msg_550_fail)
                    elif command == "QUIT":
                        cl.sendall('221 Bye.\r\n')
                        break
                    elif command == "PASV":
                        addr = nic.ifconfig()[0]
                        cl.sendall('227 Entering Passive Mode ({},{},{}).\r\n'.format(
                            addr.replace('.',','), DATA_PORT>>8, DATA_PORT%256))
                        dataclient, data_addr = datasocket.accept()
                        # print("FTP Data connection from:", data_addr)
                    elif command == "LIST" or command == "NLST":
                        if not payload.startswith("-"):
                            place = path
                        else: 
                            place = cwd
                        try:
                            send_list_data(place, dataclient, command == "LIST" or payload == "-l")
                            cl.sendall("150 Here comes the directory listing.\r\n")
                            cl.sendall("226 Listed.\r\n")
                        except:
                            cl.sendall(msg_550_fail)
                        if dataclient is not None:
                            dataclient.close()
                            dataclient = None
                    elif command == "RETR":
                        try:
                            send_file_data(path, dataclient)
                            cl.sendall("150 Opening data connection.\r\n")
                            cl.sendall("226 Transfer complete.\r\n")
                        except:
                            cl.sendall(msg_550_fail)
                        if dataclient is not None:
                            dataclient.close()
                            dataclient = None
                    elif command == "STOR":
                        try:
                            cl.sendall("150 Ok to send data.\r\n")
                            save_file_data(path, dataclient, "w")
                            cl.sendall("226 Transfer complete.\r\n")
                        except:
                            cl.sendall(msg_550_fail)
                        if dataclient is not None:
                            dataclient.close()
                            dataclient = None
                    elif command == "APPE":
                        try:
                            cl.sendall("150 Ok to send data.\r\n")
                            save_file_data(path, dataclient, "a")
                            cl.sendall("226 Transfer complete.\r\n")
                        except:
                            cl.sendall(msg_550_fail)
                        if dataclient is not None:
                            dataclient.close()
                            dataclient = None
                    elif command == "DELE":
                        try:
                            uos.remove(path)
                            cl.sendall(msg_250_OK)
                        except:
                            cl.sendall(msg_550_fail)
                    elif command == "RMD":
                        try:
                            uos.rmdir(path)
                            cl.sendall(msg_250_OK)
                        except:
                            cl.sendall(msg_550_fail)
                    elif command == "MKD":
                        try:
                            uos.mkdir(path)
                            cl.sendall(msg_250_OK)
                        except:
                            cl.sendall(msg_550_fail)
                    elif command == "RNFR":
                            fromname = path
                            cl.sendall("350 Rename from\r\n")
                    elif command == "RNTO":
                            if fromname is not None: 
                                try:
                                    uos.rename(fromname, path)
                                    cl.sendall(msg_250_OK)
                                except:
                                    cl.sendall(msg_550_fail)
                            else:
                                cl.sendall(msg_550_fail)
                            fromname = None
                    else:
                        cl.sendall("502 Unsupported command.\r\n")
                        # print("Unsupported command {} with payload {}".format(command, payload))
            except Exception as err:
                print(err)  

            finally:          
                cl.close()
                cl = None
    finally:
        datasocket.close()
        ftpsocket.close()
        if dataclient is not None:
            dataclient.close()

nic = w5x00_init()
ftpserver()    #直接跑这个就成功建立服务器了



 遇到问题点:

首先是缺少库文件:

第二是没有办法使用FTP+IP访问:

 

 

使用总结:

使用PICO W5500模块与得捷第四期平台结合,体验深刻。PICO W5500作为一款以太网控制器,其高度集成和易用性给项目带来了极大的便利。在得捷第四期的应用中,W5500的稳定性和性能表现优秀,使得网络通信更加可靠。

在使用过程中,我感受到了PICO W5500的易用性。虽然我在这个过程中遇到了很多的问题,但是在通过学习和请教朋友,最终完成这个FM4,后面我会继续研究这个板块,加深。

 

总的来说,PICO W5500是一款性能优异、易于使用的以太网控制器,与得捷第四期平台的结合为我们的项目带来了显著的便利和优势。

 

附件:

缺少SOCKET包文件:

socket.py (1.36 KB, 下载次数: 0)

静太IP:

sketch_feb5a.ino (1.26 KB, 下载次数: 0)

墨水屏:

墨水屏.ino (1.28 KB, 下载次数: 0)

终极任务二:

终极任务二 ftpserver.py (11.62 KB, 下载次数: 1)

 

W5500_EVB_PICO.uf2 (927.5 KB, 下载次数: 0)

 

 

 

点赞 关注
 
 

回复
举报

222

帖子

1

TA的资源

一粒金砂(高级)

沙发
 

终极任务二

视频

6860a940ccd1f549e295300f386c9d1c

 

补充内容 (2024-3-9 13:41): 任务汇总视频:https://www.bilibili.com/video/B ... id_from=333.999.0.0 补充内容 (2024-3-9 13:42):
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表