eew_UPQWC7

  • 2024-03-23
  • 加入了学习《得捷Follow me第4期视频》,观看 得捷Follow me第4期视频

  • 发表了主题帖: 【得捷电子Follow me第4期】补充--tcp网络显示屏

    本帖最后由 eew_UPQWC7 于 2024-3-23 21:53 编辑   原汇总帖【得捷电子Follow me第4期】任务汇总提交 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)中介绍了使用Seeed的GROVE - OLED DISPLAY0.96" 显示屏和M5的ATOMS3U制作tcp协议传输的网络显示屏,当时考虑到 1.Seeed的GROVE - OLED DISPLAY0.96"为GROVE接口恰巧能与M5的ATOMS3U对接省去接线的麻烦;2.刚好趁着任务中学习了TCP网络传输。想着就利用起来。原帖中介绍的有限现在摘出来详细介绍下: 1.接线 因为都是GROVE接口直接对插即可非常方便。     2.ATOMS3U端代码: 需要调用U8g2lib来驱动lcd。 #include <M5AtomS3.h> #include <WiFi.h> #include <WiFiMulti.h> #include <U8g2lib.h> // Set the name and password of the wifi to be connected. // 配置所连接wifi的名称和密码 const char *ssid = "OpenWrt"; const char *password = "01010101"; const uint16_t servPort = 80; WiFiServer server(servPort); const char *servIp = "192.168.1.200"; WiFiClient client; const uint16_t port = 23; U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/G1, /* data=*/G2, /* reset=*/U8X8_PIN_NONE); // All Boards without Reset of the Display void lcdprint(String str) { const u16_t strL = 22; u8g2.firstPage(); do { if (str.length() > strL) { u8g2.setFont(u8g2_font_ncenB08_tr); const int row = str.length() / strL; for (int i = 0; i < row+1; i++) { u8g2.drawStr(0, 10 * (i + 1), str.substring(i * strL, (i + 1) * strL).c_str()); } } else { u8g2.drawStr(0, 12, str.c_str()); } } while (u8g2.nextPage()); } void setup() { Serial.begin(115200); u8g2.begin(); int sum = 0; M5.begin(); // Init M5AtomS3. 初始化M5AtomS3 WiFi.config(IPAddress(192, 168, 1, 200), IPAddress(192, 168, 1, 1), IPAddress(255, 255, 255, 0), IPAddress(192, 168, 1, 1)); WiFi.begin(ssid, password); String msgStr; msgStr = "Waiting connect to WiFi: " + String(ssid); printf(msgStr.c_str()); lcdprint(msgStr); while (WiFi.status() != WL_CONNECTED) { printf("."); lcdprint("..."); delay(1000); sum += 1; if (sum == 8) printf("Conncet failed!\n"); lcdprint("Conncet failed!"); } char buff[100]; sprintf(buff, "WiFi connected\nIP address: \n %s\n", WiFi.localIP().toString()); lcdprint(buff); printf(buff); // The serial port outputs the IP address // of the M5AtomS3. 串口输出M5AtomS3的IP地址 delay(500); sum = 0; server.begin(); sprintf(buff, "Server started @%s:%d\n", WiFi.localIP().toString(), servPort); lcdprint(buff); } void loop() { WiFiClient client = server.available(); // 尝试建立客户对象 char buff[100]; if (client) { sprintf(buff, "%s connected", client.localIP().toString()); lcdprint(buff); String readBuff; // 读取信息暂存 while (client.connected()) { if (client.available()) // 如果有可读数据 { String buff = client.readStringUntil('\r'); lcdprint(buff); } } } client.stop(); // 结束当前连接: sprintf(buff, "remote lcd @ %s:%d has no client connected!", servIp,servPort); lcdprint(buff); delay(1000); }   3.测试效果: 1)wifi连接好后即可打开tcp服务端进入待配对状态: 2)在w5500-evb-pico端建立一个tcp客户端用于向tcp显示服务端发送数据: 以任务二UDP传输为例,当w5500-evb-pico接受到udp数据就会转而发送至tcp显示服务端显示,代码如下: from w5500 import w5500 import time import board import busio as io import digitalio import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket print("Task-2 TCP UDP") led = digitalio.DigitalInOut(board.GP25) led.direction = digitalio.Direction.OUTPUT #初始化网卡 eth=w5500() socket.set_interface(eth) #创建远程LCD TCP socket lcd_client = socket.socket() lcd_server_ip='192.168.1.200' lcd_server_port = 80 lcd_client.connect((lcd_server_ip,lcd_server_port)) print("remote lcd connected !") def rmLcdPrint(s:str): lcd_client.send(s+"\n") #创建UDP socket server_udp = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # Allocate socket for the server server_port_udp = 5000 server_udp.bind((eth.pretty_ip(eth.ip_address),server_port_udp)) # Bind to IP and Port print("Udp listening") def taskUdp(): data, addr = server_udp.recvfrom(50) if data: data=data.decode('utf-8') echoStr=f"get udp data:{data} @ {addr[0]}:{addr[1]}\n" print(echoStr) rmLcdPrint(echoStr) return echoStr else: return None while True: taskUdp() 3)效果: tcp显示屏服务端客户端建立连接后: 向w5500-evb-pico发送udp数据。   w5500-evb-pico接受数据发送atomsU显示:     

  • 2024-02-26
  • 发表了主题帖: 【得捷电子Follow me第4期】任务汇总提交

    本帖最后由 eew_UPQWC7 于 2024-2-26 01:01 编辑         很幸运能够抽中本次得捷电子Follow me第4期活动的参与名额,也很惭愧这个点才提交任务,还请审核大人海谅。           一、本期任务硬件简介         1.本期主板:                2.本期采购的辅助硬件:         包括:Seeed的GROVE - OLED DISPLAY0.96"(原本想直接W5500-EVB-PICO上使用的,因为没有扩展版,接线不便,计划将其作为远程显示屏使用); M5家的ATOMS3U(作为远程显示屏的控制板使用刚好有GROVE接口);ESP THREAD BORDER ROUTER/ZIGBEE(作为发送UDP数据的终端使用)。         来个合照:           二、任务实现与展示         1.入门任务:开发环境搭建,BLINK,驱动液晶显示器进行显示(没有则串口HelloWorld)         开发环境:         开发环境选择cpy简单方便,按住boot键插入usb,拖拽下好的固件至u盘即可,这里下载的adafruit-circuitpython-wiznet_w5500_evb_pico-en_US-8.2.9.uf2。         待重启后,打开thony即可轻松连接开发板编辑程序。         任务代码(显示屏接线麻烦,再TCP任务中使用网络远程调用): import board import busio as io import adafruit_ssd1306 import digitalio import time #blink and hello world # bgColor=0 # SCL=board.GP1 # SDA=board.GP0 # i2c = io.I2C(SCL,SDA) # oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c) # # oled.fill(0) # oled.text("Hello \nWorld!", 10, 10, not bgColor, font_name='font5x8.bin', size=3) # oled.show() print("hellow fm4!") led = digitalio.DigitalInOut(board.GP25) led.direction = digitalio.Direction.OUTPUT led.value = True while True: led.value = not led.value time.sleep(1)          效果展示:                      2.基础任务一:完成主控板W5500初始化(静态IP配置),并能使用局域网电脑ping通,同时W5500可以ping通互联网站点;通过抓包软件(Wireshark、Sniffer等)抓取本地PC的ping报文,展示并分析。         注意需要在lib目录下复制好所需调用的库文件:           核心代码 from w5500 import w5500 import time import board import digitalio print("Task-1 Ping Test") #通过DHCP自动获取IP # eth=w5500(is_dhcp=True) #静态IP eth=w5500() led = digitalio.DigitalInOut(board.GP25) led.direction = digitalio.Direction.OUTPUT while True: led.value = not led.value time.sleep(1) print("Done!")         效果展示:           抓包分析:         通过wireshark可以抓取到ping过程的报文,ping的过程采用ICMP协议,一组报文分为两个,首先是ping请求,然后是被ping端的回应。             3.基础任务二:主控板建立TCPIP或UDP服务器,局域网PC使用TCPIP或UDP客户端进行连接并发送数据,主控板接收到数据后,送液晶屏显示(没有则通过串口打印显示);通过抓包软件抓取交互报文,展示并分析。(TCP和UDP二选一,或者全都操作)         核心代码:         接收UDP数据,并将数据同过TCP传送并显示在ATOMS3U连接的LCD。         主板代码: from w5500 import w5500 import time import board import busio as io import digitalio import adafruit_ssd1306 import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket import asyncio print("Task-2 TCP UDP") led = digitalio.DigitalInOut(board.GP25) led.direction = digitalio.Direction.OUTPUT #初始化网卡 eth=w5500() socket.set_interface(eth) #创建远程LCD TCP socket lcd_client = socket.socket() lcd_server_ip='192.168.1.200' lcd_server_port = 80 lcd_client.connect((lcd_server_ip,lcd_server_port)) print("remote lcd connected !") def rmLcdPrint(s:str): lcd_client.send(s+"\n") #创建UDP socket server_udp = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # Allocate socket for the server server_port_udp = 5000 server_udp.bind((eth.pretty_ip(eth.ip_address),server_port_udp)) # Bind to IP and Port print("Udp listening") def taskUdp(): data, addr = server_udp.recvfrom(50) if data: data=data.decode('utf-8') echoStr=f"get udp data:{data} @ {addr[0]}:{addr[1]}\n" print(echoStr) rmLcdPrint(echoStr) return echoStr else: return None while True: taskUdp()         atoms3U代码: #include <M5AtomS3.h> #include <WiFi.h> #include <WiFiMulti.h> #include <U8g2lib.h> // Set the name and password of the wifi to be connected. // 配置所连接wifi的名称和密码 const char *ssid = "OpenWrt"; const char *password = "01010101"; const uint16_t servPort = 80; WiFiServer server(servPort); const char *servIp = "192.168.1.200"; WiFiClient client; const uint16_t port = 23; U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/G1, /* data=*/G2, /* reset=*/U8X8_PIN_NONE); // All Boards without Reset of the Display void lcdprint(String str) { const u16_t strL = 22; u8g2.firstPage(); do { if (str.length() > strL) { u8g2.setFont(u8g2_font_ncenB08_tr); const int row = str.length() / strL; for (int i = 0; i < row+1; i++) { u8g2.drawStr(0, 10 * (i + 1), str.substring(i * strL, (i + 1) * strL).c_str()); } } else { u8g2.drawStr(0, 12, str.c_str()); } } while (u8g2.nextPage()); } void setup() { Serial.begin(115200); u8g2.begin(); int sum = 0; M5.begin(); // Init M5AtomS3. 初始化M5AtomS3 WiFi.config(IPAddress(192, 168, 1, 200), IPAddress(192, 168, 1, 1), IPAddress(255, 255, 255, 0), IPAddress(192, 168, 1, 1)); WiFi.begin(ssid, password); String msgStr; msgStr = "Waiting connect to WiFi: " + String(ssid); printf(msgStr.c_str()); lcdprint(msgStr); while (WiFi.status() != WL_CONNECTED) { printf("."); lcdprint("..."); delay(1000); sum += 1; if (sum == 8) printf("Conncet failed!\n"); lcdprint("Conncet failed!"); } char buff[100]; sprintf(buff, "WiFi connected\nIP address: \n %s\n", WiFi.localIP().toString()); lcdprint(buff); printf(buff); // The serial port outputs the IP address // of the M5AtomS3. 串口输出M5AtomS3的IP地址 delay(500); sum = 0; server.begin(); sprintf(buff, "Server started @%s:%d\n", WiFi.localIP().toString(), servPort); lcdprint(buff); // while (!client.connect(host, port)) // { // printf( // "Connection failed.\nWaiting 5 seconds before retrying...\n"); // lcdprintf("Connection failed.\nWaiting 5 seconds before retrying...\n"); // delay(5000); // sum += 1; // if (sum > 8) // { // printf( // "Connection failed. Time out!\n"); // lcdprintf("Connection failed. Time out!\n"); // return; // } // } // sprintf(buff,"Connected to server.\n Client:%s:%d\n",client.remoteIP().toString().c_str(),client.remotePort()); // printf(buff); // lcdprintf(buff); } void loop() { WiFiClient client = server.available(); // 尝试建立客户对象 char buff[100]; if (client) { sprintf(buff, "%s connected", client.localIP().toString()); lcdprint(buff); String readBuff; // 读取信息暂存 while (client.connected()) { if (client.available()) // 如果有可读数据 { String buff = client.readStringUntil('\r'); lcdprint(buff); } } } client.stop(); // 结束当前连接: sprintf(buff, "remote lcd @ %s:%d has no client connected!", servIp,servPort); lcdprint(buff); delay(1000); }         另外在ESP THREAD BORDER ROUTER/ZIGBEE循环发送udp数据,代码如下: #include <Arduino.h> #include <WiFi.h> #include <WiFiUdp.h> const char *ssid = "OpenWrt"; const char *password = "01010101"; const char *host = "192.168.1.255"; const u16_t udpPort= 5000; char buffer[100]; bool status = false; bool led_logic = false; int countNum=0; WiFiUDP Udp; void setup() { Serial.begin(115200); WiFi.config(IPAddress(192, 168, 1, 150), IPAddress(192, 168, 1, 1), IPAddress(255, 255, 255, 0), IPAddress(192, 168, 1, 1)); WiFi.begin(ssid, password); int sum = 0; while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(1000); sum += 1; if (sum == 8) printf("Conncet failed!\n"); } Udp.begin(udpPort); sprintf( buffer,"Udp begined @\n IP address:%s Port:%d\n", WiFi.localIP().toString(),udpPort); Serial.print(buffer); } void loop() { // int packetSize = Udp.parsePacket(); Udp.beginPacket(host, udpPort); //准备发送数据 char buff[100]; sprintf(buff,"udp data @%s:%d, countNum=%d\n",WiFi.localIP().toString(),udpPort,countNum++); Udp.print(buff); //复制数据到发送缓存 Serial.println(buff); Udp.endPacket(); //发送数据 delay(2000); }         效果展示: 可以看到远程显示屏分别显示了,PC发送至PICO及ESP THREAD BORDER ROUTER/ZIGBEE发送至PICO的UDP数据:                   抓包分析:         可以看到UDP通信是不需求回应的,发送过程只有一帧报文。           4.进阶任务:从NTP服务器(注意数据交互格式的解析)同步时间,获取时间送显示屏(串口)显示         核心代码 # SPDX-FileCopyrightText: 2022 Scott Shawcroft for Adafruit Industries # SPDX-License-Identifier: MIT """Print out time based on NTP.""" import rtc import time import board import busio as io import digitalio import adafruit_ssd1306 import adafruit_ntp import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket from w5500 import w5500 led = digitalio.DigitalInOut(board.GP25) led.direction = digitalio.Direction.OUTPUT #初始化屏幕 bgColor=0 SCL=board.GP1 SDA=board.GP0 i2c = io.I2C(SCL,SDA) oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c) #初始化网卡 eth=w5500() socket.set_interface(eth) #创建socket # socket= socket.socket() # Allocate socket for the server ntp = adafruit_ntp.NTP(socket, server="ntp.aliyun.com",tz_offset=8) rtc.RTC().datetime = ntp.datetime while True: datetime=time.localtime() timeStr=f"{datetime.tm_year}/{datetime.tm_mon}/{datetime.tm_mday}\n{datetime.tm_hour}:{datetime.tm_min}:{datetime.tm_sec}" # print(timeStr) oled.fill(0) oled.text(f'{timeStr}', 5, 5, not bgColor, font_name='font5x8.bin', size=2) oled.show() time.sleep(0.2) led.value = not led.value         效果展示:           5.终极任务二:使用外部存储器,组建简易FTP文件服务器,并能正常上传下载文件。         核心代码: from ftp_server import ftp from sys import exit import time import board import busio as io import digitalio import adafruit_ssd1306 import adafruit_ntp import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket from w5500 import w5500 #初始化网卡 eth=w5500() socket.set_interface(eth) # my_ftp_server = ftp(socket, eth.ip,authlist={'usr1':123,'usr2':'abc'},verbose=True) my_ftp_server = ftp(socket, eth.ip,path="/ftp/",verbose=True) # my_ftp_server = ftp(socket, eth.ip,verbose=True) print(my_ftp_server) while True: # Customise your condition. print(f"polling:{my_ftp_server.poll()}") # my_ftp_server.serve() # This will run forever   效果展示:     cpy环境下ftp服务器的被动模式一直未能成功,但是命令模式可以运行并传输文件,默认会下载至windows用户名文件夹:             三、任务源码 https://download.eeworld.com.cn/detail/eew_UPQWC7/631393 补充内容 (2024-3-2 18:04): 四、对本活动的心得体会 通过本次活动学习了circuit python、树莓派pico的基本使用,了解了tcp/udp网络通信的基本原理和使用方法,收获满满!感谢主办方与赞助方共同提供的活动机会,期待eeword与得捷的下次活动。

  • 上传了资料: Follow me 第4期任务代码

最近访客

现在还没有访客

< 1/0 >

统计信息

已有--人来访过

  • 芯积分:33
  • 好友:--
  • 主题:2
  • 回复:0

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言