当我从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();
}
这允许吗?
I am planning on using a flag to determine if the device was woken up by a GPIO interrupt or from its timer, based on this information I'm planning on editing the user_update_ibeacon_adv_string as follow:
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;
}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)){
data->uuid[15] = 5;
}如果(!gpio_getpinstatus(gpio_port_2,gpio_pin_5)){
数据 - > UUID [15] = 6;
}
tilt_wk_flag = 0;
}else{
data->uuid[15] = 0;
}
//
.....
}
Testing this code, didn't seem to do anything when the GPIO was pulled low to force a wakeup.
在user_on_init()
I added this to the function:
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.
Thanks,
Well, its not suggested to start an advertising operation directly from the wake up although this should work, the proper way to start an action can be found in the ble_app_sleemode check the app_button_press_cb(), but even if not following that your device should be able to start advertising. If for example you invoke the user_app_adv_start() (which i suppose is the same with the user_advertise_operation that you have implemented) directly from the app_button_press_cb() and remove the app_easy_wakeup() the device will advertise. But the suggested way in using the app_easy_wakeup() API.
谢谢mt_dialog.
When no GPIO interrupts occurs and the device wakes up on the timed interval, all advertising event are seen on a beacon scanning app on my phone.
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,
如果代码确实是想和你做什么get the interrupt and the data that you would like and you see that the device is still advertising but with the old values then something should be wrong with how you place the data in the advertising string. After the advertising string has been updated with the new values i suppose that you stop the advertising update the advertising string with the new values and then you restart the advertising using the user_advertise_operation. You invoke the app_easy_gap_non_connectable_advertise_get_active() function in order for the SDK to fill in a new message and then you add the custom data in the advertising string, what you can do to debug this is to go step by step in the code and check that the cmd pointer that carries the advertise command includes at some point in the code the advertising data that you would like to place (check the cmd->host.adv_data array and check if your data are appended in this array).
谢谢mt_dialog.
So I tested what you suggested and found some strange behavior.
使用定时器唤醒时间间隔并禁用WKUPCT时,在User_update_ibeaCon_Adv_String中轮询GPIO,并相应地更新UUID上一个字节。我可以看到扫描仪应用程序中的这些更改,一切都应该工作。
Then I enable the wkupct with:
wkupct_register_callback(tilt_wakeup_cb);
wkupct_enable_irq(0x3f0000,0x3f0000,10);//为p2_0启用中断到p2_5
After this I no longer see the last byte of UUID change in the scanner app. Since the same code is used to update the advertise string and advertise, I would assume those two function to be working properly. Now to figure out why enabling the wkupct and calling the user_advertise_operation no longer works as it should.
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);
数据- > 雷电竞下载appcompany_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;
}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)){
data->uuid[15] = 5;
}如果(!gpio_getpinstatus(gpio_port_2,gpio_pin_5)){
数据 - > UUID [15] = 6;
}
tilt_wkup_flag = 0;
}else{
data->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.
I removed the call to user_advertise_operation(); in the tilt_wakeup_cb() and now see the expected change in the scanner app. The problem is that it finally gets recorded about 5-10 advertising intervals later. (I set the advertising interval at 5 seconds, and I receive the changed packet at about 55 seconds after the gpio is pulled low).
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);
// Start advertising for non-connectable peripheral.
if ( APP_CONNECTED == ke_state_get(TASK_APP))
{
//DO NOT advertise non-connectable advertisings in a connected state
}
else
{
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)
{
//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.
When GPIO2_0 goes low, I want to send out an advertisement with UUID ending with a 0. The phone app will record the time it received the advertisement. When another GPIO goes low, let's say GPIO2_1, I want to send out an advertisement with UUID ending in 1. The phone will record the time it received this and compute the time difference between the two advertisements. The time difference is critical for what I'm trying to do with the data. Is this a reliable way to accomplish this? Or is there some type of limitation that will not allow me to accomplish this goal?
再次感谢您继续支持。
嗨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,
Yes, there is no assurance that the advertising string is going to reach the central, due to a crowded mean, range or noise, the protocol doesn't have a mechanism in order for the central to ACK the peripheral that the emmited advertising string has received, this occurs only during connection.
谢谢mt_dialog.