標(biāo)題:
基于STM32單片機(jī)SIM800C的MQTT實(shí)現(xiàn)源碼
[打印本頁]
作者:
hg1234
時(shí)間:
2023-11-16 11:02
標(biāo)題:
基于STM32單片機(jī)SIM800C的MQTT實(shí)現(xiàn)源碼
#include "./sys/sys.h"
#include "./delay/delay.h"
#include "./usart/usart.h"
#include "./LED/led.h"
#include "./LCD/lcd.h"
#include "./KEY/key.h"
#include "./RTC/rtc.h"
//#include "./RTC/bsp_rtc.h"
#include "./BEEP/beep.h"
#include "usmart.h"
#include "malloc.h"
#include "./SDIO/sdio_sdcard.h"
#include "./W25QXX/w25qxx.h"
#include "./src/ff.h"
#include "./exfuns/exfuns.h"
#include "text.h"
#include "piclib.h"
#include "./TOUCH/touch.h"
#include "./USART2/usart2.h"
#include "./USART3/usart3.h"
#include "./MPU6050/mpu6050.h"
#include "sim800c.h"
#include "./gps.h"
#include "./OV7670/ov7670.h"
#include "./NRF24L01/24l01.h"
#include "./TIMER/timer.h"
//#include "./OV7670/sccb.h"
#include "./OV2640/ov2640.h"
#include "MQTTPacket.h"
#include "StackTrace.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
#include "./T9INPUT/t9input.h"
#include "stdarg.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* 私有變量 ------------------------------------------------------------------*/
FATFS mfs; /* FatFs文件系統(tǒng)對(duì)象 */
FIL mfile; /* 文件對(duì)象 */
FRESULT mf_res; /* 文件操作結(jié)果 */
char mfpath[] = "0:TEXT"; /* 保存當(dāng)前掃描路徑 */
BYTE WriteBuffer[100] = "歡迎使用智能終端\r\n";
UINT file_num;
nmea_msg gpsx; //GPS信息
const u8 *port = (u8 *)"1883"; //端口固定為1883
const u8 *ipaddr = (u8 *)"118.190.146.251";
typedef struct
{
float temp[3];
float humi[3];
float gps[3];
uint8_t door[4];
short mpu[6];
}menu_message,*menu_message_;
uint16_t screen_w = 800; //屏幕寬度
uint16_t screen_h = 480; //屏幕高度
uint8_t line_w = 3; //分界線寬
uint8_t menu_num = 4; //菜單組數(shù)
uint8_t cur_menu_item,old_menu_item; //當(dāng)前菜單
uint8_t tmp_buf[33]; //NRF緩存
u8 mqtt_msg[200]={0}; //MQTT消息包緩存
u16 len; //消息包有效長度
u8 gprs_tcp_flag; //TCP連接標(biāo)志
u8 mqtt_data_flag; //MQTT消息類型標(biāo)志
u8 send_data_flag; //發(fā)布消息標(biāo)志
u8 temp_data[] = "##################------000000000000"; //36字節(jié) MQTT消息內(nèi)容緩存
u8 message_type; //消息類型,區(qū)別TOPIC主題
u8 about_text_size = 24; //關(guān)于字體大小
u8* const Info_Show[13]=
{
"溫度1","溫度2","溫度3",
"濕度1","濕度2","濕度3",
"GPS經(jīng)度","GPS緯度",
"車門信息","陀螺儀狀態(tài)",
"服務(wù)器IP","藍(lán)牙地址","閾值設(shè)置"
};
menu_message menu_mess;
//_t9_obj * t9in; //輸入法
//私有函數(shù)聲明
void sim800c_init(void); //SIM800C初始化
void gprs_send_data(u8 * data,u8 lenth); //GPRS發(fā)送數(shù)據(jù)
u8 *my_strstr(const u8 *s1,u16 n1,const u8 *s2,u16 n2); //字符串查找
void Start_Gprs_TCP(void); //GPRS建立TCP連接
void Stop_Gprs_Connect(void); //關(guān)閉GPRS連接
void Gps_Msg_Show(void); //顯示GPS定位信息
void send_model_temp_humi(menu_message * mes,u8 * space,u8 type); //MQTT發(fā)送內(nèi)容包裝
int main(void)
{
int sys_run_times=0;
unsigned char valtest=0;
u8 key,fontok=0;
u8 *p1,*p2,*p3;
u8 hbeaterrcnt=0; //心跳錯(cuò)誤計(jì)數(shù)器,連續(xù)5次心跳信號(hào)無應(yīng)答,則重新連接
// t9in = 0;
gprs_tcp_flag = 0;
mqtt_data_flag = 0;
send_data_flag = 0;
message_type = 0;
delay_init(); //延時(shí)函數(shù)初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置中斷優(yōu)先級(jí)分組為組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)
uart_init(115200); //串口初始化為115200
usmart_dev.init(72); //初始化USMART
GENERAL_TIMx_Configuration(); //通用定時(shí)器初始化:1ms中斷一次
LED_Init(); //初始化與LED連接的硬件接口
KEY_Init(); //初始化按鍵
LCD_Init(); //初始化LCD
BEEP_Init(); //蜂鳴器初始化
W25QXX_Init(); //初始化W25Q128
tp_dev.init(); //初始化觸摸屏
usart3_init(115200); //初始化串口3
my_mem_init(SRAMIN); //初始化內(nèi)部內(nèi)存池
exfuns_init(); //為fatfs相關(guān)變量申請(qǐng)內(nèi)存
f_mount(fs[0],"0:",1); //掛載SD卡
f_mount(fs[1],"1:",1); //掛載FLASH.
key=KEY_Scan(0);
if(key==KEY0_PRES&&((tp_dev.touchtype&0X80)==0))//強(qiáng)制校準(zhǔn)
{
LCD_Clear(WHITE); //清屏0
TP_Adjust(); //屏幕校準(zhǔn)
TP_Save_Adjdata();
LCD_Clear(WHITE); //清屏
}
fontok=font_init(); //檢查字庫是否OK
if(fontok||key==KEY1_PRES) //需要更新字庫
{
LCD_Clear(WHITE); //清屏
POINT_COLOR=RED; //設(shè)置字體為紅色
LCD_ShowString(60,50,200,16,16,(u8 *)"ALIENTEK STM32");
while(SD_Init()) //檢測(cè)SD卡
{
LCD_ShowString(60,70,200,16,16,(u8 *)"SD Card Failed!");
delay_ms(200);
LCD_Fill(60,70,200+60,70+16,WHITE);
delay_ms(200);
}
LCD_ShowString(60,70,200,16,16,(u8 *)"SD Card OK");
LCD_ShowString(60,90,200,16,16,(u8 *)"Font Updating...");
key=update_font(20,110,16,(u8 *)"0:"); //從SD卡更新
while(key) //更新失敗
{
LCD_ShowString(60,110,200,16,16,(u8 *)"Font Update Failed!");
delay_ms(200);
LCD_Fill(20,110,200+20,110+16,WHITE);
delay_ms(200);
}
LCD_ShowString(60,110,200,16,16,(u8 *)"Font Update Success!");
delay_ms(1500);
LCD_Clear(WHITE); //清屏
}
//RTC_CheckAndConfig(&systmtime);
RTC_Init(); //RTC初始化
delay_ms(1000);
RTC_Get();
printf("time:%02d-%02d-%02d.%02d:%02d:%02d\r\n",calendar.w_year%100,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);
init_gps();
NRF24L01_Init();
while(NRF24L01_Check()){;}
NRF24L01_RX_Mode();
LCD_Clear(BLACK);
key = 0;
piclib_init(); //初始化畫圖
//I2C初始化
i2c_CfgGpio();
//MPU6050初始化
MPU6050_Init();
//檢測(cè)MPU6050
// while(!MPU6050ReadID()){;}
while(sim800c_send_cmd((u8 *)"AT",(u8 *)"OK",100))//檢測(cè)是否應(yīng)答AT指令
{
Show_Str(40,55,200,16,(u8 *)"未檢測(cè)到模塊!!!",16,0);
delay_ms(800);
Show_Str(40,55,200,16,(u8 *)"嘗試連接模塊...",16,0);
delay_ms(400);
}
printf("SIM800C Check OK\r\n");
p1=mymalloc(SRAMIN,100); //申請(qǐng)100字節(jié)內(nèi)存
while(1)
{
if(NRF24L01_RxPacket(tmp_buf)==0)
{
printf("NRF24L01:%s\r\n",(char *)tmp_buf);
switch(tmp_buf[17])
{
case '0'://終端1
menu_mess.temp[0] = tmp_buf[19] == '+' ? ((tmp_buf[20] - '0') * 10 + (tmp_buf[21] - '0') * 1 + (tmp_buf[23] - '0') * 0.1 + (tmp_buf[24] - '0') * 0.01) : \
-((tmp_buf[20] - '0') * 10 + (tmp_buf[21] - '0') * 1 + (tmp_buf[23] - '0') * 0.1 + (tmp_buf[24] - '0') * 0.01);
if(tmp_buf[27] != '#')
menu_mess.humi[0] = (tmp_buf[27] - '0') * 10 + (tmp_buf[28] - '0') * 1;
break;
case '1'://終端2
menu_mess.temp[1] = tmp_buf[19] == '+' ? ((tmp_buf[20] - '0') * 10 + (tmp_buf[21] - '0') * 1 + (tmp_buf[23] - '0') * 0.1 + (tmp_buf[24] - '0') * 0.01) : \
-((tmp_buf[20] - '0') * 10 + (tmp_buf[21] - '0') * 1 + (tmp_buf[23] - '0') * 0.1 + (tmp_buf[24] - '0') * 0.01);
if(tmp_buf[27] != '#')
menu_mess.humi[1] = (tmp_buf[27] - '0') * 10 + (tmp_buf[28] - '0') * 1;
break;
case '2'://終端3
menu_mess.temp[2] = tmp_buf[19] == '+' ? ((tmp_buf[20] - '0') * 10 + (tmp_buf[21] - '0') * 1 + (tmp_buf[23] - '0') * 0.1 + (tmp_buf[24] - '0') * 0.01) : \
-((tmp_buf[20] - '0') * 10 + (tmp_buf[21] - '0') * 1 + (tmp_buf[23] - '0') * 0.1 + (tmp_buf[24] - '0') * 0.01);
if(tmp_buf[27] != '#')
menu_mess.humi[2] = (tmp_buf[27] - '0') * 10 + (tmp_buf[28] - '0') * 1;
break;
case '3'://終端4
menu_mess.door[0] = tmp_buf[19] == 0x17 ? 0x11 : 0x10;
break;
default :
break;
}
}
sys_run_times++;
if(gprs_tcp_flag == 17)
{
//構(gòu)建MQTT連接
switch(mqtt_data_flag)
{
case 0:
sim800c_send_cmd("AT+CIPSTATUS","OK",500); //查詢連接狀態(tài)
if(strstr((const char*)USART3_RX_BUF,"CONNECT OK"))
{
len=mqtt_connect_message(mqtt_msg,"STM32","admin","public");//id=123456,用戶名和密碼為空
gprs_send_data((u8 *)mqtt_msg,len);
delay_ms(600);
len=mqtt_subscribe_message(mqtt_msg,"home/temp",1,1); //訂閱test主題
gprs_send_data((u8 *)mqtt_msg,len);
printf("MQTT Connect and subscribe OK\r\n");
}
mqtt_data_flag = 1;
break;
case 1:
if(17 == send_data_flag)
{
MQTTString topicString = MQTTString_initializer;
RTC_Get();
send_model_temp_humi(&menu_mess,(u8 *)temp_data,message_type);
temp_data[24] = calendar.w_year%100/10+'0';
temp_data[25] = calendar.w_year%10+'0';
temp_data[26] = calendar.w_month%100/10+'0';
temp_data[27] = calendar.w_month%10+'0';
temp_data[28] = calendar.w_date%100/10+'0';
temp_data[29] = calendar.w_date%10+'0';
temp_data[30] = calendar.hour%100/10+'0';
temp_data[31] = calendar.hour%10+'0';
temp_data[32] = calendar.min%100/10+'0';
temp_data[33] = calendar.min%10+'0';
temp_data[34] = calendar.sec%100/10+'0';
temp_data[35] = calendar.sec%10+'0';
printf("數(shù)據(jù)發(fā)送中...\r\n"); //提示數(shù)據(jù)發(fā)送中
if(0 == message_type)
{
topicString.cstring = "L180309001/YY0118050001/Temp"; //發(fā)送的主題
}
else if(1 == message_type)
{
topicString.cstring = "L180309001/YY0118050001/EGps";
}
else if(2 == message_type)
{
topicString.cstring = "L180309001/YY0118050001/Gyro";
}
else if(3 == message_type)
{
topicString.cstring = "L180309001/YY0118050001/Door";
}
else if(4 == message_type)
{
topicString.cstring = "L180309001/YY0118050001/Point";
}
message_type++;
if(message_type>=5)
message_type = 0;
len = MQTTSerialize_publish(mqtt_msg, 200, 0, 0, 0, 0, topicString, (u8 *)temp_data, strlen((const char *)temp_data)); /* 2 */
gprs_send_data((u8 *)mqtt_msg,len);
printf("MQTT Send data OK\r\n");
send_data_flag = 0;GPIOB -> ODR ^= GPIO_Pin_5;
}
break;
}
if(USART3_RX_STA&0X8000) //接收到一次數(shù)據(jù)了
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0; //添加結(jié)束符
printf("%s",USART3_RX_BUF); //發(fā)送到串口
if(hbeaterrcnt) //需要檢測(cè)心跳應(yīng)答
{
if(strstr((const char*)USART3_RX_BUF,"SEND OK"))hbeaterrcnt=0;//心跳正常
}
p2=(u8*)strstr((const char*)USART3_RX_BUF,"+IPD");
if(p2) //接收到TCP/UDP數(shù)據(jù)
{
p3=(u8*)strstr((const char*)p2,",");
p2=(u8*)strstr((const char*)p2,":");
p2[0]=0; //加入結(jié)束符
sprintf((char*)p1,"收到%s字節(jié)",p3+1); //接收到的字節(jié)數(shù)
printf("%s\r\n",(char*)p1);
}
USART3_RX_STA=0;
}
}
else
{
Start_Gprs_TCP(); //創(chuàng)建TCP連接
}
if(17 == (sys_run_times%100))
{
menu_mess.gps[0] = (float)(gpsx.longitude/100000);
menu_mess.gps[1] = (float)(gpsx.latitude/100000);
menu_mess.gps[2] = (float)(gpsx.speed/1000);
send_data_flag = 17;
printf("Send flag OK\r\n");
hbeaterrcnt++;
printf("hbeaterrcnt:%d\r\n",hbeaterrcnt); //方便調(diào)試代碼
}
else if(27 == (sys_run_times%5000))
{
len = mqtt_ping_message(mqtt_msg); /* 2 */
gprs_send_data((u8 *)mqtt_msg,len);
printf("heart Send OK\r\n");
}
switch(KEY_Scan(0))
{
case KEY0_PRES:
f_close(&mfile);
while(1)
{
printf("System Stop\r\n");
delay_ms(1000);
}
break;
default:
break;
}
delay_ms(6);
// printf("Sys_Time:%d \r\n",sys_run_times);
}
while(1)
{
printf("Error\r\n");
delay_ms(500);
}
}
void Start_Gprs_TCP(void)
{
//
u8 *p1,p2[100];
u8 res=0;
p1=mymalloc(SRAMIN,100); //申請(qǐng)50個(gè)字節(jié)的內(nèi)存
sim800c_send_cmd((u8 *)"ATE0",(u8 *)"OK",200); //不回顯
USART3_RX_STA=0;
sim800c_send_cmd("AT+SAPBR=3,1,\"Contype\",\"GPRS\"","OK",200); //配置承載場景1
sim800c_send_cmd("AT+SAPBR=3,1,\"APN\",\"CMNET\"","OK",200);
sim800c_send_cmd("AT+SAPBR=1,1",0,200); //激活一個(gè)GPRS上下文
delay_ms(5);
sim800c_send_cmd("AT+CNTPCID=1","OK",200); //設(shè)置CNTP使用的CID
sim800c_send_cmd("AT+CNTP=\"202.120.2.101\",32","OK",200); //設(shè)置NTP服務(wù)器和本地時(shí)區(qū)(32時(shí)區(qū) 時(shí)間最準(zhǔn)確)
sim800c_send_cmd("AT+CNTP","+CNTP: 1",600); //同步網(wǎng)絡(luò)時(shí)間
USART3_RX_STA=0;
if(sim800c_send_cmd("AT+CPIN?","OK",200))res|=1<<0; //查詢SIM卡是否在位
USART3_RX_STA=0;
if(0 == res)
{
sim800c_send_cmd("AT+CIPCLOSE=1","CLOSE OK",100); //關(guān)閉連接
sim800c_send_cmd("AT+CIPSHUT","SHUT OK",100); //關(guān)閉移動(dòng)場景
if(sim800c_send_cmd("AT+CGCLASS=\"B\"","OK",1000)) printf("SIM800C Init1 FAIL\r\n"); //設(shè)置GPRS移動(dòng)臺(tái)類別為B,支持包交換和數(shù)據(jù)交換
if(sim800c_send_cmd("AT+CGDCONT=1,\"IP\",\"CMNET\"","OK",1000)) printf("SIM800C Init2 FAIL\r\n"); //設(shè)置PDP上下文,互聯(lián)網(wǎng)接協(xié)議,接入點(diǎn)等信息
if(sim800c_send_cmd("AT+CGATT=1","OK",500)) printf("SIM800C Init3 FAIL\r\n"); //附著GPRS業(yè)務(wù)
if(sim800c_send_cmd("AT+CIPCSGP=1,\"CMNET\"","OK",500)) printf("SIM800C Init4 FAIL\r\n"); //設(shè)置為GPRS連接模式
if(sim800c_send_cmd("AT+CIPHEAD=1","OK",500)) printf("SIM800C Init5 FAIL\r\n"); //設(shè)置接收數(shù)據(jù)顯示IP頭(方便判斷數(shù)據(jù)來源)
printf("SIM800C Start OK\r\n");
USART3_RX_STA=0;
sprintf((char*)p2,"AT+CIPSTART=\"%s\",\"%s\",\"%s\"","TCP",ipaddr,port);
if(0==sim800c_send_cmd(p2,"OK",500)) //發(fā)起連接
{
delay_ms(1500);delay_ms(1000);
sim800c_send_cmd("AT+CIPSTATUS","OK",500); //查詢連接狀態(tài)
USART3_RX_STA = 0;
if(strstr((const char*)USART3_RX_BUF,"CONNECT OK"))
{
gprs_tcp_flag = 17;
printf("SIM800C TCP Connect OK\r\n");
}
else
{
gprs_tcp_flag = 0;
printf("SIM800C TCP Connect Fail\r\n");
}
}
}
myfree(SRAMIN,p2);
}
void Stop_Gprs_Connect(void)
{
sim800c_send_cmd("AT+CIPCLOSE=1","CLOSE OK",100); //關(guān)閉連接
sim800c_send_cmd("AT+CIPSHUT","SHUT OK",100); //關(guān)閉移動(dòng)場景
}
void send_model_temp_humi(menu_message * mes,u8 * space,u8 type)
{
long val;
u8 t;
//if(strlen(space)<36)return;
switch(type)
{
case 0: //溫濕度+RTC
for(t = 0;t < 3;t ++)
{
val = (int)(mes->temp[t] * 100);
if(val<0)
{
space[t * 6] = '-';
}
else
{
space[t * 6] = '+';
}
val = val >= 0 ? val : -val;
space[t * 6 + 1] = val % 10000 /1000 + '0';
space[t * 6 + 2] = val % 1000 /100 + '0';
space[t * 6 + 3] = '.';
space[t * 6 + 4] = val % 100 /10 + '0';
space[t * 6 + 5] = val % 10 /1 + '0';
val = (int)(mes->humi[t]);
space[18 + t * 2] = val % 100 / 10 + '0';
space[18 + t * 2 + 1] = val % 10 / 1 + '0';
}
printf("Temp_Data:%s\r\n",(u8 *)space);
break;
case 1: //GPS+RTC
for(t = 0;t < 2;t ++)
{
val = (long)(mes->gps[t] * 100000);
if(val<0)
{
space[t * 10] = '-';
}
else
{
space[t * 10] = '+';
}
val = val >= 0 ? val : -val;
space[t * 10 + 1] = val % 100000000 /10000000 + '0';
space[t * 10 + 2] = val % 10000000 /1000000 + '0';
space[t * 10 + 3] = val % 1000000 /100000 + '0';
space[t * 10 + 5] = val % 100000 /10000 + '0';
space[t * 10 + 6] = val % 10000 /1000 + '0';
space[t * 10 + 7] = val % 1000 /100 + '0';
space[t * 10 + 8] = val % 100 /10 + '0';
space[t * 10 + 9] = val % 10 /1 + '0';
space[t * 10 + 4] = '.';
}
val = (int)(mes->gps[2] * 10);
space[20] = val % 10000 / 1000 + '0';
space[21] = val % 1000 / 100 + '0';
space[22] = val % 100 / 10 + '0';
space[23] = val % 10 / 1 + '0';
printf("Gps_Data:%s\r\n",(u8 *)space);
break;
case 2: //陀螺儀+RTC
MPU6050ReadAcc((short *)(mes->mpu));
for(t = 0;t < 3;t ++)
{
space[t * 2] = ((mes -> mpu[t]) >> 8) & 0xFF;
space[t * 2 + 1] = (mes -> mpu[t]) & 0xFF;
}
MPU6050ReadGyro((short *)(mes->mpu));
for(t = 0;t < 3;t ++)
{
space[6 + t * 2] = ((mes -> mpu[t]) >> 8) & 0xFF;
space[6 + t * 2 + 1] = (mes -> mpu[t]) & 0xFF;
}
for(t = 12;t < 24;t ++)
{
space[t] = '#';
}
printf("Gyro_Data:%s\r\n",(u8 *)space);
break;
case 3: //開關(guān)門+RTC
space[0] = mes->door[0] + '0';
for(t = 1;t < 24;t ++)
{
space[t] = '#';
}
printf("Door_Data:%s\r\n",(u8 *)space);
break;
case 4: //點(diǎn)熄火+RTC
space[0] = mes->door[1] + '0';
for(t = 1;t < 24;t ++)
{
space[t] = '#';
}
printf("Point_Data:%s\r\n",(u8 *)space);
break;
default :
break;
}
}
//在str1字符串中找出str2字符串(不包括str2的串結(jié)束符,忽略str中的\0)
//返回該位置的指針,如找不到,返回空指針
u8 *my_strstr(const u8 *s1,u16 n1,const u8 *s2,u16 n2)
{
int n,x=0,y=0;
if (*s2)
{
while(1)
{
if(*s1==*s2)//找到s2第一次出現(xiàn),兩種情況考慮
{
for (n=0;n<n2;n++)
{
if (*(s1+n)==*(s2+n))
{
y++;
if (y>=n2)
//if (!*(s2+n+1)) //s2下一個(gè)字符是否為'\0'
{
return (u8 *)s1;
}
if (x+n>=n1-1) //防止數(shù)組越界
{
return NULL;
}
if (*(s1+n+1)!=*(s2+n+1))//查找的下一個(gè)字符不相等,一個(gè)字符相等
{
break;
}
}
else
{
break;
}
}
}
s1++;
x++;
if(x>=n1)
{
break;
}
}
return NULL;
}
else
{
return (u8*)s1;
}
}
void gprs_send_data(u8 *data,u8 lenth)
{
if(sim800c_send_cmd("AT+CIPSEND",">",500)==0) //發(fā)送數(shù)據(jù)
{
//u3_printf("%s",(u8 *)data);
my_u3_send((char *)mqtt_msg,lenth);
delay_ms(10);
if(sim800c_send_cmd((u8*)0X1A,"SEND OK",5000)==0)
printf("GPRS數(shù)據(jù)發(fā)送成功!\r\n");//最長等待10s
}
else
sim800c_send_cmd((u8*)0X1B,0,0); //ESC,取消發(fā)送
}
復(fù)制代碼
原理圖: 無
仿真: 無
代碼:
GPRS MQTT STM32.7z
(1.56 MB, 下載次數(shù): 32)
2023-11-16 13:38 上傳
點(diǎn)擊文件名下載附件
MQTT
下載積分: 黑幣 -5
作者:
wangxiangtan
時(shí)間:
2023-11-17 08:03
厲害領(lǐng)了,stm32也能搞mqtt了啊,是以太網(wǎng)通訊解析字符嗎?
作者:
柔和de黑星
時(shí)間:
2023-11-21 10:59
現(xiàn)在很多Dtu固件的 4G卡 比較方便
作者:
wangxiangtan
時(shí)間:
2023-12-12 15:51
STM32怎么進(jìn)行TCP通訊呢老哥
作者:
guguyu
時(shí)間:
2024-1-18 21:03
這是AT指令GSM模塊里的MQTT,不能做MQTT透傳
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1