777|1

1

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

【得捷Follow me第4期】项目任务提交 [复制链接]

 

入门任务:开发环境搭建,BLINK,驱动液晶显示器进行显示。

W5500-RPI-PICO开发板对Arduino有很好的支持,安扎官方文档,我们先在arduino IDE中添加开发板地址,由于我购买了一块cardputer作为项目中的协处理器,负责屏幕显示,因此也一并添加相关支持。:

链接已隐藏,如需查看请登录或者注册

https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json

 

  添加完成后,在开发板管理器中搜索pico并安装。

 

blink完成非常简单,直接使用arduino官方的basic example blink,不需要任何修改,直接上传。

  上传完成后就可以看到绿灯闪起来。

 

液晶屏是在cardputer上进行驱动的,我先在cardputer上初始化好液晶屏,然后开启一个硬件串口作为输入,当接收到信息时将它显示在屏幕上。这样就可以实现一个简单的串口显示器。W5500-RPI-PICO只需要将需要显示的内容用串口发送出去就可以。

 

在使用cardputer之前,我们需要安装一下对应的库。

 

安装好后使用起来就非常简单了。

  • #include "M5Cardputer.h"
  • #include <HardwareSerial.h>
  • HardwareSerial mySerial(2);
  • void setup() {
  • auto cfg = M5.config();
  • M5Cardputer.begin(cfg, true);
  • M5Cardputer.Display.setRotation(1);
  • M5Cardputer.Display.setTextColor(GREEN);
  • M5Cardputer.Display.setTextDatum(middle_center);
  • M5Cardputer.Display.setTextFont(&fonts::Orbitron_Light_24);
  • M5Cardputer.Display.setTextSize(1);
  • M5Cardputer.Display.drawString("Ready",
  • M5Cardputer.Display.width() / 2,
  • M5Cardputer.Display.height() / 2);
  • Serial.begin(115200);
  • mySerial.begin(115200, SERIAL_8N1, 2, 1);
  • }
  • void loop() {
  • if (mySerial.available()) {
  • String receivedString = mySerial.readString();
  • Serial.println(receivedString);
  • if (receivedString != "") {
  • M5Cardputer.Display.clear();
  • M5Cardputer.Display.drawString(receivedString,
  • M5Cardputer.Display.width() / 2,
  • M5Cardputer.Display.height() / 2);
  • }
  • }
  • }

 

这里我们用cardputer上的GPIO1和GPIO2作为TX和RX。接下来我们用pico 使用serial1打印一个hello,就可以显示在cardputer上。注意由于pico在连接上串口监视器后并不会重置,因此要先等待串口连接后,才可以继续执行串口打印任务,否则无法在串口看到输出。

  • void setup() {
  • Serial.begin(115200);
  • Serial1.begin(115200);
  • while (!Serial)
  • ;
  • Serial.println("Now send Hello");
  • Serial1.println("Hello");
  • }
  • void loop() {
  • }

 

基础任务一:完成主控板W5500初始化(静态IP配置),并能使用局域网电脑ping通,同时W5500可以ping通互联网站点;通过抓包软件(Wireshark、Sniffer等)抓取本地PC的ping报文,展示并分析。

 

同样的,先安装一下需要的库。这个库需要自己去github上下载下来zip,然后在arduino ide中导入zip库。

链接已隐藏,如需查看请登录或者注册

 

静态配置好ip,MAC等参数,就可以联网,然后分别解析dns并ping一下三个网站。

  • #include <Ethernet.h>
  • #include <Dns.h>
  • #include <EthernetICMP.h>
  • byte mac[] = { 0xDE, 0xAD, 0xBE, 0xE1, 0xF2, 0xE3 };
  • IPAddress ip(192, 168, 50, 188);
  • IPAddress gateway(192, 168, 50, 1);
  • IPAddress myDns(8, 8, 8, 8);
  • IPAddress subnet(255, 255, 255, 0);
  • IPAddress setNet() {
  • Serial.println("Ethernet Begin");
  • Ethernet.init(17);
  • // DHCP
  • // Ethernet.begin(mac);
  • // 静态IP设置
  • Ethernet.begin(mac, ip, myDns, gateway, subnet);
  • // 打印INFO
  • 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());
  • Serial.print("My Mac address: ");
  • byte macBuffer[6];
  • Ethernet.MACAddress(macBuffer);
  • for (byte octet = 0; octet < 6; octet++) {
  • Serial.print(macBuffer[octet], HEX);
  • if (octet < 5) {
  • Serial.print('-');
  • }
  • }
  • Serial.println("");
  • return Ethernet.localIP();
  • }
  • DNSClient dnClient;
  • SOCKET pingSocket = 4;
  • EthernetICMPPing ping(pingSocket, (uint8_t)random(0, 255));
  • void pingTest(const IPAddress &dstip) {
  • EthernetICMPEchoReply echoReply = ping(dstip, 4);
  • char buffer[256];
  • if (echoReply.status == SUCCESS) {
  • sprintf(buffer,
  • "Reply[%d] from: %d.%d.%d.%d: bytes=%d time=%ldms TTL=%d",
  • echoReply.data.seq,
  • echoReply.addr[0],
  • echoReply.addr[1],
  • echoReply.addr[2],
  • echoReply.addr[3],
  • REQ_DATASIZE,
  • millis() - echoReply.data.time,
  • echoReply.ttl);
  • } else {
  • sprintf(buffer, "Echo request failed; %d", echoReply.status);
  • }
  • Serial.println(buffer);
  • }
  • void ping_site() {
  • dnClient.begin(Ethernet.dnsServerIP());
  • const char domains[3][20] = { "www.eeworld.com.cn", "www.digikey.cn", "www.digikey.com" };
  • IPAddress dstip;
  • for (int i = 0; i < 3; i++) {
  • if (dnClient.getHostByName(domains[i], dstip) == 1) {
  • Serial.print(domains[i]);
  • Serial.print(" = ");
  • Serial.println(dstip);
  • pingTest(dstip);
  • } else
  • Serial.println(F("dns lookup failed"));
  • }
  • }
  • void setup() {
  • Serial.begin(115200);
  • while (!Serial)
  • ;
  • setNet();
  • ping_site();
  • }
  • void loop() {
  • }

 

打开wireshark开始抓包,然后用电脑ping一下上面串口打印出的W5500-RPI-PICO开发板,接着在wireshark中用ip地址筛选,就可以看到捕获到的icmp包。

 

 

 

基础任务二:主控板建立TCPIP或UDP服务器,局域网PC使用TCPIP或UDP客户端进行连接并发送数据,主控板接收到数据后,送液晶屏显示(没有则通过串口打印显示);通过抓包软件抓取交互报文,展示并分析。

w5500-rpi-pico连接上网络后,建立一个tcp服务器并监听5000端口。如果有客户连入,则循环读取内容,并将内容添加至字符串。等客户结束连接后,用串口监视器和cardputer同时打印接收的内容。

  • #include <Ethernet.h>
  • byte mac[] = { 0xDE, 0xAD, 0xBE, 0xE1, 0xF2, 0xE3 };
  • IPAddress ip(192, 168, 50, 188);
  • IPAddress gateway(192, 168, 50, 1);
  • IPAddress myDns(8, 8, 8, 8);
  • IPAddress subnet(255, 255, 255, 0);
  • IPAddress setNet() {
  • Serial.println("Ethernet Begin");
  • Ethernet.init(17);
  • // DHCP
  • // Ethernet.begin(mac);
  • // 静态IP设置
  • Ethernet.begin(mac, ip, myDns, gateway, subnet);
  • // 打印INFO
  • 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());
  • Serial.print("My Mac address: ");
  • byte macBuffer[6];
  • Ethernet.MACAddress(macBuffer);
  • for (byte octet = 0; octet < 6; octet++) {
  • Serial.print(macBuffer[octet], HEX);
  • if (octet < 5) {
  • Serial.print('-');
  • }
  • }
  • Serial.println("");
  • return Ethernet.localIP();
  • }
  • EthernetServer server(5000);
  • String server_loop() {
  • String msg;
  • EthernetClient client = server.available();
  • if (client) {
  • Serial.println("new client");
  • while (client.connected()) {
  • if (client.available()) {
  • char c = client.read();
  • msg += String(c);
  • }
  • }
  • }
  • return msg;
  • }
  • void setup() {
  • Serial.begin(115200);
  • Serial1.begin(115200);
  • while (!Serial)
  • ;
  • setNet();
  • server.begin();
  • }
  • void loop() {
  • String msg = server_loop();
  • if (msg != "") {
  • Serial.println(msg);
  • Serial1.println(msg);
  • }
  • }

编译代码时会有一定概率报错Compilation error: cannot declare variable 'server' to be of abstract type 'EthernetServer'。如果出现这种情况,需要修改一下两个库文件:

Ethernet.h

  • // virtual void begin();
  • virtual void begin(uint16_t port=0);

EthernetServer.cpp

  • //void EthernetServer::begin()
  • void EthernetServer::begin(uint16_t port)

 

电脑上发送tcp访问请求我使用的是python,用python写了个非常简单的代码,发送Hello!!!后关闭连接。

  • import socket
  • msg = "Hello!!!"
  • ip_addr=("192.168.50.188",5000)
  • client=socket.socket()
  • client.connect(ip_addr)
  • client.send(bytes(msg,"utf-8"))
  • client.close()

运行一下python代码,就可以看到效果。

打开wireshark,也可以抓到我们发送过去的信息。

 

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

通过NTP服务器获取时间的方式是基于UDP的,UDP是只管发送,不管对方收不收的到,因此单次请求可能会失败,所以需要设定一定的重试次数。每次重试之间需要有间隔,以免被对方服务器当作网络攻击直接屏蔽。代码中先把请求的UDP报文写好,再用该方法像服务器发送请求。成功获取到时间后,发送到串口和屏幕。

  • #include <Ethernet.h>
  • #include <EthernetUdp.h>
  • byte mac[] = { 0xDE, 0xAD, 0xBE, 0xE1, 0xF2, 0xE3 };
  • IPAddress ip(192, 168, 50, 188);
  • IPAddress gateway(192, 168, 50, 1);
  • IPAddress myDns(8, 8, 8, 8);
  • IPAddress subnet(255, 255, 255, 0);
  • IPAddress setNet() {
  • Serial.println("Ethernet Begin");
  • Ethernet.init(17);
  • // DHCP
  • // Ethernet.begin(mac);
  • // 静态IP设置
  • Ethernet.begin(mac, ip, myDns, gateway, subnet);
  • // 打印INFO
  • 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());
  • Serial.print("My Mac address: ");
  • byte macBuffer[6];
  • Ethernet.MACAddress(macBuffer);
  • for (byte octet = 0; octet < 6; octet++) {
  • Serial.print(macBuffer[octet], HEX);
  • if (octet < 5) {
  • Serial.print('-');
  • }
  • }
  • Serial.println("");
  • return Ethernet.localIP();
  • }
  • EthernetUDP Udp;
  • const uint8_t NTP_PACKET_SIZE = 48;
  • byte packetBuffer[NTP_PACKET_SIZE];
  • char bjtime[256];
  • 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 ntp()
  • {
  • while (true)
  • {
  • sendNTPpacket("time.nist.gov"); // 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:
  • sprintf(bjtime, "%d : %d : %d",
  • (epoch % 86400L) / 3600 + 8,
  • (epoch % 3600) / 60,
  • epoch % 60);
  • return;
  • }
  • // wait 3 seconds before asking for the time again
  • Serial.println("Retry in 3 seconds...");
  • delay(3000);
  • }
  • }
  • void setup() {
  • Serial.begin(115200);
  • Serial1.begin(115200);
  • while (!Serial)
  • ;
  • setNet();
  • Udp.begin(8888);
  • ntp();
  • Serial.println(bjtime);
  • Serial1.println(bjtime);
  • }
  • void loop() {
  • }

 终极任务二:使用外部存储器,组建简易FTP文件服务器,并能正常上传下载文件。

这个任务我本来打算继续在arduino平台完成的,虽然ftp部分没有很大的问题,但是储存这块出了问题。不管是littlefs,还是SD库,我尝试了各种主流的sd卡驱动库,都无法在修改默认SPI的情况下成功读取并写入SD卡。因此只好转战micropython,因为micropython可以直接在内存中虚拟出一块区域作为储存使用。

github中8266的uftp代码可以直接使用,唯一需要更改的一个小地方,就是将我们的IP地址传入即可。

  • import socket
  • import network
  • import uos
  • import gc
  • from time import localtime
  • from machine import Pin,SPI
  • import time
  • 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.50.188','255.255.255.0','192.168.50.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])
  • 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()
  • ftpserver()

 

 

项目视频


项目源码

https://download.eeworld.com.cn/detail/%E6%B1%9F%E5%8D%8E210/631263

 

心得
通过followme活动让我学到了很多,在活动中可以尝试很多之前没有尝试过的平台,希望活动越办越好。

最新回复

cardputer之前,要安装一下对应的库,谢谢提醒哈   详情 回复 发表于 2024-2-22 07:27
点赞 关注
 
 

回复
举报

6931

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

cardputer之前,要安装一下对应的库,谢谢提醒哈

 
 
 

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

猜你喜欢
随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条
电源解决方案和技术 | DigiKey 应用探索站
当月好物、电源技术资源、特色活动、DigiKey在线实用工具,干货多多~

查看 »

 
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
快速回复 返回顶部 返回列表