899|2

33

帖子

2

TA的资源

一粒金砂(中级)

楼主
 

【得捷Follow me第4期】项目总结 [复制链接]

 

一、前言(含视频)

        本次Follow Me 4共分为4个任务:入门任务,基础任务,进阶任务和终极任务,其中,基础任务分为两个小任务,所以共六个任务,都顺利完成。

        并且已经将内容一的视频上传至网络大学堂,视频地址为:https://training.eeworld.com.cn/video/39296 ;视频里包含了各任务的现场烧录演示及说明。

 

        任务完成所用开发环境为Paspberry Pi的Pico SDK v1.5.1+VSCode;其中VSCode不多赘述,而Paspberry Pi的Pico SDK v1.5.1的下载地址为 

链接已隐藏,如需查看请登录或者注册
,安装过程可参考 WIZnet W5500-EVB-Pico树莓派入门教程(一)-CSDN博客

 

        任务完成所用硬件如下几个:W5500-EVB-Pico(必购);Pico-LCD 1.14(用于大部分的显示任务);AtomS3(W5500-EVB-Pico在做FTP服务器时,读取SD卡需要用的SPI,导致无法使用Pico-LCD做显示,通过UDP传输显示数据给AtomS3,用AtomS3做显示);SEEED XIAO ESP32 C3(测试W5500-EVB-Pico的UDP Server功能)、DAPLink一个(自备,用于在线仿真,方便调试网络)以及自己绘制的LCD转接板一个,方便给将W5500-EVB-Pico主板与Pico-LCD组合起来,转接板如下:

图1-1

        下面将各任务逐一介绍并展示(内容二)。

二、入门任务

    2.1 任务介绍

        搭建开发环境,点亮小灯让其闪烁,并在显示屏上显示内容。

    2.2 主要代码片段

        LCD的显示主要靠移植Pico-LCD的官方驱动,其下载地址为

将其C驱动部分复制至工程目录下,并改名为LCD,在工程目录下的CMake中添加如下命令:

        并在项目目录下的CMake中添加如下命令:

        这样即包含了Pico-LCD的驱动库,初始化后就可直接显示输入内容,初始化过程如下:

  • DEV_Module_Init();
  • DEV_SET_PWM(30);
  • LCD_1IN14_V2_Init(HORIZONTAL);
  • LCD_1IN14_V2_Clear(BLACK);
  • UDOUBLE Imagesize = LCD_1IN14_V2_HEIGHT*LCD_1IN14_V2_WIDTH*2;
  • BlackImage = (UWORD *)malloc(Imagesize);
  • Paint_NewImage((UBYTE *)BlackImage,LCD_1IN14_V2.WIDTH,LCD_1IN14_V2.HEIGHT, 0, BLACK);
  • Paint_SetScale(65);
  • Paint_SetRotate(ROTATE);
  • Paint_Clear(BLACK);
  • LCD_1IN14_V2_Display(BlackImage);

        之后在Paint_DrawString_EN函数中输入字符串数组,显示坐标即可显示相应内容。

        小灯的闪烁代码如下:

  • const uint LED_PIN = PICO_DEFAULT_LED_PIN;
  • gpio_init(LED_PIN);
  • gpio_set_dir(LED_PIN, GPIO_OUT);
  • while (true) {
  • gpio_put(LED_PIN, 1);
  • sleep_ms(250);
  • gpio_put(LED_PIN, 0);
  • sleep_ms(250);
  • }

    2.3 功能展示

图2-1 驱动显示屏(显示屏通过转接板叠加在主控板上)
图2-2 BLink

 

 

三、基础任务一

    3.1 任务介绍

        主板W5500-EVB-Pico获取静态IP,并且PC能够ping通,同时主板可以ping通外网;PCping通结果抓包显示。

    3.2 主要代码片段

        需要用到W5500的官方库,其地址为https://gitee.com/wiznet-hk/w5500-evb-pico-routine.git

        随后如同上述LCD添加入库,即可调用相关函数即可实现静态IP:只要初始化W5500完成,再设置网络信息,标记为静态获取即可。

  • // 网络信息 默认静态
  • wiz_NetInfo net_info = {
  • .mac = {0x00, 0x08, 0xdc, 0x1e, 0xed, 0x2e}, // Configured MAC address
  • .ip = {192, 168, 1, 31}, // Configured IP address
  • .sn = {255, 255, 255, 0}, // Configured subnet mask
  • .gw = {192, 168, 1, 1}, // Configured gateway
  • .dns = {8, 8, 8, 8}, // Configured domain address
  • };
  • // 初始化
  • wizchip_initialize();
  • sleep_ms(50);
  • wizchip_setnetinfo(&net_info);
  • print_network_information(get_info);

        想要ping通互联网,则是向特定的目的主机发送 ICMP(Internet Control Message Protocol 因特网报文控制协议)Echo 请求报文,核心代码如下:

  • void ping_auto(uint8_t s, uint8_t *addr)
  • {
  • uint8_t i;
  • int32_t len = 0;
  • uint8_t cnt=0;
  • for(i = 0; i<=3;i++)
  • {
  • sleep_ms(10);
  • switch(getSn_SR(s))
  • {
  • case SOCK_CLOSED:
  • close(s);
  • IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP);
  • if(socket(s,Sn_MR_IPRAW,3000,0)!=0)
  • { }
  • while(getSn_SR(s)!=SOCK_IPRAW);
  • sleep_ms(2000);
  • break;
  • case SOCK_IPRAW:
  • ping_request(s, addr);
  • req++;
  • sleep_ms(50);
  • while(1)
  • {
  • if ( (len = getSn_RX_RSR(s) ) > 0)
  • {
  • ping_reply(s, addr, len);
  • sleep_ms(50);
  • rep++;
  • break;
  • }
  • else if(cnt > 200)
  • {
  • printf( "Request Time out. \r\n");
  • cnt = 0;
  • break;
  • }
  • else
  • {
  • cnt++;
  • sleep_ms(50); /*wait 50ms*/
  • }
  • // wait_time for 2 seconds, Break on fail
  • }
  • break;
  • default:
  • break;
  • }
  • #ifdef PING_DEBUG
  • if(rep!=0)
  • {
  • printf("Ping Request = %d, PING_Reply = %d\r\n",req,rep);
  • if(rep == req)
  • printf( "PING SUCCESS\r\n " );
  • else
  • printf( "REPLY_ERROR\r\n " );
  • }
  • else{}
  • #endif
  • }
  • }

    3.3 功能展示

图3-1 PC端Ping主板成功图
图3-2 主控板Ping互联网成功串口输出图
 

  四、基础任务二

    4.1 任务介绍

         主板W5500-EVB-Pico做UDP服务器,并能将PC端的UDP客户端发送内容显示在显示屏上,再抓包对比报文。同时使用SEEED XIAO ESP32 C3做UDP客户端进行测试。

    4.2 核心代码片段

         正常初始化网络即可,UDP主要涉及Socket,包含头文件 #include "socket.h" 即可,然后轮询状态(判断是否有数据传输等)即可,代码如下:

  • int32_t udps_2(uint8_t sn, uint8_t* buf, uint16_t port)
  • {
  • int32_t ret;
  • uint16_t size, sentsize;
  • uint8_t destip[4];
  • uint16_t destport;
  • switch(getSn_SR(sn))
  • {
  • case SOCK_UDP :
  • if((size = getSn_RX_RSR(sn)) > 0)
  • {
  • if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
  • ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport);
  • buf[ret]=0x00;
  • // printf("recv from[%d.%d.%d.%d][%d]: %s\n", destip[0],destip[1],destip[2],destip[3],destport,buf);
  • sprintf(RecvIP[RecvCnt], "> %d.%d.%d.%d:%d", destip[0],destip[1],destip[2],destip[3],destport);
  • sprintf(RecvBuf[RecvCnt], "> %s", buf);
  • ddebug(RecvIP[RecvCnt]);
  • ddebug(RecvBuf[RecvCnt]);
  • if(++RecvCnt >= 10) RecvCnt = 0;
  • if(ret <= 0)
  • {
  • return ret;
  • }
  • size = (uint16_t) ret;
  • sentsize = 0;
  • while(sentsize != size)
  • {
  • ret = sendto(sn, buf+sentsize, size-sentsize, destip, destport);
  • if(ret < 0)
  • {
  • return ret;
  • }
  • sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
  • }
  • }
  • break;
  • case SOCK_CLOSED:
  • if((ret = socket(sn, Sn_MR_UDP, port, 0x00)) != sn)
  • return ret;
  • printf("local port:%d\n",port);
  • break;
  • default :
  • break;
  • }
  • return 1;
  • }

    4.3 成果展示

          先是用PC端的UDP(192.168.1.22:3333)发送Follow Me 4!到到主控板(192.168.1.31:8000),并用WireShark抓包(过滤条件为<ip.addr == 192.168.1.31 and udp>),显示如下:

图4-1 PC和主控板UDP通信抓包显示

           再用SEED XIAO ESP32C3做UDP的客户端(192.168.1.45:8000)去测试主控板的UDP服务器功能,每3秒发送一次Follow Me 4!;同时通过显示屏展示收到的内容,完成情况如下:

图4-2 主控板显示屏显示UDP接收内容(包含主机和XIAOESP32C3)

 

五、进阶任务

    5.1 任务内容 

          从NTP服务器同步时间,获取时间送显示屏显示。

    5.2 核心代码片段

          本质上还是UDP,这里选择用tx的NTP服务器,测试期间其地址为106.55.184.199;NTP及格式解析核心代码如下:

  • // NTP
  • int8_t SNTP_run(datetime *time)
  • {
  • uint16_t RSR_len;
  • uint32_t destip = 0;
  • uint16_t destport;
  • uint16_t startindex = 40;
  • switch(getSn_SR(NTP_SOCKET))
  • {
  • case SOCK_UDP:
  • if ((RSR_len = getSn_RX_RSR(NTP_SOCKET)) > 0)
  • {
  • if (RSR_len > MAX_SNTP_BUF_SIZE) RSR_len = MAX_SNTP_BUF_SIZE;
  • recvfrom(NTP_SOCKET, data_buf, RSR_len, (uint8_t *)&destip, &destport);
  • get_seconds_from_ntp_server(data_buf,startindex);
  • time->yy = Nowdatetime.yy;
  • time->mo = Nowdatetime.mo;
  • time->dd = Nowdatetime.dd;
  • time->hh = Nowdatetime.hh;
  • time->mm = Nowdatetime.mm;
  • time->ss = Nowdatetime.ss;
  • ntp_retry_cnt=0;
  • close(NTP_SOCKET);
  • return 1;
  • }
  • if(ntp_retry_cnt<0xFFFF)
  • {
  • if(ntp_retry_cnt==0)//first send request, no need to wait
  • {
  • sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
  • ntp_retry_cnt++;
  • }
  • else // send request again? it should wait for a while
  • {
  • if((ntp_retry_cnt % 0xFFF) == 0) //wait time
  • {
  • sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port);
  • ntp_retry_cnt++;
  • }
  • }
  • }
  • else //ntp retry fail
  • {
  • ntp_retry_cnt=0;
  • close(NTP_SOCKET);
  • }
  • break;
  • case SOCK_CLOSED:
  • socket(NTP_SOCKET,Sn_MR_UDP,ntp_port,0);
  • break;
  • }
  • return 0;
  • }
  • // 送显示
  • sprintf(time_str[count], "> %d-%02d-%02d %02d:%02d:%02d", time.yy, time.mo, time.dd, time.hh, time.mm, time.ss);
  • ddebug(time_str[count]);

    5.3 成果展示

           NTP实验内容较好展示,直接百度上搜索北京时间,然后对比即可,显示每1s才刷新一次,会存在误差,对比如下:

图5-1 左为浏览器显示北京时间 右为主控板每秒输出时间
 

六、最终任务

    6.1 任务内容

          使用外部SD卡存储器,组建简易FTP文件服务器,并能正常上传下载文件。同时因SD卡需占用一路SPI,故舍弃LCD,采用UDP传输给AtomS3用于显示FTP服务器相关内容。

    6.2 核心代码片段

          主要是SD卡和FatFs的移植,有现成的库,地址为 

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

          设置静态IP,并修改并记住FTP的ID和密码,再开启Fatfs功能,需要修改部分代码,主要添加两个接口函数,scan_files和get_filesize,分别是扫描和获取大小,内容如下

  • long get_filesize(const char *dirPath, const char *filename) {
  • char fullPath[256]; // 假设路径长度不超过255个字符
  • FILINFO fno;
  • FRESULT fr;
  • // 构造完整路径
  • snprintf(fullPath, sizeof(fullPath), "%s/%s", dirPath, filename);
  • // 使用 f_stat 获取文件信息
  • fr = f_stat(fullPath, &fno);
  • if (fr == FR_OK) {
  • return (long)fno.fsize; // 返回文件大小
  • } else {
  • return -1; // 发生错误,返回 -1
  • }
  • }
  • FRESULT scan_files (
  • char *path, /* Start node to be scanned (***also used as work area***) */
  • char *files,
  • uint16_t *num)
  • {
  • FRESULT res;
  • DIR dir;
  • UINT i;
  • static FILINFO fno;
  • uint16_t _num = 0;
  • *num = 0;
  • res = f_opendir(&dir, path); /* Open the directory */
  • if (res == FR_OK) {
  • for (;;) {
  • res = f_readdir(&dir, &fno); /* Read a directory item */
  • if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
  • i = strlen(path);
  • uint8_t isdir = (fno.fattrib & AM_DIR);
  • char size[32];
  • sprintf(size, "%ld", (fno.fattrib & AM_DIR) ? 0 : fno.fsize);
  • files += sprintf(files, "%crwxr-xr-x 1 pomin pomin %s Jan 19 2024 %s\r\n", (fno.fattrib & AM_DIR) ? 'd' : '-', size, fno.fname);
  • _num++;
  • }
  • f_closedir(&dir);
  • }
  • *num = _num;
  • return res;
  • }

    6.3 成果展示

          PC端使用Filezilla做FTP客户端,W5500烧录代码后,使用Filezilla连接,地址为192.168.1.31,ID为DIgikey,密码为Followme4,端口不用选择,默认为21,连接成功,并能上传下载文件,上传过程截图如下:

图6-1 PC向W5500主控板传输图片(速度200K/s)

           虽说无法使用LCD了,但是怎么能没有显示屏呢?所以还用了AtomS3做UDP服务器,将W5500主控板通过UDP发送来的内容进行显示,当作W5500的显示屏,展示如下:

图6-2 AtomS3做主控板的显示器(演示中,上传了两张图片,下载了文本)

 

七、心得体会

        首先是学到了不少东西,接触了RP2040、W5500、ESP32,对Cmake、Ethernet、WIFI等都有了更深的理解,然后最大的感悟还是,没想到嵌入式开发还能如此简单,很多库都是别人写好的,而rp2040引脚又少,调用起来非常简单,觉得嵌入式就该往这个方向发展,更多耗费时间的还得是逻辑与算法。再者就是群里的大佬太多了,见识到了很多,自己仍需努力,向大佬看齐,最后当然是感谢得捷,感谢EEWORLD,谢谢你们提供了这个宝贵的机会,也希望今后多多出这些活动,也祝你们越来越好!

八、附件

       这里就是内容三了,已将全部源码打包并上传至:https://download.eeworld.com.cn/detail/Alohaq/631392 ;如果你也安装了Pico-sdk,那么只需要添加到pcio的vscode环境里,即可编译下载全部内容。

最新回复

Pico-LCD 1.14(用于大部分的显示任务),还是的带显示才能更高完成任务    详情 回复 发表于 2024-2-26 09:12
点赞 关注
 
 

回复
举报

6737

帖子

10

TA的资源

版主

沙发
 

Pico-LCD 1.14(用于大部分的显示任务),还是的带显示才能更高完成任务 

个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

回复

33

帖子

2

TA的资源

一粒金砂(中级)

板凳
 
秦天qintian0303 发表于 2024-2-26 09:12 Pico-LCD 1.14(用于大部分的显示任务),还是的带显示才能更高完成任务 

就最终任务无法使用Pico-LCD(基础任务静态IP那无需显示),因为SPI分给W5500和SD卡,没硬件SPI支持显示了,又不想软模拟,就用UDP传给AtomS3当显示了。

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条
ADI &文晔 探索季第一站,邀您在活动帖跟帖,ADI资深工程师将与您一道寻求解决之道! ...
春晚,最出圈当属穿着棉马甲跳秧歌的机器人”秧Bot”。
转手绢、飞手绢、变换队形,精准度和稳定性甚至超越人类,这背后少不了电机控制技术。

查看 »

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