qt开发上位机_WIFI DTU产品设计与实现(基于STM32F103+QT配置上位机案例设计分享)

27f2a46932161ca1aa7b5b3f7d54ff9c.png

1 、什么是 WIFI DTU?

1.1 、什么是 DTU ?

DTU (Data Transfer unit),是专门用于将串口数据转换为 IP 数据或将 IP 数据转换为串 口数据通过无线通信网络进行传送的无线终端设备。DTU 广泛应用于气象、水文水利、地质等行业。

1.2 、什么是 WIFI DTU?

使用 WIFI 模组,完成 DTU 的功能,就叫做 WIFI DTU,WIFI DTU 的实现难点在于配网以及后期多端口及多种协议和端口的适配。

前面我们也介绍过,其实通过文件系统ini文件改个参数也可以实现配网:

基于小熊派SD卡+Fatfs+移植开源iniparse解析库并使用

2 、WIFI DTU 市场调研

淘宝和京东上可以看到有类似的 WIFI DTU 产品:

c359ea207ded022bfbf0366092168f34.png

2e4f1ddada945096fe1b91506d432852.png

74f66df6ff6030a3a07b5ba1c3659214.png

c1465a14f7beb1dc6cab5701d474a2be.png

3 、WIFI DTU 实现方法

3.1 通过一个 MCU+ 一个 WIFI 模组的方式来实现

优点:

1、开发者只需熟悉使用 WIFI 模组的 AT 指令,使用一个 MCU 结合串口 AT 指令与 WIFI 模组 通信,编写软件即可完成 WIFI DTU 的功能,

2、MCU IO 扩展接口丰富,可以拓展实现多种接口的通信,完成更加复杂的 DTU 功能。

3、产品开发出来以后,如有多个拓展 IO,客户可自行根据需求进行二次开发,实现产品。

4、定好 MCU 端的协议,无论后期模组怎么变,一套好的通信协议即可兼容所有模组。

缺点:

1、成本高昂,对于单一只需要与服务器建立连接,发送数据到服务器的需求不太友好,这 样等于把事情复杂化了,硬件成本也相对增加了。

2、需要自行开发配网的上位机或者手机 APP,时间成本增加。

3.2 通过支持二次开发的 WIFI 模组的方式来实现。

优点:

1、成本低廉,因为只有一个模组,极限的利用模组本身的 SDK 即可完成功能需求的开发。

2、通常模组厂已经支持相应的配网协议,可通过手机 app,微信小程序,网页实现配网,模组厂支持力度大,技术也非常成熟。

缺点:

1、对于初学或者无模组 SDK 经验的开发者来说不太友好,正所谓专业的人做专业的事,想 要随时上手任何一款通信模组的 SDK 短时间内很难上手,模组的SDK 多种多样,有用C语言开发的,有用 C++开发的,Lua 语言开发的等等,复杂多化。

2、对于模组 IO 管脚本身就少的来说,拓展其它功能就不太适合了,更别说二次开发。

3、产品更新迭代快,可能你现在用的是这个模组,过一段时间,另一个模组又出来了,如果客户有需求换产品,这时候要做功能迁移,由于模组 SDK 千变万化,开发者也得适应这种规律。

4 市场上常见WIFI DTU的功能

4.1 斐悦极限无线wifi串口服务器

17cd73d9debe3eb088f305b76334cf9f.png

4.2 常见上位机软件配置功能

afed9ad7b160efdb28f226e12300739a.png

9ae8d26e68ac1382320f20b5003e6f29.png

5、简单小型WIFI DTU设计与实现

5.1 小型WIFI DTU外观及硬件设计

很早之前就做了一些超级简单的小型WIFI DTU,现在就把它开源出来分享给大家,如下图所示,这就是我们设计的DTU。

6e3e3d479f4c4704429c376335eaa30b.png

此处附上其中一个Demo板子ESP32版本的原理图:

2622d36912c0ad7532577c621a622192.png

5.2 小型WIFI DTU与上位机通信协议制定

5.2.1 WIFI模式设置

ac6c28461a29d61f053aceb53543640a.png

5.2.2 WIFI 连接AP指令设置与查询

297f01aae5154696abb7c4ab869957e2.png

5.2.3 WIFI 一键配置SoftAP参数指令设置与查询

40b780d7bc7c86c19bd03567e78b6ddb.png

5.2.4 WIFI 建立TCP链接,UDP传输或SSL连接指令设置与查询

429bf8e14781ddce70edf62e06b96c39.png

5.2.5 WIFI 模组一键配置参数设置及查询

cfa7d2784e8eb5b4b3ce1135dc0be5db.png

5.3 小型WIFI DTU软件设计

5.3.1 STM32CubeMX工程配置

4a9980130fcd5cbc34f14532cbbe408f.png

由于配置参数过多,限于篇幅限制,这里就不贴出来了,见文章最后回复关键字自行下载,谢谢谅解!

5.3.2 软件设计思路

系统初始化以后会读取FLASH,获取配置前透传的设置并打印

struct 	Upper_Variable 		 Upper_Val;
struct  Upper_WFVariable 	 Upper_ESP32Val;
/******************************************************************************************************************************************************************************
** 函数名:void   DTU_ReadFlash_SetData(struct Upper_WFVariable *Upper_WFVal)
** 功能描述:获取配置前透传的设置并打印
** 输入参数:	Upper_WFVal   存储结构体
** 输出参数:无

** 返回:无
*******************************************************************************************************************************************************************************/
void   DTU_ReadFlash_SetData(void)
{
    memset(ESP32_FlashReadTest, 0, sizeof(ESP32_FlashReadTest));
    Flash_ReadData(SetDebug_Add, ESP32_FlashReadTest);
    strcpy(Upper_Val.Upper_Debug, ESP32_FlashReadTest);
    if(strcmp("0", Upper_Val.Upper_Debug) == 0)
    {
        Debug_f = 0;
    }
    else if(strcmp("1", Upper_Val.Upper_Debug) == 0)
    {
        Debug_f = 1;
    }
    DTU_Flash_GetData(SetDebug_Add, Upper_Val.Upper_Debug, "Debug状态:");
    DTU_Flash_GetData(SetWFMode_Add, Upper_ESP32Val.Upper_SetWFMode, "WIFI模式:");

    DTU_Flash_GetData(SetWFJAP_SSID_Add, Upper_ESP32Val.Upper_SetWFJAP_SSID, "AP模式SSID:");
    DTU_Flash_GetData(SetWFJAP_PWD_Add, Upper_ESP32Val.Upper_SetWFJAP_PWD, "AP模式PWD:");

    DTU_Flash_GetData(SetWFSAP_SSID_Add, Upper_ESP32Val.Upper_SetWFSAP_SSID, "SoftAP模式SSID:");
    DTU_Flash_GetData(SetWFSAP_PWD_Add, Upper_ESP32Val.Upper_SetWFSAP_PWD, "SoftAPAP模式PWD:");

    DTU_Flash_GetData(SetWFCIPSTART_Type_Add, Upper_ESP32Val.Upper_SetWFCIPSTART_Type, "连接的模式:");
    DTU_Flash_GetData(SetWFCIPSTART_RemoteIP_Add, Upper_ESP32Val.Upper_SetWFCIPSTART_RemoteIP, "服务器端的IP:");
    DTU_Flash_GetData(SetWFCIPSTART_RemotePort_Add, Upper_ESP32Val.Upper_SetWFCIPSTART_RemotePort, "服务器端的端口号:");
}

这里的参数存储用结构体Upper_VariableUpper_WFVariable进行维护:

#define  Mode_L					2
#define  SSID_L					20
#define  PWD_L					20
#define  Type_L				        5
#define  RemoteIP_L			        100
#define  RemotePort_L		                10

struct Upper_Variable
{
    //模组设置模式
    uint8_t Upper_State;
    char  Upper_SetMode[Mode_L];	
    //模组品牌
    char  Upper_ModuleBrand[Mode_L];
    //Debug信息开关
    char  Upper_Debug[Mode_L];				
};

struct Upper_WFVariable
{
    //WIFI的模式设置
    char Upper_SetWFMode[Mode_L];				
    //WIFI的AP模式的SSID
    char Upper_SetWFJAP_SSID[SSID_L];
    //WIFI的AP模式的PWD
    char Upper_SetWFJAP_PWD[PWD_L];										
    //WIFI的SoftAP的SSID
    char Upper_SetWFSAP_SSID[SSID_L];
    //WIFI的SoftAP的PWD
    char Upper_SetWFSAP_PWD[PWD_L];										
    //字符串串参数,连接类型,"TCP","UDP" 或 "SSL"
    char Upper_SetWFCIPSTART_Type[Type_L];
    //字符串串参数,远端 IP 地址
    char Upper_SetWFCIPSTART_RemoteIP[RemoteIP_L];
    //IP地址的端口号
    char Upper_SetWFCIPSTART_RemotePort[RemotePort_L];	
};
//建立ESP32结构体和ESP8266结构体;
extern  struct  Upper_WFVariable 	 Upper_ESP32Val;		

WIFI DTU主要有以下模式

/**********************
DTU状态列表
**********************/
enum   DTU_State_List
{
        //系统空闲模式
	DTU_FreeMode = 0,
        //系统存储配置检测模式
	DTU_ConfigurationDetMode,	
        //系统配置设置模式
	DTU_ConfigurationSetMode,
        //系统透传模式
	DTU_PassthroughMode,
        //系统透传数据解析模式
	DTU_DataAnalysisMode,	
        //系统配置模式
	DTU_ConfigurationMode,	
        //系统错误模式
	DTU_ERRORMode,						
};

当用户长按按键时候,进入系统配置模式:

void key_L_CallBack(void)
{
    if(ESP32_STATE_D.ESP32_State != DTU_ConfigurationMode)	
    {
        ESP32_STATE_D.ESP32_State = DTU_ConfigurationMode;
    }

    DEBUG("按键长按rn");
}

系统配置模式:

/******************************************************************************************************************************************************************************
** 函数名:void   Upper_State_Dis(void)
** 功能描述:上位机配置状态机
** 输入参数:无
** 输出参数:无

** 返回:无
*******************************************************************************************************************************************************************************/
void   Upper_State_Dis(void)
{
    Upper_RX_Dis();
    Upper_Find_Dis(&Upper_Val);
    Upper_Set_Dis(&Upper_Val);

    switch(Upper_Val.Upper_State)
    {
        case	Upper_FreeMode:
            if(strcmp(Upper_Val.Upper_SetMode, "2") == 0)
            {
                Upper_Val.Upper_State = Upper_ESP32Mode;
                DEBUG("进入ESP32模式rn");
            }

            break;

        case		Upper_ESP32Mode:
            Upper_ESP32_ValDis(&Upper_ESP32Val);
            Upper_WFFind_ValDis(&Upper_ESP32Val);
            break;
    }

    Upper_S_bit.Upper_Byte = 0;
    memset(Upper_Rx_Buffer, 0, sizeof(Upper_Rx_Buffer));
}

系统配置模式对应的状态灯做如下处理:

系统状态对应LED灯
*********************************************************************/
if(ESP32_STATE_D.ESP32_State != DTU_ConfigurationMode)//系统空闲模式灯显示
{
    LED_SetColor(0, 1, 0);		//设置颜色为绿色
}
else if(ESP32_STATE_D.ESP32_State == DTU_ConfigurationMode)//系统配置模式灯显示
{
    LED_SetColor(0, 0, 1);		//设置颜色为蓝色
}
else if(ESP32_STATE_D.ESP32_State == DTU_PassthroughMode)//系统配置模式灯显示
{
    LED_SetColor(0, 1, 1);		//设置颜色为紫色
}

当用户短按按键时,进入系统存储配置检测模式,此时判断在系统初始化时读取FLASH的参数的参数,如果没有相应的参数,则用户需要长按按键切换到配置模式进行参数设置。

//系统存储配置检测模式
case DTU_ConfigurationDetMode:		
            DTU_STATE_D.DTU_ConfDep = ESP32_PassthroughDet(&Upper_ESP32Val);
            if(DTU_STATE_D.DTU_ConfDep == ESP32_OK)
            {
                DEBUG("检测到存储的配置信息齐全rn");

                ESP32_STATE_D.ESP32_SetModeState = TCP_Step0;

                ESP32_STATE_D.ESP32_State = DTU_ConfigurationSetMode;
            }
            else if(DTU_STATE_D.DTU_ConfDep == ESP32_ERR)
            {
                DEBUG("检测到存储的配置信息有空的rn");
                DEBUG("可以长按进入配置模式rn");
                DEBUG("配置成功后短按退出配置模式rn");
                DEBUG("退出配置模式后自动进入数据透传模式rn");
                ESP32_STATE_D.ESP32_State = DTU_ERRORMode;
            }
            break;

系统透传模式:

//系统透传模式
case DTU_PassthroughMode:					
            if(Uart1_Recv_End_Flag)
            {
                DEBUG("tx_len = %drn", Uart1_Rx_Len);			
                DEBUG("发送的数据:%srn", Uart1_Rx_Buffer);	
                Print(&huart2, "%s", Uart1_Rx_Buffer);
                Uart1_Rx_Len = 0;					//清除计数
                Uart1_Recv_End_Flag = 0;	//清除接收结束标志位
                memset(Uart1_Rx_Buffer, 0, sizeof(Uart1_Rx_Buffer));
            }

            if(Uart2_Recv_End_Flag)
            {
                //复位连接超时
                DTU_STATE_D.DTU_TCPLinkTimeOut = Set_TCPLinkTimeOut;		

                DEBUG("rx_len = %drn", Uart2_Rx_Len);					
                DEBUG("接收的数据:%srn", Uart2_Rx_Buffer);			

                Uart2_Rx_Len = 0;					
                Uart2_Recv_End_Flag = 0;	
                memset(Uart2_Rx_Buffer, 0, sizeof(Uart2_Rx_Buffer));
            }

            if(!DTU_STATE_D.DTU_TCPLinkTimeOut)		
            {
                DTU_STATE_D.DTU_TCPLinkCnt ++;
                memset(&ESP32_S_bit, 0, sizeof(ESP32_S_bit));						
                memset(ESP32_Rx_Buffer, 0, sizeof(ESP32_Rx_Buffer));		
                memset(Uart2_Rx_Buffer, 0, sizeof(Uart2_Rx_Buffer));		
                if(DTU_STATE_D.DTU_TCPLinkCnt != Set_TCPLinkCnt)
                {
                    ESP32_STATE_D.ESP32_State = DTU_ConfigurationDetMode;
                }
                else
                {
                    Print(&huart2, "+++");
                    HAL_Delay(200);
                    Print(&huart2, "AT+CIPCLOSErn");
                    HAL_Delay(200);
                    memset(&DTU_STATE_D, 0, sizeof(DTU_STATE_D));						
                    ESP32_STATE_D.ESP32_State = DTU_ERRORMode;
                }
            }
            break;

由于当初特殊原因导致项目没有继续完成下去,所以有几个模式没有实现,但该DTU已经可以实现简单的透传功能了,有兴趣的小伙伴可以自行添加完善这个项目。

上位机配置(基于QT5实现)

由于WIFI DTU的项目是我们之前工作之余在朱友鹏老师指导下实现的,故名为鹏力云,鹏力是指的深圳鹏力电子,云指的是深圳云之手科技,后续我将会在小熊派上将这个STM32版本和QT上位机重新进行整合后发布。

82f057b241c87b9208d68125caf459bd.png

感兴趣的小伙伴可自行下载代码编译,与DTU硬件进行联调。

5601f6b0960b7d469a1a27903bb4917a.png

29a2010c69b5cda983c816e5919ed283.png

860dbc5cc26b2c25c1de1a3333b6052a.png

b06a5219d9b7735cefb60ff502a13852.png

开源项目资料下载

关注公众号"嵌入式云IOT技术圈"后台回复:DTU 即可获取下载链接。

知乎粉丝福利时刻

这里我给大家申请到了福利,本公众号读者购买小熊派开发板可享受9折优惠,有需要购买小熊派的朋友,淘宝搜索即可,跟客户说你是公众号:嵌入式云IOT技术圈 的粉丝,立享9折优惠!

往期精彩

分享一个近期开源火爆全网的额温枪方案(硬件+源码)

火爆全网开源额温枪同平台之华大HC32L136 SDK开发入门

深圳云之手科技开源炫酷RGB灯板DIY项目

云之手红外式测温计产品设计分享(基于合泰BH67F2752方案)

STM32F103产品级开源项目:iLook.Time设计解读

若觉得本次分享的文章对您有帮助,随手点[在看]并转发分享,也是对我的支持。

4c73add4bb266aa7cc1b9d28fa749173.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值