基于 移远 BC26 移柯BL620的NB模块调试流程

NB模块连接网络顺序

移柯NBL260模块

NB卡: 联通   默认波特率 115200

//UDP 链接方式:

AT //判断模组是否上电开机成功

AT+CIMI //读取 IMSI, 判断 SIM 卡初始化是否成功

AT+CESQ    检查信号质量

AT+CEREG? //判断 PS 域附着(是否注册网络)状态,标识位返回 1 或 5 表示附着正常

 

AT+CIPMUX=0  //切换到单个链接

AT+CIPSTART="UDP","101.95.153.110",60110  // 配置服务器及上产方式

AT+QLWOPEN=0           // 连接网络

AT+CIPSEND =5              //固定发送数据长度位5(长度大小可自由设定)

12345                     //直接上传数据

AT+CIPRXGET=1,100    // get data

 

移远NB BC26模块

链接移远平台(COAP协议)

NB卡: 联通   默认波特率 115200

手动检查:

AT    //同步波特率直到回复OK

AT+CIMI     //读取 IMSI, 判断 SIM 卡初始化是否成功

AT+CESQ    //检查信号质量   推荐15 -31

AT+CFUN?  //是否返回1  检查 UE的功能等级  1代表全部功能

AT+CEREG? 返回0,1表示入网成功,0,0  0,2正在找网 300S

AT+CGPADDR=1    检查IP

 AT+CGSN=1  // 获取IMEI号码     在绑定平台的时候需要发送IMEI

自动检查部分:

URC:

+CPIN: READY

+IP:XXXXXXX 

//网络,格式配置

AT+NCDP=southbound.quectel.com,5683 //设置服务器端口和 地址

AT+QLWCONF="IMEI"      例如: AT+QLWCONF="866971033147948"    

AT+QLWADDOBJ=19,1,1,"0"     //配置:LWM2M

AT+QLWADDOBJ=19,0,1, "0"      //配置1:LWM2M

AT+QLWOPEN=0                //Register to the IoT platform in direct push mode

AT+QLWCFG="dataformat",1,1  //Configure hex string mode for sending and received data.

AT+QLWDATASEND=19,0,0,2,3132,0x0100   . //send data 12 datalength 2  CON数据

 

AT+SM=LOCK指令来阻止模块进入PSM      //调试的时候可以使用到

 

说明: 模块上电启动会自动连接网络,若模块返+CPIN: READY 说明模块本身的基本配置已经完成,返回+IP:XXXXXXX,表示模块已经自动联网。若自动联网即可直接进入网络配置一块,后即可发送数据。具体案例最下图所示。

 

 

移远NB  广州联通平台

https://device1-portal.10646.cn

user = "dyson.zhang@whoareyou.live";

 password = "way123!@#";

 

coAP接入方式LwM2M链接

AT

AT+CESQ

AT+CFUN?

AT+CEREG?

AT+CGPADDR=1

AT+QLWSERV="device1-api.10646.cn",5683   等价 AT+NCDP=device1-api.10646.cn,5683

AT+QLWCONF="866971033147948"

AT+QLWADDOBJ=19,1,1,"0"

AT+QLWADDOBJ=19,0,1,"0"

AT+QLWOPEN=0

AT+QLWCFG="dataformat",1,1

AT+QLWDATASEND=19,0,0,2,3132,0x0100 // con数据

注意事项:模块开机后会自动调整工作模式,不需额外干预,若一段时间不操作,模块会自进入PSM模式。如想再次操作,需从PSM唤醒。

AT指令发送时需要回车键

include "App_Main.h"
#include "NBIot_BC26.h"
#include "Drv_Usart.h"
#include "fifo.h"

static void StartingUp(void);

extern char gaucUsart1Buff[RXBUFSIZE];
 char  *gcBC26CmdBuff=0 ; // 存放BN26模块返回的状态指令
 void NB_BC26_init(void)
 {
    // NB  Vcc  
   GPIO_SetMode(NB_VCCPort, NB_VCCPin, GPIO_MODE_OUTPUT);
   GPIO_SetMode(PWRKEY_Port, PWRKEY_Pin, GPIO_MODE_OUTPUT);
   GPIO_SetMode(PSM_EINT_port, PSM_EINT_pin, GPIO_MODE_OUTPUT);
   GPIO_SetMode(Reset_Port, Reset_Pin, GPIO_MODE_OUTPUT);
	 
   NB_VCCEN;
	  Reset_Disable;
//   Reset_BC26();
   Drv_SysDelayMs(50);
   StartingUp();
	// PSM_wake();
 }
 // 从psm 唤醒
 static void PSM_wake(void)
 {
   PSM_EINT_Disable;
   Drv_SysDelayMs(10);
   PSM_EINT_EN;
   Drv_SysDelayMs(5);
   PSM_EINT_Disable;
 }
 //上电启动
 static void StartingUp(void)
 {
   PWRKEY_Disable;
   Drv_SysDelayMs(10);
   PWRKEY_EN; 
   Drv_SysDelayMs(800);
   PWRKEY_Disable;
 }
 //断电关机
  void Shutdown(void)
  {
    NB_VCCDisable;
  }
// reset 
 void Reset_BC26(void)
 {
    Reset_Disable;
    Drv_SysDelayMs(10);
    Reset_EN;
    Drv_SysDelayMs(100);
    Reset_Disable;
 }
 /*发送 AT 指令给NBiot
  返回: 1 代表成功  0 代表失败  
 */
 
 uint8_t Send_AT_CMD(UART_T* uart,uint8_t *cmdBuffer)
 {
	 uint8_t utReturn = 0;
	 
	 while(*cmdBuffer != '\0')
	 {
     utReturn = UART_Write(uart,cmdBuffer++,1);
	 }
	 return utReturn;
 }
 /* function : 判断返回数据
    @param :
    *String:  接受到的与之对比的命令
    *InBuffer: 输入的数据缓存(IN)
    * OutBuffer : 在InBuffer 中截取的String及以后的数据
    ucLen 对比之后首次出现是首地址
 */
extern volatile uint32_t gudComRFlag;
extern uint8_t guRX_num;
 
 
char *RX_BC26_CMD(char *InBuffer,char *String)
{
  char *INdex=0;
    INdex = strstr(InBuffer,String);
  return INdex;
}

 /* function : 发送指令
    @param :uart   串口号
    cmd  发送命令
    *String:  接受到的与之对比的预知命令
    waittime : 超时时间
    Index_location 对比之后首次出现是首地址
return : sucess  or  fail
 */
uint8_t BC26_send_cmd(UART_T* uart,uint8_t *cmd,char *String,char **Index_location,uint16_t waittime)
{
  uint8_t res = TA_FAIL; 
  guRX_num =0;
  memset(gaucUsart1Buff,0,sizeof(gaucUsart1Buff));
   Send_AT_CMD(uart,cmd);   //发送出去命令
    Drv_SysDelayMs(300);
      while(waittime--)
      { 
        Drv_SysDelayMs(20);//串口在一个字节一个字节的接收,这块每接收一个字节就检测接收到的整个数据是否符合要求
        if(gudComRFlag) //收到数据,检查数据是否是想要的
          {       
            *Index_location = RX_BC26_CMD(gaucUsart1Buff,String);
            if( RX_BC26_CMD(gaucUsart1Buff,String))
            {
              res = TA_SUCCESS;
				break;  //是想要的,发送结束,跳出
            }
            gudComRFlag=0;   
          } 
      }
  return res;
	}
 /*
    function: BC26模块上电自检 
    return : sucess  or  fail
  */ 
//uint8_t Power_ONCheckself(void)
//{
//	uint32_t Time_out = 0;
//   //NB_BC26_init();
// while(RX_BC26_CMD(gaucUsart1Buff,"Leaving"))
//  {
//   memset(gaucUsart1Buff,0,sizeof(gaucUsart1Buff));
//   return TA_SUCCESS;
//  }
//  else
//  {
//    Shutdown();
//    Drv_SysDelayMs(10);
//    NB_BC26_init();
//   if(TA_SUCCESS == RX_BC26_CMD(gaucUsart1Buff,"Leaving"))
//   {
//     memset(gaucUsart1Buff,0,sizeof(gaucUsart1Buff));
//    return TA_SUCCESS;
//   }
//   else
//   {
//     return TA_FAIL;
//   }
//  }
//  
//}
//将普通字符串转化成Hex字符串
uint8_t str2hex(char* str, char* hex)
{

    const char* cHex = "0123456789ABCDEF";
    int i=0,j=0;
    for( j =0; j < strlen(str); j++)
    {
        unsigned int a =  (unsigned int) str[j];
        hex[i++] = cHex[(a & 0xf0) >> 4];
        hex[i++] = cHex[(a & 0x0f)];
    }
    hex[i] ='\0';
		return i;
}
//NBiot模块上网流程
uint8_t BC26_DataProcess(uint8_t *NB_buffer,uint8_t NB_Length)
{ 
	uint32_t time_out = 5; 
	uint8_t Signal_Strength = 0;
	uint8_t Statue = NB_Start;
	uint16_t Hex_Data_Length = 0;
	uint8_t New_Satrt_count = 3 ; //启动的次数
	uint8_t Hex_buffer[100]={0};  // 存储转化为hex的数据
	char *Data_Location =0;
	char *AT_cmd1= 0;    // 存储 AD—cmd
	char *AT_cmd2= 0;

// if(TA_SUCCESS != Power_ONCheckself())// 自检失败,直接退出
//	{
//		 return TA_FAIL;
//	}
	while(1)
	{	
		if(0 == New_Satrt_count)
					return TA_FAIL;
		
		 switch(Statue)
		 {
			 case NB_Start:
				    time_out = 40;
			  //    NB_VCCDisable;
			      Drv_SysDelayMs(1000);
						NB_BC26_init();
			      while(time_out--)
						{
						  if( RX_BC26_CMD(gaucUsart1Buff,"Leaving"))
									break;
							 Drv_SysDelayMs(10);
						}
						Statue = AT;
						break;
			 case AT:    //同步波特率
				    time_out=4;
						while(time_out--)   
							{
								if(TA_SUCCESS == BC26_send_cmd(UART1,"AT\r\n","OK",&Data_Location,100)) // 超时时间2S
								{
									break;
								}
							  if( RX_BC26_CMD(gaucUsart1Buff,"+CPIN: READY"))
									break;
								if(time_out<2) // 若失败两次,则重启模块
								{
									Statue = NB_Start;
									New_Satrt_count--;
									break;
								}
							}
						  if(RX_BC26_CMD(gaucUsart1Buff,"+IP:"))
							{
								Statue = AT_NCDP;
								 break;
							}
							else
							{
							  Statue = AT_CESQ;
							 break;
							}
			 case AT_CESQ:  // 检查信号强度
							time_out =50;
							while(time_out--)
							{	      
								if( RX_BC26_CMD(gaucUsart1Buff,"+CPIN: READY"))
								{
	                  break;
								 }
									Drv_SysDelayMs(100);
							 } 					
							time_out = 3;
							while(time_out--) 
							{	
								if(RX_BC26_CMD(gaucUsart1Buff,"+IP:"))
								 {
										Statue = AT_NCDP;
									 break;
								 }								
								if(TA_SUCCESS == BC26_send_cmd(UART1,"AT+CESQ\r\n","+CESQ: ",&Data_Location,100)) // 超时时间2S
								{
									Signal_Strength = 10*(*(Data_Location+7) - 48)	+ (*(Data_Location+8) - 48);
									if(((*(Data_Location+7) - 48) == 0) || ((*(Data_Location+7) - 48) == 9))
									 {
											 New_Satrt_count--;
											 Statue = NB_Start;
											 break;
										}
										else
										{
										 Statue = AT_CFUN;
										 break;
										}
									}
								if(time_out<2)
								{
									Statue = NB_Start;
									New_Satrt_count--;
									break;
								}
							}
					break;
				case AT_CFUN:  // 检查UE功能等级  最长15S 
							time_out = 2; 
							while(time_out--)    
							{
						    if(RX_BC26_CMD(gaucUsart1Buff,"+IP:"))
							  {
							  	Statue = AT_NCDP;
							 	   break;
						   	 }
								if(TA_SUCCESS == BC26_send_cmd(UART1,"AT+CFUN?\r\n","+CFUN: ",&Data_Location,750)) // 超时时间15S
								{
									Signal_Strength = (*(Data_Location+7) - 48);
									if((Signal_Strength != 1))
									{
										continue;
									 }
										else
										{
										 Statue = AT_CEREG;
										 break;
										}
									}
									else
									{
									 PSM_wake();
									}

								if(time_out<1)
								{
									Statue = NB_Start;
									New_Satrt_count--;
									break;;
								}
							}
							break;
					case  AT_CEREG: // 检查是否入网成功
							 time_out = 3;
							while(time_out--)    
							{
								 if(RX_BC26_CMD(gaucUsart1Buff,"+IP: "))
							  {
							  	Statue = AT_NCDP;
							 	   break;
						   	 }
								if(TA_SUCCESS == BC26_send_cmd(UART1,"AT+CEREG?\r\n","+CEREG: ",&Data_Location,400)) // 超时时间2S
								{   
									if(*(Data_Location+10) == '1')// join in internet sucess
									{
										 Statue = AT_CGPADDR;
										break;
									}
									else if((*(Data_Location+10) == '2') || (*(Data_Location+10) == '0') ) //looking for internet
									{
										Drv_SysDelayMs(500);
									}
								}
								if(time_out<2)
								{
									Statue = NB_Start;
									New_Satrt_count--;
									break;
								}
							}
						
							break;
					case  AT_CGPADDR:  // Get IP adress
							 time_out = 3;
							while(time_out--)    
							{
								if(TA_SUCCESS == BC26_send_cmd(UART1,"AT+CGPADDR=1\r\n","+CGPADDR: 1",&Data_Location,100)) // 超时时间2S
								{
							     Statue = AT_NCDP;									
										break;
								}
								if(time_out<2)
								{
									Statue = NB_Start;
									New_Satrt_count--;
									break;
								}
							}
							break;
				// case  AT_CGSN:  // get IMEI 
						case AT_NCDP:  //  configure network adress
						//	 Drv_SysDelayMs(7000);		
							 time_out = 2;
							 while(time_out--)
							 {    				
									if (TA_SUCCESS == BC26_send_cmd(UART1,"AT+NCDP=southbound.quectel.com,5683\r\n","OK",&Data_Location,100)) // 超时时间2S
									{
							       Statue = AT_QLWCONF;										
											break;
									}
									else
									{
										 if(time_out<1)
											{
												Statue = NB_Start;
												New_Satrt_count--;
												break;
											}
									}
							 }

							break;
						case AT_QLWCONF: // 配置设备的IMEI
									time_out = 2;
									AT_cmd1 = "AT+QLWCONF=";
									AT_cmd2 = "866971033234043";
									memset(Hex_buffer,0,sizeof(Hex_buffer));
									Hex_Data_Length = Cmd_connect(AT_cmd1,AT_cmd2,Hex_buffer,11,15);
									 Hex_buffer[Hex_Data_Length] = 0x0D;
									 Hex_buffer[Hex_Data_Length+1] = 0x0A;
								//  UART_Write(UART1,QLWCONF_buffer,sizeof(QLWCONF_buffer));   //发送出去命令
								while(time_out--)
								{    				
										if (TA_SUCCESS == BC26_send_cmd(UART1,Hex_buffer,"OK",&Data_Location,100)) // 超时时间2S
										{
										   	Statue = AT_QLWADDOBJ;
													break;
										}
										else
										{
											if(time_out<1)
												{
													Statue = NB_Start;
													New_Satrt_count--;
													break;
												}
										}
								} 
							break;
							case AT_QLWADDOBJ: // 配置1
									time_out = 2;
									AT_cmd1 = "AT+QLWADDOBJ=19,1,1,";
									AT_cmd2 = "0";
									memset(Hex_buffer,0,sizeof(Hex_buffer));
									Hex_Data_Length = Cmd_connect(AT_cmd1,AT_cmd2,Hex_buffer,20,1);
									Hex_buffer[Hex_Data_Length]= 0x0D; //回车            
									Hex_buffer[Hex_Data_Length+1] = 0x0A;
								while(time_out--)
								{    				
										if (TA_SUCCESS == BC26_send_cmd(UART1,Hex_buffer,"OK",&Data_Location,100)) // 超时时间2S
										{
									   	Statue = AT_QLWADDOBJ1;
												break;
										}
										else
										{
											if(time_out<1)
												{
													Statue = NB_Start;
													New_Satrt_count--;
													break;
												}
										}
								}

							break;
							case AT_QLWADDOBJ1: // 配置2
									
										time_out = 2;
										AT_cmd1 = "AT+QLWADDOBJ=19,0,1,";
										AT_cmd2 = "0";
										memset(Hex_buffer,0,sizeof(Hex_buffer));
										Hex_Data_Length = Cmd_connect(AT_cmd1,AT_cmd2,Hex_buffer,20,1);
										Hex_buffer[Hex_Data_Length]= 0x0D; //回车
									while(time_out--)
									{    				
											if (TA_SUCCESS == BC26_send_cmd(UART1,Hex_buffer,"OK",&Data_Location,100)) // 超时时间2S
											{
												Statue = AT_QLWOPEN;
												break;
											}
											else
											{
												if(time_out<1)
													{
														Statue = NB_Start;
														New_Satrt_count--;
														break;
													}
											}
									}
							break;
							 case AT_QLWOPEN: //  Register to the IoT platform in direct push mode
										time_out = 2;
									while(time_out--)
									{    				
										if (TA_SUCCESS == BC26_send_cmd(UART1,"AT+QLWOPEN=0\r\n","+QLWOBSERVE:",&Data_Location,300)) // 超时时间6S
											{
												 
														break;
											}
											else
											{
												if(time_out<1)
													{
															return TA_FAIL;
													}
											}
									}
							Statue = AT_QLWCFG; // 16进制
							break;
							case AT_QLWCFG:
										time_out = 2;
										AT_cmd1 = "AT+QLWCFG=";
										AT_cmd2 = "dataformat";
										memset(Hex_buffer,0,sizeof(Hex_buffer));
										Hex_Data_Length = Cmd_connect(AT_cmd1,AT_cmd2,Hex_buffer,10,10);
										Hex_buffer[Hex_Data_Length] = 0x2c; //,
										Hex_buffer[Hex_Data_Length+1] = 0x31; //1
										Hex_buffer[Hex_Data_Length+2] = 0x2c;//,
										Hex_buffer[Hex_Data_Length+3] = 0x31; //1
										Hex_buffer[Hex_Data_Length+4]= 0x0D; //回车
									while(time_out--)
									{    				
											if (TA_SUCCESS == BC26_send_cmd(UART1,Hex_buffer,"OK",&Data_Location,100)) // 超时时间2S
											{
												  Statue = AT_QLWDATASEND;
														break;
											}
											else
											{
												if(time_out<1)
													{
															return TA_FAIL;
													}
											}
									}
							break;
						 case AT_QLWDATASEND:  // updata
							  time_out = 3;
						 	  memset(Hex_buffer,0,sizeof(Hex_buffer)); 
						 
						    Hex_Data_Length = NB_Settle_Data(Hex_buffer,NB_buffer,NB_Length);//数据整合
                Hex_buffer[Hex_Data_Length++] = 0x2c;//,
						    Hex_buffer[Hex_Data_Length++] = 0x30;//0
			          Hex_buffer[Hex_Data_Length++] = 0x78;//x
						    Hex_buffer[Hex_Data_Length++] = 0x30;//0
						    Hex_buffer[Hex_Data_Length++] = 0x31;//1
						    Hex_buffer[Hex_Data_Length++] = 0x30;//0
						    Hex_buffer[Hex_Data_Length++] = 0x30;//0
						 	  Hex_buffer[Hex_Data_Length++]= 0x0D; //回车
						    Hex_buffer[Hex_Data_Length++] = 0x0A;
							   while(time_out--)
								 {    		
                     //Drv_SysDelayMs(2000);									 
										if (TA_SUCCESS == BC26_send_cmd(UART1,Hex_buffer,"SEND OK",&Data_Location,200)) // 超时时间4S
											{
													 return TA_SUCCESS;
											}
											else
											{
												if(time_out<1)
													{
															return TA_FAIL;
													}
											}
									}

			 }
	 }  
}
/*
   功能,整理数据成NB 可以识别的正常数据
   Outbuffer  [OUT] 输出数据
   INbuf  :  输入的 开门信息
   Len :   开门信息数据长度
*/
uint8_t  NB_Settle_Data(uint8_t *Outbuffer,uint8_t *INbuf,uint8_t Len)
{
	uint16_t length0=0,i=0;
	char *AT_P = "AT+QLWDATASEND=19,0,0,";
	length0 = AT_Conversion_HEX(AT_P,Outbuffer,22);
	if(2*Len >9)
	{
	 Outbuffer[length0++] = (2*Len)/10 + 0x30;
	 Outbuffer[length0++] = (2*Len)%10 + 0x30;
	}
	else
	{
    Outbuffer[length0++] = Len + 0x30;
	}
	Outbuffer[length0++] = 0x2c; //,
	// data
	for(i=0;i<Len;i++)
	{
	  Outbuffer[length0++] = 0x33;
//	  if(INbuf[i]>9)
//	  {
	  Outbuffer[length0++] = INbuf[i]/10+0x30;
	  Outbuffer[length0++] = 0x33;
		Outbuffer[length0++] = INbuf[i]%10+0x30;
//	  }
//	 else
//	  Outbuffer[length0++] = INbuf[i]%10+0x30;
	}
	return length0;
}

/* function: AT TO Hex
   @param IN_buffer  AT_cmd (IN)
           length    the length of IN_buffer
           Outbuffer  Hex (out)

*/
uint16_t AT_Conversion_HEX(char *IN_buffer,uint8_t *Outbuffer,uint16_t length)
{
  char temp=0;
	uint16_t i=0;
	uint16_t Cmd_length = 0;
	Cmd_length = length ;
	
	while(Cmd_length--)
	{
      Outbuffer[i]= IN_buffer[i];
	   i++;
	}
	return i;
}
/*链接两个CMD
@param:*IN_buffer1 【IN】   cmd 1
          *IN_buffer2  【IN】 cmd 2
          *Outbuffer    【out】 输出 hex 
          length1  [IN]     IN_buffer1 length
          length2    [IN]   IN_buffer2 length
 */
uint16_t Cmd_connect(char *IN_buffer1,char *IN_buffer2,uint8_t *Outbuffer,uint16_t length1,uint16_t lengt2)
{
	uint16_t len1 = 0;
   uint16_t len2 = 0;

    len1 = AT_Conversion_HEX(IN_buffer1,Outbuffer,length1);
    len2 = AT_Conversion_HEX(IN_buffer2, Outbuffer + len1+1 ,lengt2);
	  Outbuffer[len1] =0x22;
    Outbuffer[len1+len2+1] = 0x22;
	return (len1+len2+2);
}

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值