我想在从GPIO中断唤醒时更改广告UUID的最后一个字节,以指示哪个GPIO唤醒它。使用beacon_v_5.40.2_0项目,我声明回调如下:
空白tilt_wakeup_cb(空白)
{
if (GetBits16(SYS_STAT_REG, PER_IS_DOWN))
{
//从外部唤醒GPIO返回GPIO功能
如果(DEVELOPMENT_DEBUG)
GPIO_reservations ();
periph_init ();
}
Tilt_wkup_flag = 1;
user_advertise_operation ();
}
这是允许的吗?
我计划使用一个标志来确定设备是否被GPIO中断或从它的定时器唤醒,根据这个信息,我计划编辑user_update_ibeacon_adv_string,如下所示:
(struct user_i_beacon_config_tag* data,struct user_beacon_config_tag config)
{
……
//由DL添加
如果(tilt_wkup_flag) {
如果(!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_0)) {
Data ->uuid[15] = 1;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_1)) {
Data ->uuid[15] = 2;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_2)) {
Data ->uuid[15] = 3;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_3)) {
Data ->uuid[15] = 4;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_4)) {
Data ->uuid[15] = 5;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_5)) {
Data ->uuid[15] = 6;
}
Tilt_wk_flag = 0;
其他}{
Data ->uuid[15] = 0;
}
//
…
}
测试这段代码时,当GPIO被拉低以强制唤醒时,似乎没有做任何事情。
在user_on_init ()
我把这个添加到函数中:
wkupct_register_callback (tilt_wakeup_cb);
x3f0000 x3f0000 wkupct_enable_irq (0, 0, 0);//开启P2_0到P2_5的中断
我修改回调如下,但似乎仍然不工作。跟踪与Jlink,我可以看到它进入回调函数,但它没有宣传新的UUID:
你好戴奥,
您只需要调试这个,如果发生了唤醒中断,您可以在user_update_ibeacon_adv_string()中放置一个断点,并检查代码是否通过该函数,以及是否满足更改广告字符串的条件。
由于MT_dialog
好的,那么调用user_advertise_operation()应该没有任何问题;在回调函数里面?收音机和所有的东西都应该开着,它应该在我设置的时候做广告?
只是确保我没有违反一些规则,我们不能在从GPIO中断醒来后立即发布这些规则。
谢谢,
好吧,不建议直接从唤醒开始广告操作,尽管这应该是可行的,启动一个动作的正确方法可以在ble_app_sleemode检查app_button_press_cb()中找到,但即使没有遵循,您的设备也应该能够开始广告。例如,如果您直接从app_button_press_cb()调用user_app_adv_start()(我认为它与您已经实现的user_advertise_operation相同)并删除app_easy_wakeup(),设备将发布。但是建议使用app_easy_wakeup() API的方法。
由于MT_dialog
当没有GPIO中断发生,设备在定时间隔内唤醒时,所有广告事件都可以在我手机上的信标扫描应用程序上看到。
当GPIO中断确实发生时,步进代码,似乎代码做了它应该做的事情,但我从未在扫描器应用程序中看到正确的值……
不知何故,我认为在这个场景中数据并没有被公开。app_easy_gap_non_connectable_advertise_start()用于这两个场景。对于GPIO中断情况,我将cmd->intv_min和cmd->intv_max更改为0。或者把这两个空着,都不走运。
这是代码。
嗨dlo,
如果代码做了它应该做的事情,你得到了你想要的中断和数据,你看到设备仍然在广告,但使用了旧的值,那么你在广告字符串中放置数据的方式应该是错误的。在广告字符串已经更新了新值后,我假设您停止广告更新广告字符串的新值,然后您重新启动广告使用user_advertise_operation。你调用app_easy_gap_non_connectable_advertise_get_active()函数为了SDK填写一个新的消息,然后你在广告中添加自定义数据字符串,你能做什么来调试这是去一步一步的代码并检查cmd指针,携带广告命令包括代码的广告数据在某种程度上,你想要(检查cmd - >主机。Adv_data数组并检查您的数据是否附加在该数组中)。
由于MT_dialog
所以我测试了你的建议发现了一些奇怪的行为。
当使用定时器唤醒间隔并禁用wkupct时,GPIO将在user_update_ibeacon_adv_string中轮询,并且UUID的最后一个字节将相应更新。我可以在扫描仪应用程序中看到这些变化,一切正常。
然后我启用wkupct:
wkupct_register_callback (tilt_wakeup_cb);
x3f0000 x3f0000 wkupct_enable_irq (0, 0, 0);//开启P2_0到P2_5的中断
在此之后,我不再看到扫描仪应用程序中UUID变化的最后一个字节。由于相同的代码用于更新广告字符串和广告,我假设这两个函数工作正常。现在来弄清楚为什么启用wkupct并调用user_advertise_operation不再正常工作。
我尝试跟踪cmd->info->host->adv_data,但没有一个值似乎与UUID或任何可识别的值匹配。
该代码只使用对话框代码user_advertise_operation();没有任何修改。
我修改了对话框提供的代码user_update_ibeacon_adv_string
(struct user_i_beacon_config_tag* data,struct user_beacon_config_tag config)
{
memcpy (data->adv_header, ADV_HEADER_iBEACON,2);
Data -亚博全网>company_id[0] = (uint8_t) (config.company_id&0xff);
Data -亚博全网>company_id[1] = (uint8_t) (config.company_id>>8);
data->data_type = iBEACON_DATA_TYPE;
data->beacon_length = ADV_DATA_LENGTH;
Memcpy (data->uuid,配置。uuid, 16);
//由DL添加
如果(tilt_wkup_flag) {
如果(!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_0)) {
Data ->uuid[15] = 1;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_1)) {
Data ->uuid[15] = 2;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_2)) {
Data ->uuid[15] = 3;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_3)) {
Data ->uuid[15] = 4;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_4)) {
Data ->uuid[15] = 5;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_5)) {
Data ->uuid[15] = 6;
}
Tilt_wkup_flag = 0;
其他}{
Data ->uuid[15] = 0;
}
//
Data ->tx_power = config.power;
}
编写了wkupct回调:
空白tilt_wakeup_cb(空白)
{
if (GetBits16(SYS_STAT_REG, PER_IS_DOWN))
{
//从外部唤醒GPIO返回GPIO功能
如果(DEVELOPMENT_DEBUG)
GPIO_reservations ();
periph_init ();
}
如果(arch_ble_ext_wakeup_get ())
{
arch_set_sleep_mode (app_default_sleep_mode);//设置默认睡眠模式
arch_ble_force_wakeup ();//强制BLE唤醒
arch_ble_ext_wakeup_off ();//禁用外部唤醒
}
Tilt_wkup_flag = 1;
user_advertise_operation ();
x003f0000 x003f0000 wkupct_enable_irq (0, 0, 0);//开启P2_0到P2_5的中断
}
感谢您一直以来的支持!
找到了更多的信息。
我删除了对user_advertise_operation()的调用;在tilt_wakeup_cb()中,现在在扫描仪应用程序中看到预期的变化。问题是,它最终在大约5-10个广告间隔后被记录下来。(我将广告间隔设置为5秒,在gpio拉低后大约55秒收到更改的数据包)。
这似乎表明有一个广告数据的缓冲区,需要在实际事件被放入队列之前被冲掉?这看起来对吗?
你提到我应该停止广告,更新广告字符串,然后重新启动广告。如果我这样做,我的理解正确吗?
app_easy_gap_advertise_stop ();
user_advertise_operation ();
user_advertise_operation()的代码;是默认的对话框之一:
空白user_advertise_operation(空白)
{
Struct gapm_start_advertise_cmd* cmd;
Current_advertising_string = next_advertising_string;
Current_advertising_mode = next_advertising_mode;
if (current_advertising_mode == NON_CONNECTABLE_MODE)
{
//获取指向BLE包的指针
CMD = app_easy_gap_non_connectable_advertise_get_active();
user_adv_restart = true;
cmd - > info.host。Adv_data_len = user_load_beacon_config(cmd);
//开始为不可连接的外围设备发布广告。
if (APP_CONNECTED == ke_state_get(TASK_APP))
{
//不要在连接状态下发布不可连接的广告
}
其他的
{
If (user_flash_beacon_config_loaded)
{
cmd->intv_min = MS_TO_BLESLOTS(user_beacon_config.adv_int);
cmd->intv_max = MS_TO_BLESLOTS(user_beacon_config.adv_int);
}
app_easy_gap_non_connectable_advertise_start ();
}
}
else if (current_advertising_mode == UNDIRECTED_MODE)
{
//获取指向BLE包的指针
CMD = app_easy_gap_undirected_advertise_get_active();
user_adv_restart = true;
cmd - > info.host。Adv_data_len = user_load_beacon_config(cmd);
if (current_advertising_string == SUOTA_ADVERTISING_STRING)
{
update_advertising_data (USER_ADVERTISE_SUOTA USER_ADVERTISE_SUOTA_LEN);
user_update_adv_string (cmd, (void *) dynamic_adv_string SUOTA_ADVERTISING_STRING, USER_ADVERTISE_SUOTA_LEN);
}
//开始通告非直接外围设备。
app_easy_gap_undirected_advertise_start ();
}
}
关于我正在尝试做的事情的背景,如果可能的话,请告诉我。
当GPIO2_0变低时,我想发送一个UUID以0结尾的广告。手机应用程序将记录它收到广告的时间。当另一个GPIO变低时,比方说GPIO2_1,我想发送一个UUID以1结尾的广告。手机将记录它收到广告的时间,并计算出两个广告之间的时间差。时差对于我想要处理的数据非常重要。这是一种可靠的实现方法吗?或者是否存在某种类型的限制,不允许我完成这个目标?
再次感谢你们一直以来的支持。
嗨dlo,
关于更新580上的广告字符串,为了正确地停止,更新广告字符串并重新开始广告,你必须发出一个停止命令,然后等待堆栈回复广告确实已经停止(SDK会通知你广告已经停止,app_on_adv_undirect完成无定向广告,对于不可连接的广告,也有相应的回调-请检查barebone示例,以便有一个比信标更简单的引用)。因此,当堆栈通知您广告已经完成并且回调发生时,您可以从该回调调用您将更新的新广告字符串的开始。您不能调用停止广告,然后立即调用函数启动。我想这是你的主要问题。
关于您正在尝试实现的内容和两个广告数据之间的时间差,请注意,广告不是一种可靠的发送数据的方式,这意味着不能保证您将发送的数据将在特定的时间到达扫描仪,因为在一般的平均值之间,其他广告设备和协议之间会发生碰撞。因此,在广告过程中,并不能保证无论外设发送什么,扫描仪一定会接收到。所以请注意这一点。
由于MT_dialog
感谢你们一直以来的支持。我尝试在barebone项目中实现该示例,但它似乎仍然不能工作。我不知道还能尝试什么,但既然你提到不能保证数据能到达扫描仪,我们就得想别的办法了。
嗨dlo,
是的,不能保证广告字符串将到达中心,由于拥挤的平均值、范围或噪声,协议没有一种机制来让中心对发出的广告字符串已接收的外围设备进行ACK,这只发生在连接期间。
由于MT_dialog