移远NBIOT模组BC26 OpenCPU对接OneNET详细讲解
本文主要讲解移远NBIOT模组BC26 OpenCPU方式对接OneNET,使用的是BC26_OpenCPU_SDK_V1.2:https://github.com/sanjaywu/BC26_OpenCPU_SDK_V1.2。为方便调试,还会涉及到BC26_OpenCPU UART的讲解。
一、实现UART打印调试信息
1、宏定义打印信息的UART端口
这里采用UART0来打印信息,同事UART0也用于发送AT命令和下载程序。
#define APP_DEBUG_PORT UART_PORT0
2、注册UART0和打开UART0端口
注册UART0,并大开UART0端口,让UART0能发送和接收数据。
Ql_UART_Register(APP_DEBUG_PORT, CallBack_UART_Hdlr, NULL); /* CallBack_UART_Hdlr为回调函数 */
Ql_UART_Open(APP_DEBUG_PORT, 115200, FC_NONE); /* 波特率为115200,无流控制 */
3、实现调试打印信息功能
通过宏定义来说实现一个打印调试信息功能。
#define DBG_BUF_LEN 1024
static char DBG_BUFFER[DBG_BUF_LEN];#define APP_DEBUG(FORMAT,...) \
{\Ql_memset(DBG_BUFFER, 0, DBG_BUF_LEN); \Ql_sprintf(DBG_BUFFER,FORMAT,##__VA_ARGS__); \Ql_UART_Write((Enum_SerialPort)(APP_DEBUG_PORT), (u8*)(DBG_BUFFER), Ql_strlen((const char *)(DBG_BUFFER))); \
}
4、CallBack_UART_Hdlr回调函数的实现
CallBack_UART_Hdlr为回调函数主要实现实时读取串口是否有接收到数据,主要用于AT指令的接受和处理。
static void CallBack_UART_Hdlr(Enum_SerialPort port, Enum_UARTEventType msg, bool level, void* customizedPara)
{switch (msg){case EVENT_UART_READY_TO_READ:{if (APP_DEBUG_PORT == port){s32 totalBytes = ReadSerialPort(port, m_RxBuf_Uart, sizeof(m_RxBuf_Uart));if (totalBytes <= 0){APP_DEBUG("<-- No data in UART buffer! -->\r\n");return;}else{APP_DEBUG ("%s\r\n", m_RxBuf_Uart);s32 ret;char* pCh = NULL;pCh = Ql_strstr((char*)m_RxBuf_Uart, "\r\n");if (pCh){*(pCh + 0) = '\0';*(pCh + 1) = '\0';}if (Ql_strlen((char*)m_RxBuf_Uart) == 0){return;}ret = Ql_RIL_SendATCmd((char*)m_RxBuf_Uart, totalBytes, ATResponse_Handler, NULL, 0);}}break;}case EVENT_UART_READY_TO_WRITE:break;default:break;}
}
二、对接OneNET的实现
1、注册一个对接OneNET定时器
注册一个对接OneNET定时,主要用于实现检查是否注册上网以及ONENET_CREATE、ONENET_ADDOBJ、ONENET_OPEN、ONENET_OBSERVER_RSP、ONENET_DISCOVER_RSP、ONENET_NOTIFY、ONENET_UPDATE等功能。
Ql_Timer_Register(ONENET_TIMER_ID, Callback_Timer_OneNET, NULL);
2、在主线程实时接收内核传来的消息
在主线程里面实时接收内核传来的消息,包括检查RIL层是否就绪,是否接收到URC消息等。
void proc_main_task(s32 taskId)
{ ...... /* 省略部分代码,完整具体看GitHub代码 */// START MESSAGE LOOP OF THIS TASKwhile(TRUE){Ql_OS_GetMessage(&msg);switch(msg.message){case MSG_ID_RIL_READY: /* RIL层就绪 */{APP_DEBUG("<-- RIL is ready -->\r\n");Ql_RIL_Initialize();Ql_RIL_SendATCmd("AT+CPSMS=0",Ql_strlen("AT+CPSMS=0"),ATResponse_Handler,NULL,0);APP_DEBUG("<-- Disable PSM -->\r\n");Ql_SleepDisable();APP_DEBUG("<-- Disable Sleep -->\r\n");break;}case MSG_ID_URC_INDICATION: /* 接收到URC消息 */{...... /* 处理URC消息 */}}}}
3、关闭PSM和sleep模式
由上面代码可知,在RIL就绪之后,关闭了PSM和Sleep模式,这个是为了不让模组进入睡眠模式,当然这个要看实际的应用情况去选择是关闭还是开启。
Ql_RIL_SendATCmd("AT+CPSMS=0", Ql_strlen("AT+CPSMS=0"), ATResponse_Handler,NULL,0);
APP_DEBUG("<-- Disable PSM -->\r\n");
Ql_SleepDisable();
APP_DEBUG("<-- Disable Sleep -->\r\n");
4、接收处理URC消息,检查SIM卡状态是否就绪
在前面的主线程实时接收内核传来的URC消息中,实时的去接收URC消息,当检查到URC消息是当前卡状态的时候,判断卡是否就绪(是否已经插卡),如果卡就绪就开启OneNET定时器,周期为1秒,模式是循环。
case URC_SIM_CARD_STATE_IND:
{APP_DEBUG("<-- SIM Card Status:%d -->\r\n", msg.param2);if(SIM_STAT_READY == msg.param2){Ql_Timer_Start(ONENET_TIMER_ID, ONENET_TIMER_PERIOD, TRUE);}break;
}
5、OneNET定时器回调函数的实现
OneNET定时器主要实现检查模组是否注册上网以及实现模组对接OneNET的功能。
static void Callback_Timer_OneNET(u32 timerId, void* param)
{s32 ret = 0;if (ONENET_TIMER_ID == timerId){switch (m_onenet_state){ case STATE_NW_QUERY_STATE:{s32 cgreg = 0;ret = RIL_NW_GetEGPRSState(&cgreg);APP_DEBUG("<--Network State:cgreg=%d-->\r\n",cgreg);if((cgreg == NW_STAT_REGISTERED)||(cgreg == NW_STAT_REGISTERED_ROAMING)){m_onenet_state = STATE_ONENET_CREATE;}break;}case STATE_ONENET_CREATE:{ret = RIL_QONENET_Create();if (RIL_AT_SUCCESS == ret){APP_DEBUG("<-Onenet Create successfully-->\r\n");m_onenet_state = STATE_ONENET_ADDOBJ;}else{APP_DEBUG("<--Onenet Create failure, error=%d.-->\r\n",ret);}break;}case STATE_ONENET_ADDOBJ:{onenet_obj_param_t.ref = 0;onenet_obj_param_t.obj_id = 3203;onenet_obj_param_t.ins_count = 1;onenet_obj_param_t.attrcount = 4;onenet_obj_param_t.actcount = 1;onenet_obj_param_t.insbitmap=(u8*) Ql_MEM_Alloc(sizeof(u8)*ONENET_TEMP_BUFFER_LENGTH);Ql_memset(onenet_obj_param_t.insbitmap,0,ONENET_TEMP_BUFFER_LENGTH);Ql_strncpy(onenet_obj_param_t.insbitmap,"1\0",Ql_strlen("1\0"));ret = RIL_QONENET_Addobj(&onenet_obj_param_t);if (RIL_AT_SUCCESS == ret){APP_DEBUG("<-- Onenet Add object successfully\r\n");m_onenet_state = STATE_ONENET_OPEN;}else{APP_DEBUG("<--Onenet Add object failure,error=%d.-->\r\n",ret);}Ql_MEM_Free(onenet_obj_param_t.insbitmap);onenet_obj_param_t.insbitmap = NULL;break;}case STATE_ONENET_OPEN:{u32 lifetime = LIFETIME; //Lifetime, unit is second.ret = RIL_QONENET_Open(onenet_obj_param_t.ref, lifetime);if (RIL_AT_SUCCESS == ret){APP_DEBUG("<-- Onenet Open successfully\r\n");m_onenet_state = STATE_TOTAL_NUM;Ql_Timer_Stop(ONENET_TIMER_ID);}else{APP_DEBUG("<--Onenet Open failure,error=%d.-->\r\n",ret);}break;}case STATE_ONENET_OBSERVER_RSP:{ST_ONENET_Observe_Param_t onenet_observe_param_t;onenet_observe_param_t.ref = onnet_param_t.ref;onenet_observe_param_t.msgid = onnet_param_t.observe_msg_id;onenet_observe_param_t.obderve_result= ONENET_OBSERVE_RESULT_1;//2.04 Content, indicate the correct result.ret = RIL_QONENET_Observer_Rsp(&onenet_observe_param_t);if (RIL_AT_SUCCESS == ret){APP_DEBUG("<--Onenet Observer respond successfully\r\n");observe_flag = FALSE;m_onenet_state = STATE_TOTAL_NUM;}else{APP_DEBUG("<--Onenet Observer respond failure,error=%d.-->\r\n",ret);}break;}case STATE_ONENET_DISCOVER_RSP:{ST_ONENET_Discover_Rsp_Param_t onenet_discover_rsp_param_t;onenet_discover_rsp_param_t.ref = onnet_param_t.ref;onenet_discover_rsp_param_t.msgid = onnet_param_t.discover_msg_id;onenet_discover_rsp_param_t.result= ONENET_OBSERVE_RESULT_1;//2.05 Content, indicate the correct result.onenet_discover_rsp_param_t.length = Ql_strlen("5750\0");onenet_discover_rsp_param_t.value_string=(u8*) Ql_MEM_Alloc(sizeof(u8)*ONENET_TEMP_BUFFER_LENGTH);Ql_memset(onenet_discover_rsp_param_t.value_string,0,ONENET_TEMP_BUFFER_LENGTH);Ql_strncpy(onenet_discover_rsp_param_t.value_string,"5750\0",Ql_strlen("5750\0"));onnet_param_t.res_id = Ql_atoi(onenet_discover_rsp_param_t.value_string);ret = RIL_QONENET_Discover_Rsp(&onenet_discover_rsp_param_t);if (RIL_AT_SUCCESS == ret){APP_DEBUG("<--Onenet discover respond successfully\r\n");m_onenet_state = STATE_ONENET_CFG;}else{APP_DEBUG("<--Onenet discover failure,error=%d.-->\r\n",ret);}Ql_MEM_Free(onenet_discover_rsp_param_t.value_string);onenet_discover_rsp_param_t.value_string = NULL;break;}case STATE_ONENET_CFG:{ST_ONENET_Config_Param_t onenet_config_param;onenet_config_param.onenet_access_mode =ONENET_ACCESS_MODE;onenet_config_param.onenet_recv_mode = ONENET_RECV_MODE;ret = RIL_QONENET_Config(&onenet_config_param,FALSE);if (RIL_AT_SUCCESS == ret){APP_DEBUG("<--Configure Optional Parameters successfully\r\n");m_onenet_state = STATE_ONENET_NOTIFY;}else{APP_DEBUG("<--Configure Optional Parameters failure,error=%d.-->\r\n",ret);}break;}case STATE_ONENET_NOTIFY:{ST_ONENET_Notify_Param_t onenet_notify_param_t;onenet_notify_param_t.ref = onnet_param_t.ref;onenet_notify_param_t.msgid = onnet_param_t.observe_msg_id;onenet_notify_param_t.objid = onnet_param_t.obj_id;onenet_notify_param_t.insid = onnet_param_t.ins_id;onenet_notify_param_t.resid = onnet_param_t.res_id;onenet_notify_param_t.value_type = ONENET_VALUE_TYPE_STRING;onenet_notify_param_t.len = Ql_strlen("Hello World\0");onenet_notify_param_t.value=(u8*) Ql_MEM_Alloc(sizeof(u8)*ONENET_TEMP_BUFFER_LENGTH);Ql_memset(onenet_notify_param_t.value,0,ONENET_TEMP_BUFFER_LENGTH);Ql_strncpy(onenet_notify_param_t.value,"Hello World\0",Ql_strlen("Hello World\0")); onenet_notify_param_t.index = 0;onenet_notify_param_t.flag =0;//onenet_notify_param_t.ackid = 0ret = RIL_QONENET_Notify(&onenet_notify_param_t,FALSE);if (RIL_AT_SUCCESS == ret){APP_DEBUG("<-- Onenet notify Request successfully\r\n");m_onenet_state = STATE_ONENET_NOTIFY;}else{APP_DEBUG("<--Onenet notify Request failure,error=%d.-->\r\n",ret);}Ql_MEM_Free(onenet_notify_param_t.value);onenet_notify_param_t.value = NULL;break;}case STATE_ONENET_UPDATE:{u32 lifttime;Ql_Timer_Stop(ONENET_TIMER_ID);lifttime = LIFETIME;ret = RIL_QONENET_Update(onnet_param_t.ref,lifttime,0) ;if (RIL_AT_SUCCESS == ret){Ql_Timer_Stop(ONENET_TIMER_ID);APP_DEBUG("<-- send data successfully\r\n");m_onenet_state = STATE_TOTAL_NUM;}else{APP_DEBUG("<--send data failure,error=%d.-->\r\n",ret);m_onenet_state = STATE_ONENET_CLOSE;}break;}case STATE_ONENET_RD:{Ql_memset(m_recv_buf,0,RECV_BUFFER_LEN);ret = RIL_QONENET_RD(onnet_param_t.recv_length,&onenet_actual_length,&onenet_remain_length,m_recv_buf) ;if (RIL_AT_SUCCESS == ret){Ql_Timer_Stop(ONENET_TIMER_ID);APP_DEBUG("<-- recv data,actual_length(%d),reamin_length(%d),buffer(%s)\r\n",onenet_actual_length,onenet_remain_length,m_recv_buf);m_onenet_state = STATE_TOTAL_NUM;}else{APP_DEBUG("<--recv data failure,error=%d.-->\r\n",ret);m_onenet_state = STATE_ONENET_CLOSE;}break;}case STATE_ONENET_CLOSE:{ret = RIL_QONENET_CLOSE(onnet_param_t.ref);if (RIL_AT_SUCCESS == ret){APP_DEBUG("<-- close onenet successfully\r\n");m_onenet_state = STATE_TOTAL_NUM;}else{APP_DEBUG("<--close onenet failure,error=%d.-->\r\n",ret);}break;}case STATE_TOTAL_NUM:{APP_DEBUG("<--onenet test case-->\r\n",ret);m_onenet_state = STATE_TOTAL_NUM;}default:break;} }
}
6、检查模组是否注册上网
前面我们知道OneNET回调函数实现了1秒循环检查模组注册上网。
case STATE_NW_QUERY_STATE:
{s32 cgreg = 0;ret = RIL_NW_GetEGPRSState(&cgreg);APP_DEBUG("<--Network State:cgreg=%d-->\r\n",cgreg);if((cgreg == NW_STAT_REGISTERED)||(cgreg == NW_STAT_REGISTERED_ROAMING)){m_onenet_state = STATE_ONENET_CREATE;}break;
}
7、创建OneNET通信接口
在模组注册上网之后,下一步就执行创建OneNET接口。
case STATE_ONENET_CREATE:
{ret = RIL_QONENET_Create();if (RIL_AT_SUCCESS == ret){APP_DEBUG("<-Onenet Create successfully-->\r\n");m_onenet_state = STATE_ONENET_ADDOBJ;}else{APP_DEBUG("<--Onenet Create failure, error=%d.-->\r\n",ret);}break;
}
8、向通信套件添加 object
创建OneNET通信接口成功之后就添加资源对象了。
case STATE_ONENET_ADDOBJ:
{onenet_obj_param_t.ref = 0;onenet_obj_param_t.obj_id = 3203;onenet_obj_param_t.ins_count = 1;onenet_obj_param_t.attrcount = 4;onenet_obj_param_t.actcount = 1;onenet_obj_param_t.insbitmap=(u8*) Ql_MEM_Alloc(sizeof(u8)*ONENET_TEMP_BUFFER_LENGTH);Ql_memset(onenet_obj_param_t.insbitmap,0,ONENET_TEMP_BUFFER_LENGTH);Ql_strncpy(onenet_obj_param_t.insbitmap,"1\0",Ql_strlen("1\0"));ret = RIL_QONENET_Addobj(&onenet_obj_param_t);if (RIL_AT_SUCCESS == ret){APP_DEBUG("<-- Onenet Add object successfully\r\n");m_onenet_state = STATE_ONENET_OPEN;}else{APP_DEBUG("<--Onenet Add object failure,error=%d.-->\r\n",ret);}Ql_MEM_Free(onenet_obj_param_t.insbitmap);onenet_obj_param_t.insbitmap = NULL;break;
}
9、向OneNET发起注册请求
添加资源对象之后就可以向OneNET发起注册请求了,请求完之后关闭OneNET定时器。
case STATE_ONENET_OPEN:
{u32 lifetime = LIFETIME; //Lifetime, unit is second.ret = RIL_QONENET_Open(onenet_obj_param_t.ref, lifetime);if (RIL_AT_SUCCESS == ret){APP_DEBUG("<-- Onenet Open successfully\r\n");m_onenet_state = STATE_TOTAL_NUM;Ql_Timer_Stop(ONENET_TIMER_ID);}else{APP_DEBUG("<--Onenet Open failure,error=%d.-->\r\n",ret);}break;
}
10、主线程接收OneNET返回的OBSERVER URC消息
在前面向OneNET发起注册请求之后,主线程会接收到下发的OBSERVER URC消息,处理URC消息,并开启OneNET定时器,定时器只支持一次,用于回复OBSERVER。
case URC_ONENET_OBSERVE:
{onenet_urc_param_ptr = msg.param2;if( onenet_obj_param_t.ref == onenet_urc_param_ptr->ref &&observe_flag == FALSE){APP_DEBUG("<--urc_onenet_observer,ref(%d),msg_id(%d),obj_id(%d),ins_id(%d),res_id(%d)-->\r\n",\onenet_urc_param_ptr->ref,onenet_urc_param_ptr->msgid,onenet_urc_param_ptr->objid,\onenet_urc_param_ptr->insid,onenet_urc_param_ptr->resid);onnet_param_t.ref = onenet_urc_param_ptr->ref;onnet_param_t.observe_msg_id = onenet_urc_param_ptr->msgid;onnet_param_t.obj_id = onenet_urc_param_ptr->objid;onnet_param_t.ins_id = onenet_urc_param_ptr->insid;observe_flag = TRUE;m_onenet_state = STATE_ONENET_OBSERVER_RSP;Ql_Timer_Start(ONENET_TIMER_ID, ONENET_TIMER_PERIOD, FALSE);}break;
}
11、OneNET定时器回复OBSERVER
接收到OneNET 的OBSERVER消息之后,需要回复。
case STATE_ONENET_OBSERVER_RSP:
{ST_ONENET_Observe_Param_t onenet_observe_param_t;onenet_observe_param_t.ref = onnet_param_t.ref;onenet_observe_param_t.msgid = onnet_param_t.observe_msg_id;onenet_observe_param_t.obderve_result= ONENET_OBSERVE_RESULT_1;ret = RIL_QONENET_Observer_Rsp(&onenet_observe_param_t);if (RIL_AT_SUCCESS == ret){APP_DEBUG("<--Onenet Observer respond successfully\r\n");observe_flag = FALSE;m_onenet_state = STATE_TOTAL_NUM;}else{APP_DEBUG("<--Onenet Observer respond failure,error=%d.-->\r\n",ret);}break;
}
12、主线程接收OneNET下发的DISCOVER URC消息
在回复OBSERVER之后,OneNET会下发DISCOVER,主线程接收这个URC消息,处理并开启循环定时器去处理。
case URC_ONENET_DISCOVER:
{onenet_urc_param_ptr = msg.param2;if( onenet_obj_param_t.ref == onenet_urc_param_ptr->ref){APP_DEBUG("<--urc_onenet_discover,ref(%d),msg_id(%d),obj_id(%d)-->\r\n", \onenet_urc_param_ptr->ref,onenet_urc_param_ptr->msgid,onenet_urc_param_ptr->objid);onnet_param_t.ref = onenet_urc_param_ptr->ref;onnet_param_t.discover_msg_id = onenet_urc_param_ptr->msgid;m_onenet_state = STATE_ONENET_DISCOVER_RSP;Ql_Timer_Start(ONENET_TIMER_ID, ONENET_TIMER_PERIOD, TRUE);}break;
}
13、OneNET定时回复DISCOVER消息
接收到了DISCOVER消息之后,通过OneNET定时回复DISCOVER消息。
case STATE_ONENET_DISCOVER_RSP:
{ST_ONENET_Discover_Rsp_Param_t onenet_discover_rsp_param_t;onenet_discover_rsp_param_t.ref = onnet_param_t.ref;onenet_discover_rsp_param_t.msgid = onnet_param_t.discover_msg_id;onenet_discover_rsp_param_t.result= ONENET_OBSERVE_RESULT_1;onenet_discover_rsp_param_t.length = Ql_strlen("5750\0");onenet_discover_rsp_param_t.value_string=(u8*)Ql_MEM_Alloc(sizeof(u8)*ONENET_TEMP_BUFFER_LENGTH);Ql_memset(onenet_discover_rsp_param_t.value_string,0,ONENET_TEMP_BUFFER_LENGTH);Ql_strncpy(onenet_discover_rsp_param_t.value_string,"5750\0",Ql_strlen("5750\0"));onnet_param_t.res_id = Ql_atoi(onenet_discover_rsp_param_t.value_string);ret = RIL_QONENET_Discover_Rsp(&onenet_discover_rsp_param_t);if (RIL_AT_SUCCESS == ret){APP_DEBUG("<--Onenet discover respond successfully\r\n");m_onenet_state = STATE_ONENET_CFG;}else{APP_DEBUG("<--Onenet discover failure,error=%d.-->\r\n",ret);}Ql_MEM_Free(onenet_discover_rsp_param_t.value_string);onenet_discover_rsp_param_t.value_string = NULL;break;
}
14、配置OneNET参数
主要配置接收模式。
case STATE_ONENET_CFG:
{ST_ONENET_Config_Param_t onenet_config_param;onenet_config_param.onenet_access_mode =ONENET_ACCESS_MODE;onenet_config_param.onenet_recv_mode = ONENET_RECV_MODE;ret = RIL_QONENET_Config(&onenet_config_param,FALSE);if (RIL_AT_SUCCESS == ret){APP_DEBUG("<--Configure Optional Parameters successfully\r\n");m_onenet_state = STATE_ONENET_NOTIFY;}else{APP_DEBUG("<--Configure Optional Parameters failure,error=%d.-->\r\n",ret);}break;
}
三、上报数据到OneNET
1、上报数据到OneNET
这里上报一个字符串 “Hello World”
case STATE_ONENET_NOTIFY:
{ST_ONENET_Notify_Param_t onenet_notify_param_t;onenet_notify_param_t.ref = onnet_param_t.ref;onenet_notify_param_t.msgid = onnet_param_t.observe_msg_id;onenet_notify_param_t.objid = onnet_param_t.obj_id;onenet_notify_param_t.insid = onnet_param_t.ins_id;onenet_notify_param_t.resid = onnet_param_t.res_id;onenet_notify_param_t.value_type = ONENET_VALUE_TYPE_STRING;onenet_notify_param_t.len = Ql_strlen("Hello World\0");onenet_notify_param_t.value=(u8*) Ql_MEM_Alloc(sizeof(u8)*ONENET_TEMP_BUFFER_LENGTH);Ql_memset(onenet_notify_param_t.value,0,ONENET_TEMP_BUFFER_LENGTH);Ql_strncpy(onenet_notify_param_t.value,"Hello World\0",Ql_strlen("Hello World\0")); onenet_notify_param_t.index = 0;onenet_notify_param_t.flag =0;//onenet_notify_param_t.ackid = 0ret = RIL_QONENET_Notify(&onenet_notify_param_t,FALSE);if (RIL_AT_SUCCESS == ret){APP_DEBUG("<-- Onenet notify Request successfully\r\n");m_onenet_state = STATE_ONENET_NOTIFY;}else{APP_DEBUG("<--Onenet notify Request failure,error=%d.-->\r\n",ret);}Ql_MEM_Free(onenet_notify_param_t.value);onenet_notify_param_t.value = NULL;break;
}
2、在OneNET平台看数据是否上报成功
上报数据到OneNET成功。
移远NBIOT模组BC26 OpenCPU对接OneNET详细讲解相关推荐
- 移远BC20模组使用LwM2M协议接入华为IoT平台(NB-IoT专栏—进阶篇2)
目录 1.背景 2.部署华为云 3.华为云与BC20模组进行数据收发实验 1.背景 最近在做一个智慧路灯项目,构思使用STM32结合NB-IoT模组实现数据上传和联动控制,并且可以使用GPS模块上传路 ...
- 中移M5310A NBIoT模组通信测试命令
总结一下中移M5310A NBIoT模组的常用测试命令,这个命令是个脚本,可以编辑,在自己开发的串口软件上可用,有需要的请留言. 脚本是.ini格式的文件,可以直接编辑文件然后加载到脚本区.字段用\t ...
- OpenHarmony3.1适配移远EC20模组4G上网功能
OpenHarmony3.1适配移远EC20模组4G上网功能 一.概述 通过阅读本篇文档,您将学习到如何适配移远EC20模组到OpenHarmony3.1(以下简称OHOS),并添加4G上网功能. 本 ...
- 移远BC35-G模组(NB-IoT 通信模组)AT指令测试 UDP 通信过程
移远BC35-G NB-IoT模组 BC35-G 是一款高性能.低功耗的多频段 LTE Cat NB1 (NB-IoT) 无线通信模块,支持 B1/B3/B8/B5/B20/B28 频段,尺寸仅为23 ...
- 【单片机笔记】上海移远公司NB-IOT模组 BC26 使用STM32 AT命令实现连接阿里云数据上传和下载
前言 在调试之前看这个数据手册一脸懵,特别是MQTT部分还是独立的,这个和前接触到的上海合宙的模块多少有点出处.另外就是那个AT命令的传入参数也是一脸懵,后来发现BC26的模块好像把MQTT部分单独的 ...
- 移远 EC200S 模组(4G Cat.1 通信模组)AT指令测试 TCP/UDP 通信过程
移远EC200S 4G Cat.1 模组 EC200S-CN 是移远通信推出的LTE Cat 1 无线通信模块,支持最大下行速率10Mbps 和最大上行速率5Mbps,具有超高的性价比. 同时在封装上 ...
- 移远5G模组RM500U-CN在Win11下的短信和通话演示
关键词:移远 5G 展锐芯片组 RM500U-CN 短信 text 通话 拨号 概述:5G模组主要用于跑数据流量,但其实基础的短信功能也还是支持的.而且,虽然没有音频接口,但是呼入呼 ...
- 使用移远EC200N-CN模组PING谷歌
目录 概述 AT指令 数据处理 提取数据 注意事项 概述 本文记录下使用EC200N-CN模组ping谷歌官网的测试过程.ping谷歌主要是摸底下设备在海外的联网丢包.延迟等情况.其实主要是为了记录下 ...
- 移远BC35-G模组通过LWM2M协议接入OneNet教程
首先平台配置: 1.注册OneNet账号(通过访问OneNet官网进入注册): 2.进入控制台,选择"全部产品服务"--"NB-IoT物联网套件": 3.添加产 ...
- 树莓派4+lede+移远5G模组RM500Q
0. 环境 win10 树莓派4 + lede rm500q // 内核文件夹 // /home/xxjianvm/lede/build_dir/toolchain-aarch64_cortex-a7 ...
最新文章
- 实现一个简单的投票功能
- ??ArcGIS server公交线路动态分段问题
- 【原创】原来你竟然是这样的Chrome?!Firefox笑而不语
- js改变css样式_React 中使用CSS的7种方法
- access 查找工龄大于30_面试前必知必会的二分查找及其变种
- Android睡眠唤醒机制--Kernel态
- netty大白话--helloword(一)
- python websocket爬虫_Python如何爬取实时变化的WebSocket数据
- Linux Shell常用命令学习(1)
- 【sklearn第二十五讲】交叉验证
- java Socket(TCP)编程小项目
- [归并排序] 二路归并排序
- 轻松学Pytorch –车辆类型与颜色识别
- Verilog语法入门
- T检验与F检验的区别_f检验和t检验的关系
- SAP 如何保证同一销售业务产生的收入和成本计入相同的会计期间?
- Ethernet guarder V1.1.exe 下载
- 微信小程序傻瓜制作_怎么能免费制作自己的微信小程序?
- Error排错:container runtime network not ready
- 数学建模美国赛论文常用句式总结