I would like to change the advertising's last byte of the UUID when I wake up from a GPIO interrupt to indicate which GPIO woke it up. Using the beacon_v_5.40.2_0 project, I'm declaring the callback as follow:
void tilt_wakeup_cb(void)
{
if(getBits16(sys_stat_reg,per_is_down))
{
//从外部唤醒GPIO返回GPIO功能
if (DEVELOPMENT_DEBUG)
GPIO_reservations();
periph_init();
}
tilt_wkup_flag = 1;
user_advertise_operation();
}
Is this allowed?
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)
{
.......
/ /一个dded by DL
if(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)){
data->uuid[15] = 2;
}如果(!gpio_getpinstatus(gpio_port_2,gpio_pin_2)){
data->uuid[15] = 3;
}如果(!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)){
数据- > 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,1,0); // Enable interrupt for P2_0 to P2_5
我修改了回调follow, but still doesn't seem to work. Tracing with Jlink, I can see it go into the callback function, but it doesn't advertise the new UUID:
嗨dio,
如果发生唤醒中断,则需要调试此操作,可以在User_update_ibeacon_add()中放置一个断点,并检查代码是否通过该函数,并且如果满足条件以更改广告字符串。
Thanks MT_dialog
好的,所以不应该有任何problem in calling user_advertise_operation(); inside the callback right? The radio and everything should be on and it should advertise when set up the way I have it?
只是确保我没有违反一些规则,从GPIO中断唤醒后我们无法宣传。
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.
Thanks 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.
当GPIO中断确实发生时,踩到代码时,似乎代码会做它应该是什么,但我从未在扫描仪应用中看到正确的值......
Somehow I don't think the data is being advertised in this scenario. The app_easy_gap_non_connectable_advertise_start() is used for both scenario. For the GPIO interrupt case I changed the cmd->intv_min and cmd->intv_max to 0. or leave those two blank, no luck either way.
Here is the code.
Hi 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).
Thanks MT_dialog
所以我测试了你建议的东西,发现了一些奇怪的行为。
When using timer wakeup interval and disabling the wkupct, the GPIO is polled in user_update_ibeacon_adv_string and the UUID last byte is updated accordingly. I can see these changes in the scanner app, everything works as it should.
Then I enable the wkupct with:
wkupct_register_callback(tilt_wakeup_cb);
wkupct_enable_irq(0x3F0000,0x3F0000,1,0); // Enable interrupt for P2_0 to 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.
我尝试追踪CMD->信息 - >主机 - > ADV_DATA,但没有一个值似乎匹配UUID或任何识别的任何识别。
The code only uses the dialog code user_advertise_operation(); no modifications to it.
I modified the dialog provided code 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);
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, config.uuid, 16);
/ /一个dded by DL
if(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)){
data->uuid[15] = 2;
}如果(!gpio_getpinstatus(gpio_port_2,gpio_pin_2)){
data->uuid[15] = 3;
}如果(!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)){
数据- > uuid [15] = 6;
}
tilt_wkup_flag = 0;
}else{
data->uuid[15] = 0;
}
//
data-> tx_power = config.power;
}
Wrote the wkupct callback:
void tilt_wakeup_cb(void)
{
if(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); //set default sleep mode
arch_ble_force_wakeup(); //force the BLE to wake up
ARCH_BLE_EXT_WAKEUP_OFF();//禁用外部唤醒
}
tilt_wkup_flag = 1;
user_advertise_operation();
wkupct_enable_irq(0x003f0000,0x003f0000,10);//为p2_0启用中断到p2_5
}
Thanks for your continued support!
发现有点信息。
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).
这似乎表明,在将实际事件放在队列中之前需要刷新的广告数据的缓冲区?这似乎是对吗?
You mentioned I should stop the advertising, update the advertising string and then restart the advertising. Am I interpreting this correctly if I do the following?
app_easy_gap_advertise_stop();
user_advertise_operation();
The code for user_advertise_operation(); is the default Dialog one:
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)
{
//获取指向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);
//Start advertising for non-connectable peripheral.
if(app_connected == ke_state_get(task_app))
{
//不要在连接状态广告不可连接的广告
}
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)
{
//获取指向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_undircated_advertise_start();
}
}
关于我想做的事情的背景,请告诉我是否有可能。
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?
Thanks again for your continued support.
Hi dlo,
关于在580上更新广告字符串,为了正确地停止,更新广告字符串并再次启动广告,您将不得不发出停止,然后等待堆栈回复广告确实停止了(SDK Will通知您广告已停止使用APP_ONC_ADV_UNDIRECT为无向广告,对于不可连接的广告,还有CORRSPONDING回调 - 请检查鞍骨灯,以便具有比标识更简单的引用)。因此,当堆栈通知您广告已完成并发生回调时,从该回调开始,您可以调用您将更新的新广告字符串的启动。您无法调用停止广告,然后将函数拨打函数开始。我想这是你的主要问题。
Regarding what you are trying to implement and time the difference between two advertising data, be aware that the advertising is not a reliable way to send data, that means that there is no guarantee that the data that you will send will reach the scanner at that particular time, since there will be collisions between other advertising devices and protocols emmiting at that time in general interierence to the mean, so with the advertising procedure there is no assurance that whatever the peripheral will send the scanner will most definatelly receive. So please be aware of that.
Thanks MT_dialog
谢谢你继续支持。我尝试在鞍骨项目中实现示例,但它仍然没有工作。我不知道还有什么要尝试,但是因为你提到没有保证到达扫描仪的数据,我们需要解决其他问题。
Hi 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.
Thanks MT_dialog