亲爱的Dialog_Support,
我正在使用BLE外设作为我项目的参考代码。BLE外围代码正在作为广告设备工作,但我想将其配置为扫描设备(中央)。现在我在现有示例中完成了以下更改。
1.在user_config.h
static const结构gapm_configuration user_gapm_conf = {
///设备角色:中心,外围,观察者或广播
。role = gap_central_mst,
struct scan_configuration {
///操作代码。
UINT8_T代码;
///设备自带BD地址源
uint8_t addr_src;
/ / /扫描间隔
uint16_t间隔;
///扫描窗口大小
uint16_t窗口;
/ / /扫描模式
UINT8_T模式;
///扫描过滤策略
uint8_t filt_policy;
///扫描重复过滤策略
uint8_t filter_duplic;
};
静态const struct scan_configuration
///操作代码。
.code = gapm_scan_passive,
///设备自带BD地址源
.addr_src = GAPM_PUBLIC_ADDR,
/ / /扫描间隔
.interval = 10,
///扫描窗口大小
.window = 5,
/ / /扫描模式
.mode = gap_gen_discovery,
///扫描过滤策略
.filt_policy = SCAN_ALLOW_ADV_ALL,
///扫描重复过滤策略
.filter_duplic = scan_filt_duplic_en.
};
2.在user_callback_config.h
静态const struct app_callbacks
.app_on_connection = user_app_connection,
.app_on_disconnect = user_app_disconnect,
.app_on_update_params_rejected = null,
.app_on_update_params_complete =零,
.app_on_set_dev_config_complete = default_app_on_set_dev_config_complete,
.app_on_adv_nonconn_complete =零,
.app_on_adv_undirect_complete = user_app_add_undirect_complete,
.app_on_adv_direct_complete = null,
.app_on_db_init_complete = default_app_on_db_init_complete,
.app_on_scanning_completed = user_on_scanning_completed,
.app_on_adv_report_ind = user_on_adv_report_ind,
#如果(BLE_APP_SEC)
.app_on_pairing_request =零,
.app_on_tk_exch_nomitm =零,
.app_on_irk_exch =零,
.app_on_csrk_exch =零,
.app_on_ltk_exch = null,
.app_on_pairing_succeded = null,
.app_on_encrypt_ind = null,
.app_on_mitm_passcode_req =零,
.app_on_encrypt_req_ind = null,
.app_on_security_req_ind = null,
#endif //(ble_app_sec)
};
3.我已经在user_peripheral.c文件中添加了这些函数
无效user_on_scanning_completed (uint8_t status)
{
如果状态= = GAP_ERR_CANCELED)
{
app_easy_gap_start_connection_to();
connection_timer = app_easy_timer(USER_CON_TIMEOUT, user_gapm_cancel);
}
别的
{
user_scan_start();
}
返回;
}
静态void user_scan_start(void)
{
struct gapm_start_scan_cmd* cmd = KE_MSG_ALLOC(gapm_start_scan_cmd,
task_gapm,task_app,
gapm_start_scan_cmd);
cmd - > op。代码= user_scan_conf.code;
cmd-> op.addr_src = user_scan_conf.addr_src;
cmd - >间隔= user_scan_conf.interval;
cmd窗口- > = user_scan_conf.window;
cmd - >模式= user_scan_conf.mode;
cmd - > filt_policy = user_scan_conf.filt_policy;
cmd - > filter_duplic = user_scan_conf.filter_duplic;
//发送消息
ke_msg_send (cmd);
//我们现在是可连接的
ke_state_set (TASK_APP APP_CONNECTABLE);
}
我已经尝试过上面的备受尊重文件的更改,但随着我运行程序,它进入NMI_Handler.c。
我遗漏了什么吗?或者我做了任何错误的配置?请指导我正确的步骤配置BLE外设作为一个中心。
提前谢谢你。
带着敬意,
前腿帕特尔
嗨,前腿帕特尔
当设备准备开始(配置,设置并准备好)广告或扫描命令都从.default_operation_Adv,所以在那个挂钩中,您应该在准备好的情况下放置您想要的设备。所以我假设如果你在那个钩子中放置user_start_scan()函数而不是user_app_adv_start()你的设备将开始扫描过程。
由于MT_dialog
谢谢你的建议。
我已经尝试过上述解决方案,但我仍然得到同样的问题。当我运行程序时,它进入nmi_handler.h。是我在user_config.h中完成的上述配置,user_callback_config.h和user_peripher.cl文件是正确的?您可以提供详细的解决方案或示例代码,展示中央功能。
带着敬意,
前腿帕特尔
嗨,前腿帕特尔
如果触发user_scan_start()函数,请检查调试器,如果触发完成,请检查完成回调,如果它是拨打的错误代码是什么,如果它是一个GAP_ERROR_TIMEOUT,则在大约8秒的活动之后得到它您正在扫描,并且当您到达扫描过程的完成回调时触发NMI。关于您粘贴的文件和代码,我没有看到它们的任何问题,你得到的nmi意味着代码保持相当于困境的时间(如果有的话可以是主循环中的wfi()休眠禁用,没有BLE活动超过2.6秒,这是看门狗可以测量的最长时间)。据一个例子是关注,我想你已经熟悉来自主机侧的DSPS代码。
由于MT_dialog
你好MT_Dialog,
感谢您的回复。现在我可以将ble_app_peripheral与我的中心设备连接起来。下一个任务是从中心设备发送一个命令到ble_app_peripheral来切换LED。我可以使用自定义配置文件特征发送命令ble_app_peripheral从中心设备,因为我们正在做从BLE扫描仪应用程序?
带着敬意,
前腿帕特尔
嗨,前腿帕特尔
与来自中心的自定义配置文件进行交互,需要在中心侧实现,因为当设备连接时,中央应开始发现过程,以便发现可用的服务和特性。在中央发现外围侧的特性之后,它可以开始写入和读取数据,因为中央需要知道应在外围侧读取或写入的手柄。简而言之,是的,你可以将数据写入自定义特征,只要特征是可写的,但您必须实现中心侧的发现过程,然后您将能够编写数据。DSP主机侧实现了DSP配置文件的发现过程,您可以将其视为参考。
由于MT_dialog
感谢您的快速回复。
我需要实现定制服务和特性的发现程序。我还没有找到关于证据开示程序的明确步骤。我也经历了DSPS的例子,但由于其复杂性,我不能正确地理解它。
1.您可以列出详细信息中发现程序的步骤吗?
2.参考DSP,提到哪些文件发现相关信息?
3.哪些功能可用于发现定制服务和特征?
带着敬意,
前腿帕特尔
嗨,前腿帕特尔
1.我不能提及的每一个细节发现过程在这个论坛上,您应该检查的BLE规范为了得到广泛的知识发现过程,我可以提几个关于这个过程的关键步骤,也给你一些代码片段在需求方的源代码。另外一个非常有用的文档是RW-BLE-GATT-IS.pdf,该文档包含了所有应该向堆栈发出和从堆栈发出的命令/响应,以便完成发现过程。
由于MT_dialog
hello dialog_support,
感谢您的客户端配置步骤。我追随了你的脚步,但我正在出错。
1…\src\custom_profile\user_custs_config.c(47): error: #29: expected a expression
struct attm_desc_128 custs1_att_db[CUST1_IDX_NB] = {};
const struct cust_prf_func_callbacks cust_prf_funcs [] =
{
#if(ble_custom1_server)
{TASK_CUSTS1,
custs1_att_db,
CUST1_IDX_NB,
#if(ble_app_present)
app_custs1_create_db,app_custs1_enable,
其他#
null,null,
# endif
custs1_init,null.
},
# endif
#如果(BLE_CUSTOM2_SERVER)
{TASK_CUSTS2,
空值,
0,
#if(ble_app_present)
app_custs2_create_db app_custs2_enable,
其他#
null,null,
# endif
custs2_init,零
},
# endif
{task_none,null,0,null,null,null,null},//不要移动。必须始终持久
};
我在user_custs_config.c中声明了上面的函数
在user_custs1_def.h中
extern struct attm_desc_128 custs1_att_db[CUST1_IDX_NB];
2.我应该写什么而不是#if(ble_sps_client)
带着敬意,
前腿帕特尔
嗨,前腿帕特尔
1.很明显,你已经在DSPS主机中放置了custs1.h include,以便包含自定义概要文件,你还没有声明任何东西作为数据库,检查例如ble_app_peripheral的例子,并检查数组中有什么。
2.但是我不理解第二个问题,这只是为了包含SPS客户端功能的一个定义。
由于MT_dialog
非常感谢你的步骤。它有助于我们很多。经过长时间,我能够发现服务和特征。现在我的下一个任务是客户端和服务器之间的数据传输。您能告诉我哪个自定义函数启动数据传输程序?
感谢和问候,
前腿帕特尔
嗨,前腿帕特尔
您的意思是,您想要执行从中心到外设特性的写入?您可以使用prf_gatt_write()命令的dsp实现例子,当然这个函数发送一个特定消息向堆栈GATTC_WRITE_CMD,,你将能够找到额外的信息在RW-BLE-GATT-IS.pdf支持网站。
由于MT_dialog
嗨MT_Dialog,
是的,我想从核心写入外围的特征。
如您建议使用“PRF_Gatt_Write()”命令,我在DSP示例中检查了它。据我所知,有一个名为“sps_client_data_tx_req_handler”的特定处理程序,它使用“prf_gatt_write()”命令处理传输请求。因此,每当中央提升写(数据TX)请求时,应理想地调用处理程序。但是,我不明白如何调用tx_req_handler。我究竟究竟是如何调用内置函数或写自己的函数,这将调用“sps_client_data_tx_req_handler”?
感谢和问候,
前腿帕特尔
嗨,前腿帕特尔
你看到的处理程序是DSPS引用应用程序的实现,如果你想通过发送消息和通过消息处理事件而不是直接调用一个函数调用来触发写入事件,你可以实现类似DSPS项目的东西。当DSPS希望发送数据时,它实现一个名为SPS_CLIENT_DATA_TX_REQ的消息并将其发送到堆栈,然后堆栈一旦消息被处理就会触发相应的处理程序,SPS_CLIENT_DATA_TX_REQ消息通过user_send_ble_data()函数发送,由该消息触发的处理程序声明在sps_client_connected数组中的sps_client_task.c文件中,您可以将其作为一个引用。
由于MT_dialog
.
嗨MT_dialog,
最初,我也考虑使用“user_send_ble_data()”功能,用于通过ble发送数据。此函数要求数据和data_length作为参数。然后它将该数据发送到预定的特征。但在我的情况下,我不想始终将我的数据发送到固定的特征。
例如:
假设我有一个名为“Cust_Service_1”的自定义服务。在该服务中,我有一些自定义特征,如“led_1_亮度”,“led_2_亮度”等,它们具有写入无响应属性。
现在,我想向“LED_1_Brightness”的特征发送0x57。
所以我所遇到的是一个简单的功能,接受以下参数:
UINT8_T数据[1] = {0x57};
UINT8_T长度= 1;
空白my_function_to_send_data (服务名称Cust_Service_1,charecteristic_name.LED_1_Brightness,data_value.*数据,Data_Length长度);
因为“user_send_ble_data()”函数只接受数据和数据长度;我如何确保我的数据被发送到我想要的正确特征?是否应该像上面的例子中那样为服务名称和特征名称附加附加参数?或者是否有其他方法可以首先在外部的某个变量中设置服务和特征名,然后调用“user_send_ble_data()”函数,以便将数据发送到所需的特征?请帮我一下。
感谢和问候,
前腿帕特尔
嗨,前腿帕特尔
如上所述,user_send_ble_data()是DSPS使用的函数,它不是用于将数据发送到服务上可用的任何特征的通用函数。实际发送数据的处理程序是sps_client_data_tx_req_handler(),而实际发送数据的函数是prf_gatt_write()。因为这个函数实际上是向另一边发送数据的,所以它也是确定数据将被发送的特征句柄的函数。因此,通过调用带有相应句柄参数的prf_gatt_write()将更新适当的特征值。在DSPS的情况下,在sps_client_data_tx_req_handler中使用的特征句柄总是spsc_env->sp .chars[SPSC_SRV_RX_DATA_CHAR].val_hdl。
由于MT_dialog
嗨MT_dialog,
正如您之前评论中正确提及的那样,sps_client_data_tx_req_handler()是实际发送数据的函数。我想要一个简单的应用程序,用户按下按钮,它会触发中断例程。在中断例程内,我想调用sps_client_data_tx_req_handler()函数发送一些数据。该函数需要以下参数:
静态int sps_client_data_tx_req_handler(ke_msg_id_t const msgid,
Struct sps_client_data_tx_req const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
但是,我不太清楚要在每个参数中传递什么,以便将我的数据发送到特定的特征。你能给我更多的解释吗?
感谢和问候,
前腿帕特尔
嗨,前腿帕特尔
您可以在sps_client_data_tx_req strult中添加额外的成员,并通过该成员来传递您想要的特征,因此当您分配SPS_CLIENT_DATA_TX_REQ消息时,您还应通过您想要执行写入的特性,例如该结构目前具有三个成员(inhdl,长度和数据),在发送消息之前分配消息,因此添加一个额外的成员,该成员将保存您想要编写的特征。当调用SPS_CLIENT_DATA_TX_REQ_HANDLER()而不是PRF_GATT_WRITE()中的固定值时,您可以通过SPS_CLIENT_DATA_TX_REQ结构中添加的额外成员的值。
由于MT_dialog
嗨MT_Dialog,
谢谢你的帮助。我成功地将数据写入一个特定的特征。我使用了一种与你建议的略有不同的方法,但既然它能起到作用,我也不介意。下面是我的程序所做的总结:
因此,我目前可以将数据从1个BLE客户端发送到1个BLE外围设备。请注意,它们都始终在整个会话中连接。
现在,我的项目仍然存在最后一步。有1个客户端(我正在努力),有4个外围设备。我有4个不同的用户输入按钮,并且根据按下的按钮,我想从我的BLE客户端发送数据到特定的BLE外围设备。所以这里是我现在想要实现的示例流程:
请注意,我不希望同时连接,我只需要连接到特定的设备,发送数据然后断开连接。
我急需实施这个计划。所以我希望你能给出具体的解决方案。请帮. . ! !
提前谢谢,
前腿帕特尔
嗨,前腿帕特尔
您的用例是非常具体的,我无法在本论坛上留下或记录每种特定细节,请查看我的建议。
为了通过中央连接到外围设备,需要广告外设(需要广告,以便外围设备接收连接请求,仅用于扫描设备的中心,所以您将假设您的外围设备将在那里并发出没有扫描过程的连接请求,或者您也将扫描?我想您将要为您的设备使用公共地址,因为SPEG定义的静态地址,它们应该在每个重启外设的重新启动时更改,并且随机可解析需要与每个单独的设备绑定。所以假设您正在使用公共地址,并且据我所知,您的中央地址是有两个选项:
1)假设设备已经有和没有扫描过程从中央,当按钮被按下可以发出一个连接通过app_easy_gap_start_connection_to_set()和app_easy_gap_start_connection_to()以启动连接过程中,但同样,你必须确保设备在做广告,如果没有,连接过程不会超时,如果没有人回应,你就必须通过应用程序超时。因此,一旦设备连接起来,发现过程就会开始,设备会做它连接时做的任何事情。一旦交换了数据,就可以调用app_easy_gap_disconnect()以断开外围设备与中心设备的连接,当连接发生时,禁用并清理概要文件结构(取决于您如何实现自定义概要文件)。断开连接请求可以通过外设发出,也可以通过中央发出。
2)关于第二个选项,您可以按下按钮并存储在全局变量中,您想要连接的相应的BD地址,因此当扫描过程返回指示标准的特定地址时,您可以发出连接请求。除了所有的剩余部分都保持不变。
由于MT_dialog
嗨MT_dialog,
我的最终目标是设计一个可编程BLE远程用于控制多个调光灯。因此,遥控器最初保留在外围模式中并与Android应用程序连接。那么该应用程序将判断哪个按钮应该做哪些功能。BLE遥控器仅仍然存在于外围模式。但是一旦用户按下按钮,让我们说按钮-1,它执行以下操作:
我仍然没有想到如何在运行时进行角色切换。所以目前,我的可编程BLE遥控器始终处于中央模式。
为了操作我的BLE遥控器上的按钮按下调光器,我写了以下代码:
BOOL GBOOLD1CONNECT = FALSE;
void user_button_pressed(void)
{
gboold1connect = true;
/ / user_on_adv_report_ind (param - >报告。adv_addr_type: 0 x01);
if(dimmer1_connected == true)//仅在整个连接过程完成后才为真
{
uint8_t my_data [1];
my_data [0] = 0 x14;/ /亮度值
uint16_t my_length;
my_length = 1;
//这个函数从开关发送数据到调光器
prf_gatt_write(con_info,val_hdl,(uint8_t *)my_data,sizeof(uint8_t)* my_length,gattc_write);
}
}
//这是Inbuilt函数,我已修改,以便在Gboold1Connect为真时才能连接到Dimmer-1
Void user_on_adv_report_ind(struct gapm_adv_report_ind const * param) (struct gapm_adv_report_ind const * param)
{
如果(gboolD1Connect)
{
如果(! memcmp (param - >报告。数据[3]、USER_ADVERTISE_DATA USER_ADVERTISE_DATA_LEN))
{
arch_printf("Connect with %02x %02x %02x %02x %02x %02x %02x",
param - > report.adv_addr.addr [5],
param-> eport.addr.addr [4],
param - > report.adv_addr.addr [3],
param - > report.adv_addr.addr [2],
param - > report.adv_addr.addr [1],
param-> report.adddr.addr [0]);
app_easy_gap_start_connection_to_set(param-> rapth.adv_addr_type,(uint8_t *)&param-> report.adv_ddr.addr,ms_to_doubleslots(12.5));
user_gapm_cancel();
}
}
}
上述实施方式,但它有问题。当我第一次按遥控器按钮的时候,它会设置gboolD1Connect返回true,然后退出函数,因为dimmer1_connected还没有真。之后,在背景中,何时user_on_adv_report_ind ()运行,它将与dimmer1连接。一旦连接完成,将发现所有的服务、特征和描述符。最后,就在发现描述符之后,我还在内建函数中插入了一行dimmer1_connected = true.整个过程需要2-3秒。所以3秒后,当我再次按下按钮时,它最终会进入dimmer1_connected == true部分并发送亮度值。所以你可以看到,我得按两次按钮(1号用于连接,2号用于发送数据)能够发送数据。这个问题发生,因为每当我给一个命令,以连接到一个调光器设备(通过制作gboolD1Connect使真实,或通过使用app_easy_gap_start_connection_to_set ()函数),我必须退出中断例程,并允许主程序运行,以便实际连接可以发生。但是,既然我已经退出了中断程序,我将如何重新进入它并在连接外围设备时发送数据呢?
所以我有两个需要帮助的问题:
在此先感谢您的帮助,
前腿帕特尔
嗨Ruchi,
我可以建议你看看无附庸的样本应用程序(https://support.dialog-semiconductor.com/connectivity/reference-design/smartbond-codeless-serial-link)。
此应用程序演示中央和外围设备的各个方面以及如何在角色之间切换。
/ mhv.
嗨mhv,
你给出的建议真的很棒,我很高兴能够继续实现。但是看文档,我明白它的实施需要两个主要的东西:
(1) DA1458x BLE模块与AT命令固件
(2)第三方微控制器来控制BLE模块
但在我的情况下,我在单个芯片上只有一个DA1458x BLE模块。我没有权限在同一个芯片上添加另一个第三方控制器来控制BLE模块。
我希望我的DA1458x BLE模块有一个AT固件,然后逻辑地调用AT命令序列本身以独立的方式操作。
所以,是否可以在不需要终端,Android应用程序或第三方控制器等外部控制机制的情况下实现AT命令方法?
谢谢,
前腿帕特尔
嗨Ruchi,
实现应该只是用于指导如何完成不同的事情。通过运行代码,并使用调试器逐步执行各种命令,您将能够了解看似复杂的任务是如何实现的。这里有一些例子:
无附加的实现是在命令触发不同动作的命令,但应该可以编写自己的逻辑来驱动相同的功能(您可能只将应用程序的代码复制到您的项目中的无附带部分)
/ mhv.
我无法发现特征,但我可以发现服务,我的项目BLE_APP_PERITERAL
你能告诉我如何发现特征?
非常感谢你!
嗨Chenpenglai,
这个论坛的帖子很旧了,所以我建议你创建一个新的。如果你不知道你应该遵循的程序,以创建一个新的论坛线程,请让我知道,我将提供您所需的所有步骤。所以,请创建一个新的论坛帖子和复制粘贴你的问题。
关于你的问题,你使用的是哪个版本的SDK ?你在SDK的ble_app_peripheral例子中做了任何修改吗?
谢谢,PM_Dialog