模块初始化
初始化的时候不管三七二十,直接硬复位
bool GPRS_Init()//(const char APN[])
{
/GPRS PWR & RST
GPIO_SetBits(GPIOB,GPIO_Pin_1);//唤醒
GPIO_SetBits(GPIOB,GPIO_Pin_13);//复位
//vTaskDelay(3000);
printf("开关机处理\r\n");
UARTClearRxBuffer();
GPIO_ResetBits(GPIOB,GPIO_Pin_13);//复位
vTaskDelay(3000);
GPIO_SetBits(GPIOB,GPIO_Pin_13);
//等待*ATREADY:1
pr_dbg("等待*ATREADY:1\r\n");
if(!GPRS_WaitForTargetRsp("*ATREADY: 1",GPRS_INIT_TIME_OUT))
{
return false;
}
//等待+CFUN:1
pr_dbg("等待+CFUN:1\r\n");
if(!GPRS_WaitForTargetRsp("+CFUN: 1",GPRS_INIT_TIME_OUT))
{
return false;
}
//等待CPIN: READY
pr_dbg("等待CPIN: READY\r\n");
if(!GPRS_WaitForTargetRsp("+CPIN: READY",GPRS_INIT_TIME_OUT))
{
return false;
}
//设置state状态
pr_dbg("设置state的状态\r\n");
if(!GPRS_ATCmd_A("AT+CMSYSCTRL=0,2",1000))
{
// return false;
}
//等待+IP:x.x.x.x
pr_dbg("等待+IP:x.x.x.x\r\n");
if(!GPRS_WaitEventWithStrParam("+IP:",local_IP,local_IP_size,GPRS_INIT_IP_TIME_OUT))
{
pr_err("等待IP超时\r\n");
return false;
}
pr_dbg("IP:%s\r\n",local_IP);
//清除驻网记录
pr_dbg("清除驻网记录\r\n");
int param;
if(!GPRS_ATCmd_D("AT+CLPLMN",¶m,1,GPRS_INIT_TIME_OUT))
{
return false;
}
//关闭模块自动深度休眠
pr_dbg("关闭自动休眠\r\n");
if(!GPRS_ATCmd_A("AT+SM=LOCK_FOREVER",GPRS_INIT_TIME_OUT))
{
return false;
}
//关闭模块eDRX功能
pr_dbg("关闭模块eDRX功能\r\n");
if(!GPRS_ATCmd_A("AT+CEDRXS=0,5",GPRS_INIT_TIME_OUT))
{
return false;
}
//读取CIMI(IMSI)
pr_dbg("读取CIMI\r\n");
if(!GPRS_ATCmd_B("AT+CIMI",CIMI,32,GPRS_INIT_TIME_OUT))
{
return false;
}
pr_dbg("CIMI:%s\r\n",CIMI);
//确认基站注册状态
pr_dbg("确认基站注册状态\r\n");
{
int param[2];
if(!GPRS_ATCmd_D("AT+CEREG?",param,2,GPRS_INIT_TIME_OUT))
{
return false;
}
pr_dbg("+CEREG:%d,%d\r\n",param[0],param[1]);
if(param[1]!=1&¶m[1]!=5)
{
return false;
}
}
//确认PDP 激活状态
pr_dbg("确认PDP 激活状态\r\n");
{
int param;
if(!GPRS_ATCmd_D("AT+CGATT?",¶m,1,GPRS_INIT_TIME_OUT))
{
return false;
}
pr_dbg("+CGATT:%d\r\n",param);
if(param!=1)
{
return false;
}
}
//确认PSM 参数是否设置成功
{
//..
}
//读取IMEI(IMEI)IMEI
if(!GPRS_ATCmd_B("AT+GSN",IMEI,32,GPRS_INIT_TIME_OUT))
{
return false;
}
pr_dbg("IMEI:%s\r\n",IMEI);
//读取CCID(CCID)
pr_dbg("读取CCID\r\n");
if(!GPRS_ATCmd_C("AT+ICCID",CCID,32,GPRS_INIT_TIME_OUT))
{
return false;
}
pr_dbg("CCID:%s\r\n",CCID);
//检查信号质量
pr_dbg("检查信号质量\r\n");
{
int param[2];
if(!GPRS_ATCmd_D("AT+CSQ",param,2,GPRS_INIT_TIME_OUT))
{
return false;
}
pr_dbg("rssi:%d,ber:%d\r\n",param[0],param[1]);
}
return true;
}
MQTT连接
#define string const char *
typedef struct
{
string host;
int port;
string id;
int keepAlive;
string user;
string passwd;
bool clean;
bool encrypt;
} MQTT_Config_t;
bool mqtt_sub(string topic);
bool MQTT_Connect(MQTT_Config_t *config)//(const char ip[],int port,const char *id,const char *user,const char *pass)
{
char str[255]= {0}; //=<host>,<port>,<id>,<keepAlive>,<user>,<passwd>,<clean>[,<encrypt>]
static const char mqttcfg[]="AT+MQTTCFG=\"%s\",%d,\"%s\",%d,\"%s\",\"%s\",%d,%d";// <host>,<port>,<id>,<keepAlive>,<user>,<passwd>,<clean>[,<encrypt>]
sprintf(str,mqttcfg,
config->host,
config-> port,
config-> id,
config-> keepAlive,
config-> user,
config-> passwd,
config-> clean,
config-> encrypt
);
pr_dbg("开始MQTT配置\r\n");
if(!GPRS_ATCmd_A(str,GPRS_INIT_TIME_OUT))
{
return false;
}
pr_dbg("MQTT连接\r\n");
if(!GPRS_ATCmd_A("AT+MQTTOPEN=1,1,0",GPRS_INIT_TIME_OUT))
{
return false;
}
//+MQTTOPEN: OK
pr_dbg("等待MQTT连接成功\r\n");
if(!GPRS_WaitForTargetRsp("+MQTTOPEN: OK",GPRS_INIT_TIME_OUT))
{
return false;
}
pr_dbg("订阅主题:\r\n");
mqtt_sub("/topic1");
mqtt_sub("/topic2");
mqtt_sub("/topic3");
return true;
}
bool mqtt_connect()
{
MQTT_Config_t config= {
. host="***********",
. port=1883,
. id="test",
. keepAlive=60,
. user="root",
. passwd="asdmmmm",
. clean = 1,
. encrypt=0
};
bool result= MQTT_Connect(&config);
if(result)
{
pr_dbg("MQTT测试成功\r\n");
}
else
{
pr_err("测试shibai\r\n");
}
return result;
}
MQTT订阅
文档里面说的是参数index可以不输入,但是不给会报错,默认写0就好
后续测试也不是这样,还是会出现报错,在登录MQTT后加点延时再订阅消息就不会报错了
//主题订阅
bool mqtt_sub(string topic)
{
char str[255]= {0};
pr_dbg("订阅主题:\r\n");
sprintf(str,"AT+MQTTSUB=\"%s\",2,0",topic);
if(!GPRS_ATCmd_A(str,GPRS_INIT_TIME_OUT))
{
return false;
}
pr_dbg("等待MQTT订阅结果\r\n");
if(!GPRS_WaitForTargetRsp("+MQTTSUBACK:",GPRS_INIT_TIME_OUT))
{
return false;
}
return true;
}
MQTT主题发布
bool mqtt_pub(string topic,string msg)
{
static const char *mqtt_pub_fmt ="AT+MQTTPUB=\"%s\",\"%d\",%d,%d,%d,\"%s\"";//
char str[255]= {0};
// char *topic="/hzx/ctl";//topic 订阅的主题
int qos=2;//qos 订阅的消息的 QoS 等级,支持 0-2
int retain=0;//retain 服务器是否储存该消息,并向新订阅者发送最新订阅消息,0-1
int dup=0;//dup 重发标志,0-1
int msg_len=0;//msg_len 输入消息类型,0-字符串输入,1-16 进制串输入,缺省时为 message 解析为字符串输入
//char *message="mqtt_send_test msg";//message 消息内容
int len = sprintf(str,mqtt_pub_fmt,topic,qos,retain,dup,msg_len,msg);
if(!GPRS_ATCmd_A(str,GPRS_INIT_TIME_OUT))
{
return false;
}
pr_dbg("等待发送应答\r\n");
if(!GPRS_WaitForTargetRsp("+MQTTPUBCOMP",GPRS_INIT_TIME_OUT))
{
pr_dbg("MQTT发送失败\r\n");
return false;
}
pr_dbg("MQTT发送成功\r\n");
return true;
}
bool mqtt_send_test()
{
mqtt_pub("/topic/ack","hello world");
}
百度云MQTT测试
上面的测试是在自检MQTT服务器上的测试,但是在百度云上有所区别,我发现百度云MQTT的Qos级别不支持Qos2。在客户端上测试发布Qos2的消息就会卡死,也不能订阅Qos2的消息。
添加主题
如图不支持$开头的主题,被用来做系统主题了,这里也提醒到我可以用通配符+来注册一类的主题。例如:nbdev/+/request
问题记录
- 模块电压及功率不够的时候会造成模块联网失败。
- 我是用的模块下载串口电路花里花哨,有多个电需要提供。其实就是为了电平兼容,设计上多余了啊,给我造成了很多困扰。