注册个人网站,加盟网官方网站,做网站ps笔记本电脑,用net语言做网站平台好不好项目描述#xff1a;该系列记录了STM32G0EMW3080实现单片机智能联网功能项目的从零开始一步步的实现过程#xff1b;硬件环境#xff1a;单片机为STM32G030C8T6#xff1b;物联网模块为EMW3080V2-P#xff1b;网联网模块的开发板为MXKit开发套件#xff0c;具体型号为XCH… 项目描述该系列记录了STM32G0EMW3080实现单片机智能联网功能项目的从零开始一步步的实现过程硬件环境单片机为STM32G030C8T6物联网模块为EMW3080V2-P网联网模块的开发板为MXKit开发套件具体型号为XCHIP MXKit-Base V2.2软件环境STM32需要的软件有STM32CubeMX和STM32CubeIDE开发IDE为eclipseMXKit的串口调试工具使用的是putty.exe串口指令串口指令使用的是AT指令 通信方式使用的是UART项目过程本项目采用模块化的形式一步步的实现STM32G0EMW3080阿里云实现单片机智能联网功能第一步先使用MXKit开发板和PC进行通信第二步是配置阿里云飞燕平台第三步是MXKit开发板实现配网功能MXKit和阿里云之间成功通讯第四步是STM32G0单片机实现和EMW3080的串口通讯第五步是测试整体的功能 本节为该项目的第四节主要任务是实现STM32G030C8T6控制EMW3080实现IoT功能即STM32G030C8T6控制EMW3080实现配网、断网重连、以及数据的下发、app控制设备等最终的结果是单片机上电后向EMW3080发送配网指令配网成功后在云智能app端下发指令能够控制单片机上的LED等开和关当然也支持wifi断开重连等功能
经过上一篇文章STM32G0EMW3080阿里云飞燕平台实现单片机WiFi智能联网功能三EMW3080完成配网EMW3080连接到阿里云飞平台通过串口调试EMW3080已经能成功的进行配网了所以我们现在要做的就是让STM32G030C8T6来发送配网指令完成EMW3080的配网过程并且在完成配网后可以向STM32G030C8T6发送和接收数据用于控制设备 文章目录 一、硬件连接二、代码实现笔记 一、硬件连接
STM32G030C8T6和EMW3080的连接原理图如下图所示
其中使用STM32G030C8T6的UART1串口接到EMW3080的UART串口上接线如上图所示然后STM32G030C8T6通过STLINK或JLINK连接到电脑上便于调试和烧写程序EMW3080开发板通过自带电源线也连接到电脑的USB端口上用于供电这样接线部分就接好了 需要注意的是STM32G030C8T6我是用的是USART1EMW3080开发板上有“UART”和“DEBUG”两个区域都由RX和TX
我们需要使用UART区域中的RX和TX而不是DEBUG中的如果不小心使用了DEBUG中的RX和TX指令虽然也能发送到EMW3080但是无法识别
接线完成后实物图如下所示 二、代码实现
接下来就是在STM32G030C8T6中编写代码实现向EMW3080发送AT指令进行配网并根据返回的信息判断是否配网成功待配网成功后STM32G030C8T6接收云端发下来的指令并进行响应的控制本代码示例中通过下发LED等开和关的指令控制STM32上的灯亮和灭
整个工程的代码可以从以下链接中下载https://download.csdn.net/download/AnChenliang_1002/88511568
下载后的资源可以直接用STM32CubeIDE运行
下面大致讲解一下代码结构 主要的源文件如上图所示其中我们IoT的功能主要在wilo_wifiMoudule.c中实现
附上wilo_wifiMoudule.c的完整代码
#include wilo_wifiModule.h#include wilo_uart.h#define DISCONNECT_TRUE 1
#define DISCONNECT_FALSE 0extern UART_HandleTypeDef huart1;
extern uint8_t rxBuffer[128];
extern __IO uint8_t receivedIndex;//跟踪接收到的字符的索引
extern uint8_t stringMatched ;//是否接收到完整的字符串
extern uint8_t receivedData[128]; // 全局数组用于存储完整接收到的内容
extern __IO uint8_t receivedLength; // 当前接收到的数据长度,为0时表示未收到数据大于0时表示收到了数据
extern uint8_t preReceivedLength;//前一次接收到的数据长度
extern const char* atCommands[] ;// 声明一个设备参数变量
DeviceParameters deviceParams;void reset_receive()
{// 重置接收索引准备接收下一段内容receivedIndex 0;stringMatched 0;receivedLength 0;preReceivedLength 0;memset(receivedData,0,sizeof(receivedData));
}// 发送指令并等待回复函数
HAL_StatusTypeDef sendCommandAndWait(const char* command, const char* expectedReply)
{// 发送指令HAL_UART_Transmit_IT(huart1, (uint8_t*)command, strlen(command));// 接收回复HAL_UART_Receive_IT(huart1, rxBuffer[receivedIndex], 1); while((0 receivedLength))//如果还未接收到数据一直等待;直到收到数据{OLED_ShowString(0,4,wait response);}//HAL_UART_Transmit_IT(huart1, (uint8_t*)wait!!!!\r\n, 10);//OLED_Clear();//OLED清零while(0 stringMatched )//如果还没有接收完所有数据,一直等待直到接收完所有数据{ReceivedAll();//判断是否接收完所有字符串了}//HAL_UART_Transmit_IT(huart1, (uint8_t*)111\r\n, 5);//HAL_Delay(1000);//HAL_UART_Transmit_IT(huart1, (uint8_t*)received\r\n, 10);OLED_Clear();//OLED清零OLED_ShowString(0,4,received:);OLED_ShowString(80,4,(u8 *)receivedData);// 延时3秒//HAL_Delay(3000);//replyBuffer receivedData;if (strstr((const char *)receivedData, expectedReply) ! NULL){// 重置接收准备接收下一段内容reset_receive();// 收到期望的回复return HAL_OK;}// 重置接收准备接收下一段内容reset_receive(); return HAL_ERROR;
}
#if 0
//等待wifi配网成功
HAL_StatusTypeDef WaitConnected()
{//uint32_t startTime HAL_GetTick();//uint32_t elapsedTime 0;int Connected 0;//是否配网完成// 持续等待回复直到收到配网成功的回复当TimeOut_flag为2时说明超时了while ( 1 ! Connected){HAL_UART_Receive_IT(huart1, rxBuffer[receivedIndex], 1);if(0 stringMatched)//还未接收到数据一直等待{OLED_Clear();//OLED清零OLED_ShowString(0,4,000 wait Connect);// 延时3秒//HAL_Delay(3000);while( stringMatched 0){ReceivedAll();//判断是否接收完所有字符串了}}if(1 stringMatched){OLED_Clear();//OLED清零OLED_ShowString(0,0,received:);OLED_ShowString(80,0,(u8 *)receivedData);// 延时3秒HAL_Delay(3000);if (strstr(receivedData, ILOPEVENT:ILOP,CONNECTED) ! NULL){OLED_Clear();//OLED清零OLED_ShowString(0,4,Connect OK);// 延时3秒//HAL_Delay(3000);// 重置接收准备接收下一段内容reset_receive();Connected 1;return HAL_OK;//配网成功}// 重置接收准备接收下一段内容reset_receive();}// 更新经过的时间//elapsedTime HAL_GetTick() - startTime;}return HAL_TIMEOUT;
}
#endif//等待wifi配网成功
HAL_StatusTypeDef WaitConnected()
{//uint32_t startTime HAL_GetTick();//uint32_t elapsedTime 0;OLED_Clear();//OLED清零OLED_ShowString(0,4, waiting Connect);int Connected 0;//是否配网完成// 持续等待回复直到收到配网成功的回复当TimeOut_flag为2时说明超时了while ( 1 ! Connected){HAL_UART_Receive_IT(huart1, rxBuffer[receivedIndex], 1);if(0 ! receivedLength)//收到数据了{//OLED_Clear();//OLED清零//OLED_ShowString(0,4,000 wait Connect);// 延时3秒//HAL_Delay(3000);while( stringMatched 0)//判断是否接收完数据如果未接收完则一直循环直到接收完{ReceivedAll();//判断是否接收完所有字符串了}OLED_Clear();//OLED清零OLED_ShowString(0,0,received:);OLED_ShowString(80,0,(u8 *)receivedData);// 延时3秒//HAL_Delay(3000);if (strstr((const char *)receivedData, ILOPEVENT:ILOP,CONNECTED) ! NULL){OLED_Clear();//OLED清零OLED_ShowString(0,4,Connect OK);// 延时3秒//HAL_Delay(3000);// 重置接收准备接收下一段内容reset_receive();Connected 1;return HAL_OK;//配网成功}// 重置接收准备接收下一段内容reset_receive();}}return HAL_TIMEOUT;
}// 进入WiFi配网过程的函数
HAL_StatusTypeDef WiFiConfigInit()
{HAL_StatusTypeDef status;// 发送指令 AT直到收到的回复是OKstatus sendCommandAndWait(atCommands[0], OK);while (status ! HAL_OK){OLED_Clear();//OLED清零OLED_ShowString(0,4,AT Not OK);status sendCommandAndWait(AT\r\n, OK);}OLED_Clear();//OLED清零OLED_ShowString(0,4,AT OK);// 延时10秒//HAL_Delay(10000);// 发送指令 ATILOPAWSAP\r\nstatus sendCommandAndWait(ATILOPAWSAP\r\n, OK);while (status ! HAL_OK){OLED_Clear();//OLED清零OLED_ShowString(0,4,SWAP Not OK);status sendCommandAndWait(ATILOPAWSAP\r\n, OK);}OLED_Clear();//OLED清零OLED_ShowString(0,4,SWAP OK);// 延时10秒//HAL_Delay(10000);if(HAL_OK WaitConnected()){OLED_Clear();//OLED清零OLED_ShowString(0,4,Connect OK);}else{OLED_Clear();//OLED清零OLED_ShowString(0,4,Connect TimeOut);return HAL_TIMEOUT;}// 配网成功return HAL_OK;
}void DeviceInit()
{deviceParams.powerState 0;
}
/*判断wifi是否断开返回DISCONNECT 表示wifi断开返回CONNECT表示wifi处于连接状态*/
uint8_t wifi_isDisconnected()
{uint8_t disConnected DISCONNECT_FALSE;//默认没有断开if (strstr((const char *)receivedData, ILOPEVENT:ILOP,CONNECTING) ! NULL){OLED_Clear();//OLED清零OLED_ShowString(0,4,wifi disconnect );// 延时3秒//HAL_Delay(3000);// 重置接收准备接收下一段内容reset_receive();disConnected DISCONNECT_TRUE;//wifi断开} return disConnected;
}void wifi_task()
{HAL_UART_Receive_IT(huart1, rxBuffer[receivedIndex], 1);//if(0 stringMatched)//还未接收到数据一直等待if(0 ! receivedIndex)//说明接收到消息了{//OLED_ShowString(0,4,Recive date begin);// 延时3秒//HAL_Delay(3000);while( 0 stringMatched){ReceivedAll();//判断是否接收完所有字符串了}OLED_Clear();//OLED清零OLED_ShowString(0,0,received:);OLED_ShowString(80,0,(u8 *)receivedData);// 延时3秒//HAL_Delay(3000);if(DISCONNECT_TRUE wifi_isDisconnected())//如果wifi断开了{OLED_Clear();//OLED清零OLED_ShowString(0,4,wifi DisConnect );// 延时3秒//HAL_Delay(3000); //while(HAL_OK ! WaitConnected());WaitConnected();//等待wifi重连成功OLED_Clear();//OLED清零OLED_ShowString(0,4,wifi recover );// 延时3秒//HAL_Delay(3000); }else{OLED_Clear();//OLED清零OLED_ShowString(0,4,wifi parse Task );//HAL_Delay(3000);parseWiFiCommand((char *)receivedData);deviceControl();reset_receive(); }}{OLED_Clear();//OLED清零OLED_ShowString(0,4,wifi connect ); } }void parseWiFiCommand(const char* command)
{const char* keyword ILOPEVENT:SETJSON,property,;const char* powerstateKeyword \powerstate\:;const char* powerstateValue NULL;// 检查指令是否以关键字开头if (strncmp(command, keyword, strlen(keyword)) ! 0) {while(1){OLED_Clear();//OLED清零OLED_ShowString(0,4,error 1);}//return;}// 定位到powerstate关键字的位置powerstateValue strstr(command, powerstateKeyword);if (powerstateValue NULL) {while(1){OLED_Clear();//OLED清零OLED_ShowString(0,4,error 2);}//return;}// 解析powerstate的值powerstateValue strlen(powerstateKeyword);int powerstate *powerstateValue - 0;//将powerstateValue指针所指向的字符转换为整数并将结果存储在powerstate变量中。*powerstateValue表示取指针所指向的字符然后通过减去字符0的ASCII值实现将字符转换为对应的整数值。// 根据powerstate设置state的值if (powerstate 0) {deviceParams.powerState 0;} else if (powerstate 1) {deviceParams.powerState 1;} else {while(1){OLED_Clear();//OLED清零OLED_ShowString(0,4,error 3);}}
}void deviceControl()
{if(0 deviceParams.powerState)HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);//灯灭elseHAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);//灯亮
}// 发送数据
void sendWiFiData(const char* paramName, const char* paramValue) {// 构建发送数据的格式//sprintf(txBuffer, ILOPEVENT:SETJSON,%s,%d,{\%s\:%s}\r\n, paramName, strlen(paramValue), paramName, paramValue);// 在这里实现串口发送功能将txBuffer中的数据发送出去// 例如HAL_UART_Transmit(huart1, (uint8_t*)txBuffer, strlen(txBuffer), HAL_MAX_DELAY);
}笔记
记录几个开发中的细节
1、单片机向wifi模块发送指令 ATILOPAWSAP\r\n进行配网 2、当单片机收到wifi模块返回的信息中包含ILOPEVENT:ILOP,CONNECTED时说明配网成功 3、当单片机收到wifi模块返回的信息中包含ILOPEVENT:ILOP,CONNECTING时说明wifi已经断开正在重连 4、云端向EMW3080发送的控制指令也就是单片机需要解析的指令格式如下以参数“开关状态”为例
ILOPEVENT:SETJSON,property,16,{powerstate:0}
ILOPEVENT:SETJSON,property,16,{powerstate:1}