当我从GPIO中断唤醒时,我想改变UUID的广告的最后一个字节,以指示哪个GPIO唤醒了。使用beacon_v_5.40.2_0项目,我声明回调如下:
void tilt_wakeup_cb(void)
{
如果(GetBits16 (SYS_STAT_REG PER_IS_DOWN))
{
//从外部唤醒GPIO返回GPIO功能
if(development_debug)
GPIO_reservations ();
periph_init();
}
tilt_wkup_flag = 1;
user_advertise_operation();
}
这允许吗?
我计划使用一个标志来确定设备是被GPIO中断唤醒还是从它的计时器唤醒,基于此信息,我计划编辑user_update_ibeacon_adv_string如下:
Void user_update_ibeacon_adv_string(struct user_i_beacon_config_tag* data,struct user_beacon_config_tag config)
{
.......
//由DL添加
如果(tilt_wkup_flag) {
if(!gpio_getpinstatus(gpio_port_2,gpio_pin_0)){
数据- > uuid [15] = 1;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_1)) {
数据 - > UUID [15] = 2;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_2)) {
数据 - > UUID [15] = 3;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_3)) {
数据 - > UUID [15] = 4;
}如果(!gpio_getpinstatus(gpio_port_2,gpio_pin_4)){
数据- > uuid [15] = 5;
}如果(!gpio_getpinstatus(gpio_port_2,gpio_pin_5)){
数据 - > UUID [15] = 6;
}
tilt_wk_flag = 0;
其他}{
数据- > uuid [15] = 0;
}
//
.....
}
测试这段代码时,当GPIO被拉低以强制唤醒时,似乎没有做任何事情。
在user_on_init()
我在函数中添加了以下内容:
wkupct_register_callback (tilt_wakeup_cb);
wkupct_enable_irq(0x3f0000,0x3f0000,10);//为p2_0启用中断到p2_5
我修改了回调,如下所示,但仍然没有工作。用jlink跟踪,我可以看到它进入回调函数,但它没有通告新的uuid:
你好戴奥,
您只需要调试它,如果发生唤醒中断,您可以在user_update_ibeacon_adv_string()中放置一个断点,并检查代码是否通过该函数,以及是否满足更改广告字符串的条件。
谢谢mt_dialog.
好的,所以在调用user_advertise_operation()中不应该有任何问题;在回调里面吧?收音机和一切都应该打开,它应该在设置我的方式时宣传吗?
我只是想确保我没有违反一些规则,我们不能在GPIO中断后立即发布。
谢谢,
它不建议直接从醒来开始广告操作虽然这应该工作,可以找到适当的方式开始一个动作在app_button_press_cb ble_app_sleemode检查(),但即使不遵循你的设备应该能够开始广告。例如,如果您直接从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填充新消息,然后将自定义数据添加到广告字符串中,要调试它,您可以在代码中一步一步地进行,并检查携带advertise命令的CMD指针是否在代码的某个点包含您想放置的广告数据(检查CMD ->主机。Adv_data数组,并检查你的数据是否被添加到这个数组中)。
谢谢mt_dialog.
所以我测试了你的建议发现了一些奇怪的行为。
使用定时器唤醒时间间隔并禁用WKUPCT时,在User_update_ibeaCon_Adv_String中轮询GPIO,并相应地更新UUID上一个字节。我可以看到扫描仪应用程序中的这些更改,一切都应该工作。
然后我启用wkupct:
wkupct_register_callback (tilt_wakeup_cb);
wkupct_enable_irq(0x3f0000,0x3f0000,10);//为p2_0启用中断到p2_5
在此之后,我不再看到扫描仪应用程序中UUID的最后一个字节的变化。由于使用相同的代码更新广告字符串和广告,我将假定这两个函数工作正常。现在来弄清楚为什么启用wkupct和调用user_advertise_operation不再正常工作。
我尝试跟踪cmd->info->host->adv_data,但没有一个值似乎匹配UUID或任何可识别的东西。
代码仅使用对话框user_advertise_operation();没有修改它。
我修改了对话框代码user_update_ibeacon_adv_string
Void 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);
>compa雷电竞下载appny_id[0] = (uint8_t) (config.company_id&0xff);
数据 - >雷电竞下载app company_id [1] =(UINT8_T)(CONFIG.COMPANY_ID >> 8);
数据- > data_type = iBEACON_DATA_TYPE;
数据 - > beacon_length = adv_data_length;
memcpy(data-> uuid,config.uuid,16);
//由DL添加
如果(tilt_wkup_flag) {
if(!gpio_getpinstatus(gpio_port_2,gpio_pin_0)){
数据- > uuid [15] = 1;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_1)) {
数据 - > UUID [15] = 2;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_2)) {
数据 - > UUID [15] = 3;
} else if (!GPIO_GetPinStatus (GPIO_PORT_2 GPIO_PIN_3)) {
数据 - > UUID [15] = 4;
}如果(!gpio_getpinstatus(gpio_port_2,gpio_pin_4)){
数据- > uuid [15] = 5;
}如果(!gpio_getpinstatus(gpio_port_2,gpio_pin_5)){
数据 - > UUID [15] = 6;
}
tilt_wkup_flag = 0;
其他}{
数据- > uuid [15] = 0;
}
//
数据- > tx_power = config.power;
}
写了wkupct回调:
void tilt_wakeup_cb(void)
{
如果(GetBits16 (SYS_STAT_REG PER_IS_DOWN))
{
//从外部唤醒GPIO返回GPIO功能
if(development_debug)
GPIO_reservations ();
periph_init();
}
if(arch_ble_ext_wakeup_get()))
{
ARCH_SET_SLEEP_MODE(app_default_sleep_mode);//设置默认睡眠模式
ARCH_BLE_FORCE_WAKEUP();//强制摇晃醒来
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_restarted = true;
cmd - > info.host。adv_data_len = user_load_beacon_config (cmd);
//开始发布不可连接的外设。
if (TASK_APP) == ke_state_get(TASK_APP)
{
//在连接状态下不要发布不可连接的广告
}
其他的
{
如果(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_restarted = 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上的广告字符串,为了正确停止,更新广告字符串并重新开始广告,你必须发出一个stop,然后等待堆栈回复广告确实停止了(SDK会通知你广告已经停止了,同时app_on_adv_undirect complete for the undirected advertising,对于不可连接的广告也有相应的回调-请检查基本的例子,以便有一个比信标更简单的参考)。因此,当堆栈通知你广告已经完成,并发生回调时,从那个回调中,你可以调用你将更新的新广告字符串的开始。您不能调用停止广告,然后立即调用函数来启动。我想这就是你的主要问题。
关于您试图实施和时间两个广告数据之间的差异,请注意,广告不是一种可靠的方式来发送数据,这意味着无法保证您将发送的数据将到达扫描仪特定的时间,由于在当时在常规摄像机时,其他广告设备和协议之间的协议之间的碰撞,所以通过广告过程没有保证,无论外围设备发送扫描仪是否将最肯定地接收。所以请注意。
谢谢mt_dialog.
(谢谢你们一直以来的支持。)我尝试在基本项目中实现这个例子,但它似乎仍然不起作用。我不知道还能尝试什么,但既然你提到不能保证数据到达扫描仪,我们就得想点别的办法。
嗨DLO,
是的,并不能保证广告字符串将到达中央,由于拥挤的平均值,范围或噪音,协议没有一个机制,以便中央确认发送的广告字符串已经收到的外设,这只发生在连接期间。
谢谢mt_dialog.