当我从GPIO中断唤醒时,我想改变UUID的广告的最后一个字节,以指示哪个GPIO唤醒了。使用beacon_v_5.40.2_0项目,我声明回调如下:
void tilt_wakeup_cb(void)
{
if (GetBits16(SYS_STAT_REG, PER_IS_DOWN))
{
// Return GPIO functionality from external wakeup GPIO
if(development_debug)
gpio_reservations();
periph_init();
}
tilt_wkup_flag = 1;
user_advertise_operation();
}
这允许吗?
我计划使用标志来确定设备是否通过GPIO中断或从其定时器唤醒,根据我计划编辑user_update_ibeacon_adv_adv_tring的信息,如下所示:
void user_update_ibeacon_adv_string(struct user_i_beacon_config_tag* data,struct user_beacon_config_tag config)
{
.......
//由DL添加
if(tilt_wkup_flag){
if(!gpio_getpinstatus(gpio_port_2,gpio_pin_0)){
data->uuid[15] = 1;
}如果(!gpio_getpinstatus(gpio_port_2,gpio_pin_1)){
数据 - > UUID [15] = 2;
}别的if(!GPIO_GetPinStatus(GPIO_PORT_2, GPIO_PIN_2)){
数据 - > UUID [15] = 3;
}别的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:
Hi dio,
You will just need to debug this, if the wake up interrupt occurs, you can place a breakpoint in the user_update_ibeacon_adv_string() and check if the code goes through that function and if the conditions are met in order to change the advertising string.
谢谢mt_dialog.
好的,所以在调用user_advertise_operation()中不应该有任何问题;在回调里面吧?收音机和一切都应该打开,它应该在设置我的方式时宣传吗?
Just making sure I am not breaking some rules that we can't advertise right after waking up from a GPIO interrupt.
谢谢,
嗯,它没有建议直接从唤醒开始广告操作虽然这应该工作,可以在BLE_APP_SLEEMODE中找到一个动作的正确方法,检查app_button_press_cb(),但即使没有跟随你的设备应该能够开始广告。例如,如果可以直接从app_button_press_cb()和删除app_easy_wakeup()设备将宣传的App_easy_wakeUp()将用户调用user_app_adv_start()(我假设是与已实现的user_advertise_operation相同。但是使用app_easy_wakeup()API的建议方式。
谢谢mt_dialog.
当没有发生GPIO中断并且设备在定时间隔上唤醒时,在手机上的灯架扫描应用上看到所有广告活动。
When a GPIO interrupt does occur, stepping through the code, it seems the code does what it is supposed to, but I never see the correct values in the scanner app...
不知何故,我认为没有暗示在这种情况下发布的数据。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()函数才能填写一个新消息,然后在广告字符串中添加自定义数据,您可以做些什么来调试这是为了逐步在代码中查看携带广告命令的CMD指针包括您想要放置的广告数据的代码中的某个点(检查CMD-> host.adv_data阵列并检查您的数据是否在此阵列中附加)。
谢谢mt_dialog.
So I tested what you suggested and found some strange behavior.
使用定时器唤醒时间间隔并禁用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不再适用。
I tried tracing the cmd->info->host->adv_data but none of the values seem to match UUID or anything recognizable.
代码仅使用对话框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);
数据 - >雷电竞下载app company_id [0] =(UINT8_T)(CONFIG.COMPANY_ID&0xFF);
数据 - >雷电竞下载app company_id [1] =(UINT8_T)(CONFIG.COMPANY_ID >> 8);
data->data_type = iBEACON_DATA_TYPE;
数据 - > beacon_length = adv_data_length;
memcpy(data-> uuid,config.uuid,16);
//由DL添加
if(tilt_wkup_flag){
if(!gpio_getpinstatus(gpio_port_2,gpio_pin_0)){
data->uuid[15] = 1;
}如果(!gpio_getpinstatus(gpio_port_2,gpio_pin_1)){
数据 - > UUID [15] = 2;
}别的if(!GPIO_GetPinStatus(GPIO_PORT_2, GPIO_PIN_2)){
数据 - > UUID [15] = 3;
}别的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;
}
//
data->tx_power = config.power;
}
写了wkupct回调:
void tilt_wakeup_cb(void)
{
if (GetBits16(SYS_STAT_REG, PER_IS_DOWN))
{
// Return GPIO functionality from external wakeup 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(); //disable the external wake up
}
tilt_wkup_flag = 1;
user_advertise_operation();
wkupct_enable_irq(0x003f0000,0x003f0000,10);//为p2_0启用中断到p2_5
}
感谢你一如既往的支持!
Found a bit more information.
我删除了对user_advertise_operation()的调用;在tilt_wakeup_cb()中,现在看到扫描仪应用程序中的预期更改。问题是它稍后最终记录了大约5-10个广告间隔。(我在5秒钟内设置广告间隔,我在GPIO被拉低后在大约55秒内收到更改的数据包)。
That seems to indicate that there's a buffer of advertising data that needs to be flushed out before the actual event one is placed in queue? Does this seem right?
你提到我应该停止广告,更新广告字符串,然后重新启动广告。我是否正确地解释这一点,如果我这样做了?
app_easy_gap_advertise_stop();
user_advertise_operation();
user_advertise_operation()的代码;是默认的对话框:
void user_advertise_operation(void)
{
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)
{
//Get a pointer to the BLE packet
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 ( APP_CONNECTED == ke_state_get(TASK_APP))
{
/ /不做广告non-connectable一点a connected state
}
别的
{
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();
}
}
否则if(current_advertising_mode ==未向连接_mode)
{
//Get a pointer to the BLE packet
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);
}
// Start advertising for undirect peripheral.
app_easy_gap_undirected_advertise_start();
}
}
Background on what I'm trying to do, please let me know if it's possible.
当GPIO2_0变为低电平时,我想用uuid结尾发出一个广告,以0.手机应用程序将记录它收到广告的时间。当另一个GPIO变低时,让我们说GPIO2_1,我想用uuid结尾发出一个广告。手机将记录它收到的时间并计算两个广告之间的时间差。时间差对我正在尝试与数据进行操作至关重要。这是实现这一目标的可靠方法吗?或者是否有一些类型的限制,不允许我完成这一目标?
再次感谢您继续支持。
嗨DLO,
Regarding updating the advertising string on a 580, in order to properly stop, update the advertising string and start advertising again, you will have to issue a stop and then wait for the stack to reply back that the advertising has indeed stopped (the SDK will inform you that the advertising has stopped with the app_on_adv_undirect complete for the undirected advertising, for the non-connectable advertising there is also the corrsponding callback - please check the barebone example in order to have a more simple reference than the beacon). So when the stack notifies you that the advertising has completed and the callback occurs, from that callback you can invoke the starting of the new advertising string which you will have updated. You can't invoke stop advertising and then immidiatelly call the function to start. I suppose that this is your main issue.
关于您试图实施和时间两个广告数据之间的差异,请注意,广告不是一种可靠的方式来发送数据,这意味着无法保证您将发送的数据将到达扫描仪特定的时间,由于在当时在常规摄像机时,其他广告设备和协议之间的协议之间的碰撞,所以通过广告过程没有保证,无论外围设备发送扫描仪是否将最肯定地接收。所以请注意。
谢谢mt_dialog.
谢谢你继续support. I tried implementing the example in the barebone project, but it still doesn't seem to work. I don't know what else to try, but since you mentioned that there is no guarantee about the data reaching the scanner, we'll need to figure something else out.
嗨DLO,
是的,没有保证广告字符串将要达到中央,由于一个拥挤的平均值,范围或噪音,协议没有机制,以便核心adcied广告串的外围设备收到,这仅在连接期间发生。
谢谢mt_dialog.