Controlling Nimble BLE Advertising Scan Channels on S3
Controlling Nimble BLE Advertising Scan Channels on S3
How do I control the advertising scan channels for numble ble_gap_disc() on the S3?
There appears to be an undocumented API in the ROM -- ble_ll_scan_channel_setting(). Is that what I want? What are the parameters? Why isn't this documented?
There appears to be an undocumented API in the ROM -- ble_ll_scan_channel_setting(). Is that what I want? What are the parameters? Why isn't this documented?
Re: Controlling Nimble BLE Advertising Scan Channels on S3
> How do I control the advertising scan channels for numble ble_gap_disc() on the S3?
ble_gap_disc is used to discover / scan for devices in the vicinity. Per spec, during scanning there is no way host can set the channel, hence no such API exists in NimBLE / Bluedroid stack
However, if you refer to spec, then both LE Set Advertising params and LE set ext advertising params, has a way to set the advertising channel_map, where host can set the preferred channel. Peripheral can advertise on a particular channel.
> There appears to be an undocumented API in the ROM -- ble_ll_scan_channel_setting(). Is that what I want? What are the parameters? Why isn't this documented?
Because that code is not exposed and is part of proprietary Espressif closed library code. It is more for internal usage.
ble_gap_disc is used to discover / scan for devices in the vicinity. Per spec, during scanning there is no way host can set the channel, hence no such API exists in NimBLE / Bluedroid stack
However, if you refer to spec, then both LE Set Advertising params and LE set ext advertising params, has a way to set the advertising channel_map, where host can set the preferred channel. Peripheral can advertise on a particular channel.
> There appears to be an undocumented API in the ROM -- ble_ll_scan_channel_setting(). Is that what I want? What are the parameters? Why isn't this documented?
Because that code is not exposed and is part of proprietary Espressif closed library code. It is more for internal usage.
Re: Controlling Nimble BLE Advertising Scan Channels on S3
So what is the best way to build a battery powered temperature sensor which connects to an ESP based device? The ESP device is mains powered and also on wifi with a small amount of traffic. My goal here is to minimize the number of packets the temp sensor is sending. If I use BLE advertising to send the temperature I have to send three packets (37,38,39) because I don't know what channel the ESP is listening on. Even if I send three packets the ESP is only seeing the temp 75% of the time. So in the current model I have to send six packets to have a good chance of communicating to the ESP.
The temp sensor tracks the temp and when it changes 0.2C it sends the temp. That results in a packet on average of once about every six minutes. I don't want to set up a BLE connection because that takes even more power. Maximum connection interval is four seconds which is 20x as many packets.
So what is the best way to send a packet to the ESP when the ESP is listening? The only thing the BLE engine on the ESP is doing is listening for the temp sensor, it is not dealing with any other BLE traffic. One proposal I found when searching is to set the scan interval up as high as possible, and then cancel the scan before it switches channels. Keep doing that as a technique to prevent the scan channel from changing. Does the ESP scan in a pre-determined order allowing this technique to work?
The temp sensor is a multiprotocol radio and I put the S3 into a different mode than BLE? Temp sensor can't generate wifi packets.
The temp sensor tracks the temp and when it changes 0.2C it sends the temp. That results in a packet on average of once about every six minutes. I don't want to set up a BLE connection because that takes even more power. Maximum connection interval is four seconds which is 20x as many packets.
So what is the best way to send a packet to the ESP when the ESP is listening? The only thing the BLE engine on the ESP is doing is listening for the temp sensor, it is not dealing with any other BLE traffic. One proposal I found when searching is to set the scan interval up as high as possible, and then cancel the scan before it switches channels. Keep doing that as a technique to prevent the scan channel from changing. Does the ESP scan in a pre-determined order allowing this technique to work?
The temp sensor is a multiprotocol radio and I put the S3 into a different mode than BLE? Temp sensor can't generate wifi packets.
Re: Controlling Nimble BLE Advertising Scan Channels on S3
Hello @jonsmirl,
Please try below in your application.
typedef enum {
SCAN_ALL_CHANNLE,
ONLY_SCAN_CHANNEL_37,
ONLY_SCAN_CHANNEL_38,
ONLY_SCAN_CHANNEL_39,
SCAN_MODE_TYPE_ERROR,
} scan_mode_config_t;
extern uint8_t esp_ble_scan_channel_setting(scan_mode_config_t scan_mode);
So your application can be modified as:
On peripheral side, set the channel number you would be advertising on , say on channel 37 . This can be done by passing appropriate parameters when calling le set adv parameters.
The on central side, you invoke the above API , BEFORE starting scanning. I.e. set the channel number to scan on ,and then start scanning. Please let me know if any more query.
Thanks.
Please try below in your application.
typedef enum {
SCAN_ALL_CHANNLE,
ONLY_SCAN_CHANNEL_37,
ONLY_SCAN_CHANNEL_38,
ONLY_SCAN_CHANNEL_39,
SCAN_MODE_TYPE_ERROR,
} scan_mode_config_t;
extern uint8_t esp_ble_scan_channel_setting(scan_mode_config_t scan_mode);
So your application can be modified as:
On peripheral side, set the channel number you would be advertising on , say on channel 37 . This can be done by passing appropriate parameters when calling le set adv parameters.
The on central side, you invoke the above API , BEFORE starting scanning. I.e. set the channel number to scan on ,and then start scanning. Please let me know if any more query.
Thanks.
Re: Controlling Nimble BLE Advertising Scan Channels on S3
I have implemented esp_ble_scan_channel_setting() and verified that it works as expected. However, that does not seem to be the cause of my problems. If I set the sensor to Channel 37 and the S3 to Channel 39 I receive no packets, if I set them both to Channel 39 I see packets.
Also note that I have esp-matter also running on this S3. It is not doing much of anything but it does keep active wifi for things like MDNS.
As a test I have set my sensor to send three packets with 100ms spacing on channel 39 once per second. I have a sniffer which monitors these packets to verify they are being sent and are receivable. The sniffer is Nordic based and it never misses a single packet.
This is what I see on the S3. Note the Count column. If no packets are being dropped I should see each Count repeated three times at 100ms intervals. If you look between Count 262 and Count 265 I dropped ten packets in a row and received nothing for 2.8 seconds.
The scan should permanently be running on Channel 39. So why am I dropping so many packets? The RSSI is really good, the devices are only 40cm apart.
Also note that I have esp-matter also running on this S3. It is not doing much of anything but it does keep active wifi for things like MDNS.
As a test I have set my sensor to send three packets with 100ms spacing on channel 39 once per second. I have a sniffer which monitors these packets to verify they are being sent and are receivable. The sniffer is Nordic based and it never misses a single packet.
This is what I see on the S3. Note the Count column. If no packets are being dropped I should see each Count repeated three times at 100ms intervals. If you look between Count 262 and Count 265 I dropped ten packets in a row and received nothing for 2.8 seconds.
Code: Select all
I (1081616) ble_advert: BLE 34:f1:ae:d4:10:00 Count 257 RSSI 193 Temp 2086 Humid 39 Battery 3371
I (1081816) ble_advert: BLE 34:f1:ae:d4:10:00 Count 257 RSSI 193 Temp 2086 Humid 39 Battery 3371
I (1082636) ble_advert: BLE 34:f1:ae:d4:10:00 Count 258 RSSI 191 Temp 2085 Humid 39 Battery 3328
I (1082846) ble_advert: BLE 34:f1:ae:d4:10:00 Count 258 RSSI 192 Temp 2085 Humid 39 Battery 3328
I (1083766) ble_advert: BLE 34:f1:ae:d4:10:00 Count 259 RSSI 192 Temp 2087 Humid 39 Battery 3371
I (1083866) ble_advert: BLE 34:f1:ae:d4:10:00 Count 259 RSSI 192 Temp 2087 Humid 39 Battery 3371
I (1084676) ble_advert: BLE 34:f1:ae:d4:10:00 Count 260 RSSI 191 Temp 2084 Humid 39 Battery 3328
I (1084886) ble_advert: BLE 34:f1:ae:d4:10:00 Count 260 RSSI 191 Temp 2084 Humid 39 Battery 3328
I (1085706) ble_advert: BLE 34:f1:ae:d4:10:00 Count 261 RSSI 191 Temp 2084 Humid 39 Battery 3371
I (1085816) ble_advert: BLE 34:f1:ae:d4:10:00 Count 261 RSSI 191 Temp 2084 Humid 39 Battery 3371
I (1085926) ble_advert: BLE 34:f1:ae:d4:10:00 Count 261 RSSI 191 Temp 2084 Humid 39 Battery 3371
I (1086936) ble_advert: BLE 34:f1:ae:d4:10:00 Count 262 RSSI 192 Temp 2086 Humid 39 Battery 3328
I (1089786) ble_advert: BLE 34:f1:ae:d4:10:00 Count 265 RSSI 192 Temp 2085 Humid 39 Battery 3371
I (1090816) ble_advert: BLE 34:f1:ae:d4:10:00 Count 266 RSSI 192 Temp 2085 Humid 39 Battery 3328
I (1090926) ble_advert: BLE 34:f1:ae:d4:10:00 Count 266 RSSI 192 Temp 2085 Humid 39 Battery 3328
I (1091036) ble_advert: BLE 34:f1:ae:d4:10:00 Count 266 RSSI 191 Temp 2085 Humid 39 Battery 3328
I (1091836) ble_advert: BLE 34:f1:ae:d4:10:00 Count 267 RSSI 191 Temp 2084 Humid 39 Battery 3328
I (1091946) ble_advert: BLE 34:f1:ae:d4:10:00 Count 267 RSSI 191 Temp 2084 Humid 39 Battery 3328
I (1092046) ble_advert: BLE 34:f1:ae:d4:10:00 Count 267 RSSI 191 Temp 2084 Humid 39 Battery 3328
I (1092856) ble_advert: BLE 34:f1:ae:d4:10:00 Count 268 RSSI 191 Temp 2085 Humid 39 Battery 3328
I (1093066) ble_advert: BLE 34:f1:ae:d4:10:00 Count 268 RSSI 191 Temp 2085 Humid 39 Battery 3328
I (1093986) ble_advert: BLE 34:f1:ae:d4:10:00 Count 269 RSSI 192 Temp 2085 Humid 39 Battery 3328
I (1094096) ble_advert: BLE 34:f1:ae:d4:10:00 Count 269 RSSI 192 Temp 2085 Humid 39 Battery 3328
I (1095116) ble_advert: BLE 34:f1:ae:d4:10:00 Count 270 RSSI 192 Temp 2086 Humid 39 Battery 3328
I (1096136) ble_advert: BLE 34:f1:ae:d4:10:00 Count 271 RSSI 191 Temp 2085 Humid 39 Battery 3328
I (1096946) ble_advert: BLE 34:f1:ae:d4:10:00 Count 272 RSSI 191 Temp 2085 Humid 39 Battery 3328
Code: Select all
typedef enum {
SCAN_ALL_CHANNLE,
ONLY_SCAN_CHANNEL_37,
ONLY_SCAN_CHANNEL_38,
ONLY_SCAN_CHANNEL_39,
SCAN_MODE_TYPE_ERROR,
} scan_mode_config_t;
extern "C" uint8_t esp_ble_scan_channel_setting(scan_mode_config_t scan_mode);
esp_err_t StartScan()
{
uint8_t ownAddrType;
struct ble_gap_disc_params discParams;
int rc;
/* Figure out address to use while advertising. */
rc = ble_hs_id_infer_auto(0, &ownAddrType);
if (rc != 0)
{
// ChipLogError(DeviceLayer, "ble_hs_id_infer_auto failed: %d", rc);
return ESP_ERR_INVALID_STATE;
}
/* Set up discovery parameters. */
memset(&discParams, 0, sizeof(discParams));
/* Tell the controller to filter the duplicates. */
discParams.filter_duplicates = 0;
/* Perform passive scanning. */
discParams.passive = 1;
/* Use defaults for the rest of the parameters. */
discParams.itvl = 0;
discParams.window = 0;
discParams.filter_policy = 0;
discParams.limited = 0;
esp_ble_scan_channel_setting(ONLY_SCAN_CHANNEL_39);
/* Start the discovery process. */
rc = ble_gap_disc(ownAddrType, BLE_HS_FOREVER, &discParams, OnBleCentralEvent, NULL);
if (rc != 0)
{
ESP_LOGE(TAG, "ble_gap_disc failed: %d", rc);
return ESP_ERR_INVALID_STATE;
}
return ESP_OK;
}
Re: Controlling Nimble BLE Advertising Scan Channels on S3
Hello @jonsmirl,
Setting scan interval and window as 0 would result in default value. Can you modify them to 100 ms ( so set value as 160 decimal ).
Also, is this operation being done in open air ? which can result in packet loss ?
Can you shutdown matter activity on wifi also for testing purpose. We can confirm if coex activity is taking some bandwidth resulting in such behaviour as you observe.
Is the packet loss observed multiple times at your end ? or periodically ?
Setting scan interval and window as 0 would result in default value. Can you modify them to 100 ms ( so set value as 160 decimal ).
Also, is this operation being done in open air ? which can result in packet loss ?
Can you shutdown matter activity on wifi also for testing purpose. We can confirm if coex activity is taking some bandwidth resulting in such behaviour as you observe.
Is the packet loss observed multiple times at your end ? or periodically ?
Re: Controlling Nimble BLE Advertising Scan Channels on S3
Here's the periodicity of dropping packets. It is sending three packets once per second. These are the seconds when all three were dropped. First column is the seconds count, second is the delta seconds. The average delta is 25 seconds. Starts at 315. No code is changed from previous post.
Code: Select all
325
377 52
440 63
466 26
468 2
542 74
609 67
620 11
681 61
706 25
754 48
812 58
857 45
864 7
949 85
995 46
1033 38
1104 71
1130 26
1160 30
1168 8
1228 60
1262 34
1337 75
1386 49
1481 95
1535 54
1575 40
1581 6
1593 12
1597 4
1620 23
1645 25
1657 12
1659 2
1718 59
1736 18
1739 3
1796 57
1803 7
1849 46
1877 28
1881 4
1927 46
1938 11
1972 34
1991 19
1996 5
2040 44
2068 28
2070 2
2088 18
2091 3
2201 110
2207 6
2209 2
2246 37
2301 55
2305 4
2349 44
2372 23
2422 50
2443 21
2459 16
2462 3
2492 30
2494 2
2496 2
2499 3
2505 6
2507 2
2511 4
2535 24
2538 3
2543 5
2548 5
2550 2
2559 9
2561 2
2566 5
2569 3
2577 8
2606 29
2614 8
2617 3
2623 6
2648 25
2655 7
2658 3
2660 2
2667 7
2699 32
2705 6
2712 7
2732 20
2738 6
2740 2
2745 5
2748 3
2769 21
2776 7
2780 4
2786 6
2804 18
2806 2
2809 3
2818 9
2824 6
2826 2
2852 26
2856 4
2859 3
2877 18
2879 2
2882 3
2885 3
2890 5
2929 39
2952 23
2965 13
2984 19
2986 2
2990 4
2995 5
3024 29
3029 5
3031 2
3068 37
3102 34
3125 23
3134 9
3170 36
3205 35
3225 20
3234 9
3297 63
3321 24
3360 39
3365 5
3396 31
3415 19
3460 45
3484 24
3491 7
3493 2
3519 26
3556 37
3559 3
3595 36
3636 41
3650 14
3656 6
3667 11
3689 22
3695 6
3714 19
3720 6
3752 32
3760 8
3790 30
3824 34
3852 28
3885 33
3891 6
3930 39
3949 19
3954 5
4028 74
4048 20
4065 17
4120 55
4126 6
4134 8
4165 31
4173 8
4214 41
4256 42
4275 19
4295 20
4355 60
4379 24
4400 21
4415 15
4473 58
4496 23
4498 2
4535 37
4596 61
4613 17
4677 64
4679 2
4711 32
4731 20
4733 2
4782 49
4825 43
4831 6
4839 8
4842 3
4878 36
4884 6
4918 34
4954 36
4991 37
5025 34
5037 12
5060 23
5123 63
5141 18
5162 21
5164 2
5201 37
5203 2
5207 4
5215 8
5256 41
5263 7
5295 32
5340 45
5343 3
5376 33
5397 21
5438 41
5442 4
5482 40
5526 44
5601 75
5622 21
5638 16
5671 33
5716 45
5721 5
5754 33
5802 48
5828 26
5830 2
5838 8
5857 19
5908 51
5912 4
5951 39
5960 9
5993 33
6031 38
6053 22
6068 15
6092 24
6094 2
6102 8
6105 3
6143 38
6182 39
6218 36
6263 45
6288 25
6335 47
6376 41
6385 9
6387 2
6417 30
6423 6
6464 41
6554 90
6559 5
6579 20
6582 3
6587 5
6601 14
6606 5
6610 4
6646 36
6694 48
6773 79
6783 10
6807 24
6824 17
6900 76
6926 26
6930 4
6940 10
7021 81
7024 3
7061 37
7064 3
7100 36
7110 10
7149 39
7198 49
7220 22
7243 23
7245 2
7286 41
7306 20
7333 27
7335 2
7384 49
7435 51
7438 3
7467 29
7475 8
7479 4
7521 42
7563 42
7629 66
7646 17
7674 28
7686 12
7707 21
7713 6
7727 14
7762 35
7801 39
7854 53
7873 19
7903 30
7925 22
7987 62
8010 23
8015 5
8114 99
8120 6
8129 9
8131 2
8133 2
8185 52
8188 3
8221 33
8255 34
8261 6
8277 16
8300 23
8325 25
8327 2
8378 51
8420 42
8441 21
8468 27
8490 22
8496 6
8498 2
8510 12
8519 9
8523 4
8525 2
8528 3
8557 29
8562 5
8569 7
8662 93
8668 6
8671 3
8754 83
8764 10
8803 39
8805 2
8844 39
8858 14
8869 11
8897 28
8908 11
8942 34
8950 8
8981 31
9000 19
9004 4
9030 26
9045 15
9079 34
9171 92
9216 45
9224 8
9302 78
9312 10
9314 2
9324 10
9351 27
9353 2
9435 82
9437 2
9535 98
9539 4
9568 29
9584 16
9661 77
9664 3
9710 46
9722 12
9764 42
9769 5
9803 34
9822 19
9850 28
9859 9
9864 5
9867 3
9870 3
9921 51
9924 3
9932 8
9979 47
9983 4
10000 17
10035 35
10043 8
10077 34
10087 10
10092 5
10154 62
10163 9
10201 38
10251 50
10253 2
10257 4
10271 14
10329 58
10384 55
10390 6
10392 2
10451 59
10458 7
10460 2
10462 2
10515 53
10525 10
10529 4
10597 68
10642 45
10646 4
10760 114
10777 17
10840 63
10883 43
10892 9
10909 17
10982 73
11016 34
Re: Controlling Nimble BLE Advertising Scan Channels on S3
Changing intvl and window to 160 doesn't seem to have any impact. Average of 33 seconds.
Code: Select all
8
30 22
51 21
90 39
134 44
142 8
148 6
154 6
156 2
198 42
298 100
348 50
392 44
463 71
475 12
534 59
576 42
614 38
649 35
699 50
725 26
818 93
820 2
862 42
881 19
938 57
966 28
973 7
986 13
Re: Controlling Nimble BLE Advertising Scan Channels on S3
Next I made a BLE only test program by stripping down the blecent example.
I ran it for 20 minutes on bare S3 WROOM dev module.
3.1% packet loss. Once during the 20 minutes it lost all three.
Then I ran the same program on the target hardware which is inside a plastic case and uses a MINI module.
3.3% packet loss. Once during the 20 minutes it lost all three.
So maybe the plastic case is causing a little extra loss but nothing significant.
Code: Select all
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "esp_log.h"
#include "nvs_flash.h"
/* BLE */
#include "nimble/nimble_port.h"
#include "nimble/nimble_port_freertos.h"
#include "host/ble_hs.h"
#include "host/util/util.h"
#include "console/console.h"
#include "services/gap/ble_svc_gap.h"
#include "blecent.h"
static const char *TAG = "ble_cent";
void ReportDevice(const struct ble_hs_adv_fields *fields, const ble_addr_t *addr, uint8_t rssi)
{
if (fields->mfg_data != NULL)
{
if ((fields->mfg_data[0] == 0x4c) && (fields->mfg_data[1] == 0xd))
{
int i = 2;
uint16_t temp, humid, battery, count;
temp = humid = battery = count = 0;
while (i < fields->mfg_data_len)
{
switch (fields->mfg_data[i])
{
case 2:
temp = *(uint16_t *)&fields->mfg_data[i + 1];
break;
case 5:
humid = *(uint16_t *)&fields->mfg_data[i + 1];
break;
case 0xfe:
count = *(uint16_t *)&fields->mfg_data[i + 1];
break;
default:
case 0xff:
battery = *(uint16_t *)&fields->mfg_data[i + 1];
break;
}
i += 3;
}
ESP_LOGI(TAG, "BLE %s Count %u RSSI %u Temp %u Humid %u Battery %u", addr_str((void *)addr), count, rssi, temp, humid, battery);
}
}
}
/**
* The nimble host executes this callback when a GAP event occurs. The
* application associates a GAP event callback with each connection that is
* established. blecent uses the same callback for all connections.
*
* @param event The event being signalled.
* @param arg Application-specified argument; unused by
* blecent.
*
* @return 0 if the application successfully handled the
* event; nonzero on failure. The semantics
* of the return code is specific to the
* particular GAP event being signalled.
*/
static int
blecent_gap_event(struct ble_gap_event *event, void *arg)
{
struct ble_gap_conn_desc desc;
struct ble_hs_adv_fields fields;
int rc;
switch (event->type) {
case BLE_GAP_EVENT_DISC:
ble_hs_adv_parse_fields(&fields, event->disc.data, event->disc.length_data);
ReportDevice(&fields, &event->disc.addr, event->disc.rssi);
return 0;
default:
return 0;
}
}
typedef enum {
SCAN_ALL_CHANNLE,
ONLY_SCAN_CHANNEL_37,
ONLY_SCAN_CHANNEL_38,
ONLY_SCAN_CHANNEL_39,
SCAN_MODE_TYPE_ERROR,
} scan_mode_config_t;
extern uint8_t esp_ble_scan_channel_setting(scan_mode_config_t scan_mode);
/**
* Initiates the GAP general discovery procedure.
*/
static void
blecent_scan(void)
{
uint8_t own_addr_type;
struct ble_gap_disc_params disc_params;
int rc;
/* Figure out address to use while advertising (no privacy for now) */
rc = ble_hs_id_infer_auto(0, &own_addr_type);
if (rc != 0) {
MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc);
return;
}
/* Tell the controller to filter duplicates; we don't want to process
* repeated advertisements from the same device.
*/
disc_params.filter_duplicates = 0;
/**
* Perform a passive scan. I.e., don't send follow-up scan requests to
* each advertiser.
*/
disc_params.passive = 1;
/* Use defaults for the rest of the parameters. */
disc_params.itvl = 160;
disc_params.window = 160;
disc_params.filter_policy = 0;
disc_params.limited = 0;
esp_ble_scan_channel_setting(ONLY_SCAN_CHANNEL_39);
rc = ble_gap_disc(own_addr_type, BLE_HS_FOREVER, &disc_params,
blecent_gap_event, NULL);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Error initiating GAP discovery procedure; rc=%d\n",
rc);
}
}
void blecent_host_task(void *param)
{
ESP_LOGI(TAG, "BLE Host Task Started");
/* This function will return only when nimble_port_stop() is executed */
nimble_port_run();
nimble_port_freertos_deinit();
}
static void
blecent_on_reset(int reason)
{
MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
}
static void
blecent_on_sync(void)
{
int rc;
/* Make sure we have proper identity address set (public preferred) */
rc = ble_hs_util_ensure_addr(0);
assert(rc == 0);
/* Begin scanning for a peripheral to connect to. */
blecent_scan();
}
void
app_main(void)
{
int rc;
/* Initialize NVS — it is used to store PHY calibration data */
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
ret = nimble_port_init();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to init nimble %d ", ret);
return;
}
/* Configure the host. */
ble_hs_cfg.reset_cb = blecent_on_reset;
ble_hs_cfg.sync_cb = blecent_on_sync;
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
nimble_port_freertos_init(blecent_host_task);
}
3.1% packet loss. Once during the 20 minutes it lost all three.
Then I ran the same program on the target hardware which is inside a plastic case and uses a MINI module.
3.3% packet loss. Once during the 20 minutes it lost all three.
So maybe the plastic case is causing a little extra loss but nothing significant.
Re: Controlling Nimble BLE Advertising Scan Channels on S3
Next I started with the esp-matter/example/light code and added this file:
Starting it from app_main.cpp with this:
Used menuconfig to tell esp-matter to leave ble running.
I commissioned it so that wifi would start
Now look at the difference, between 6461 and 6463 it dropped ten packets in a row, and between 6449 and 6461 it dropped over 30 in a row. It is dropping about 20% of all packets. Note that Matter was not actively sending packets during this period because Matter prints when it sends. MDNS doesn't print, so it could be active.
This is 100% espressif code except for the file above and it is on a S3 WROOM dev board.
Are Matter and MDNS coordinating on wifi coexistence?
Code: Select all
#include <esp_err.h>
#include <esp_log.h>
#include <host/ble_gap.h>
static const char *TAG = "ble_advert";
static void
print_uuid(const ble_uuid_t *uuid)
{
char buf[BLE_UUID_STR_LEN];
printf("%s", ble_uuid_to_str(uuid, buf));
}
static void
print_bytes(const uint8_t *bytes, int len)
{
int i;
for (i = 0; i < len; i++)
{
printf("%s0x%02x", i != 0 ? ":" : "", bytes[i]);
}
}
static char *
addr_str(const void *addr)
{
static char buf[6 * 2 + 5 + 1];
const uint8_t *u8p;
u8p = (uint8_t *)addr;
sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
return buf;
}
static void
print_adv_fields(const struct ble_hs_adv_fields *fields)
{
char s[BLE_HS_ADV_MAX_SZ];
const uint8_t *u8p;
int i;
printf("BLE Advert\n");
if (fields->flags != 0)
{
printf(" flags=0x%02x\n", fields->flags);
}
if (fields->uuids16 != NULL)
{
printf(" uuids16(%scomplete)=",
fields->uuids16_is_complete ? "" : "in");
for (i = 0; i < fields->num_uuids16; i++)
{
print_uuid(&fields->uuids16[i].u);
printf(" ");
}
printf("\n");
}
if (fields->uuids32 != NULL)
{
printf(" uuids32(%scomplete)=",
fields->uuids32_is_complete ? "" : "in");
for (i = 0; i < fields->num_uuids32; i++)
{
print_uuid(&fields->uuids32[i].u);
printf(" ");
}
printf("\n");
}
if (fields->uuids128 != NULL)
{
printf(" uuids128(%scomplete)=",
fields->uuids128_is_complete ? "" : "in");
for (i = 0; i < fields->num_uuids128; i++)
{
print_uuid(&fields->uuids128[i].u);
printf(" ");
}
printf("\n");
}
if (fields->name != NULL)
{
assert(fields->name_len < sizeof s - 1);
memcpy(s, fields->name, fields->name_len);
s[fields->name_len] = '\0';
printf(" name(%scomplete)=%s\n",
fields->name_is_complete ? "" : "in", s);
}
if (fields->tx_pwr_lvl_is_present)
{
printf(" tx_pwr_lvl=%d\n", fields->tx_pwr_lvl);
}
if (fields->slave_itvl_range != NULL)
{
printf(" slave_itvl_range=");
print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
printf("\n");
}
if (fields->svc_data_uuid16 != NULL)
{
printf(" svc_data_uuid16=");
print_bytes(fields->svc_data_uuid16, fields->svc_data_uuid16_len);
printf("\n");
}
if (fields->public_tgt_addr != NULL)
{
printf(" public_tgt_addr=");
u8p = fields->public_tgt_addr;
for (i = 0; i < fields->num_public_tgt_addrs; i++)
{
printf("public_tgt_addr=%s ", addr_str(u8p));
u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN;
}
printf("\n");
}
if (fields->appearance_is_present)
{
printf(" appearance=0x%04x\n", fields->appearance);
}
if (fields->adv_itvl_is_present)
{
printf(" adv_itvl=0x%04x\n", fields->adv_itvl);
}
if (fields->svc_data_uuid32 != NULL)
{
printf(" svc_data_uuid32=");
print_bytes(fields->svc_data_uuid32, fields->svc_data_uuid32_len);
printf("\n");
}
if (fields->svc_data_uuid128 != NULL)
{
printf(" svc_data_uuid128=");
print_bytes(fields->svc_data_uuid128, fields->svc_data_uuid128_len);
printf("\n");
}
if (fields->uri != NULL)
{
printf(" uri=");
print_bytes(fields->uri, fields->uri_len);
printf("\n");
}
if (fields->mfg_data != NULL)
{
printf(" mfg_data=");
print_bytes(fields->mfg_data, fields->mfg_data_len);
printf("\n");
}
}
void ReportDevice(const struct ble_hs_adv_fields *fields, const ble_addr_t *addr, uint8_t rssi)
{
if (fields->mfg_data != NULL)
{
if ((fields->mfg_data[0] == 0x4c) && (fields->mfg_data[1] == 0xd))
{
int i = 2;
uint16_t temp, humid, battery, count;
temp = humid = battery = count = 0;
while (i < fields->mfg_data_len)
{
switch (fields->mfg_data[i])
{
case 2:
temp = *(uint16_t *)&fields->mfg_data[i + 1];
break;
case 5:
humid = *(uint16_t *)&fields->mfg_data[i + 1];
break;
case 0xfe:
count = *(uint16_t *)&fields->mfg_data[i + 1];
break;
default:
case 0xff:
battery = *(uint16_t *)&fields->mfg_data[i + 1];
break;
}
i += 3;
}
ESP_LOGI(TAG, "BLE %s Count %u RSSI %u Temp %u Humid %u Battery %u", addr_str((void *)addr), count, rssi, temp, humid, battery);
}
}
}
void RemoveDevice()
{
// TODO
}
int OnBleCentralEvent(struct ble_gap_event *event, void *arg)
{
switch (event->type)
{
case BLE_GAP_EVENT_DISC_COMPLETE:
{
return 0;
}
case BLE_GAP_EVENT_DISC:
{
/* Try to connect to the advertiser if it looks interesting. */
struct ble_hs_adv_fields fields;
ble_hs_adv_parse_fields(&fields, event->disc.data, event->disc.length_data);
ReportDevice(&fields, &event->disc.addr, event->disc.rssi);
return 0;
}
}
return 0;
}
typedef enum {
SCAN_ALL_CHANNLE,
ONLY_SCAN_CHANNEL_37,
ONLY_SCAN_CHANNEL_38,
ONLY_SCAN_CHANNEL_39,
SCAN_MODE_TYPE_ERROR,
} scan_mode_config_t;
extern "C" uint8_t esp_ble_scan_channel_setting(scan_mode_config_t scan_mode);
esp_err_t StartScan()
{
uint8_t ownAddrType;
struct ble_gap_disc_params discParams;
int rc;
/* Figure out address to use while advertising. */
rc = ble_hs_id_infer_auto(0, &ownAddrType);
if (rc != 0)
{
// ChipLogError(DeviceLayer, "ble_hs_id_infer_auto failed: %d", rc);
return ESP_ERR_INVALID_STATE;
}
/* Set up discovery parameters. */
memset(&discParams, 0, sizeof(discParams));
/* Tell the controller to filter the duplicates. */
discParams.filter_duplicates = 0;
/* Perform passive scanning. */
discParams.passive = 1;
/* Use defaults for the rest of the parameters. */
discParams.itvl = 160;
discParams.window = 160;
discParams.filter_policy = 0;
discParams.limited = 0;
esp_ble_scan_channel_setting(ONLY_SCAN_CHANNEL_39);
/* Start the discovery process. */
rc = ble_gap_disc(ownAddrType, BLE_HS_FOREVER, &discParams, OnBleCentralEvent, NULL);
if (rc != 0)
{
ESP_LOGE(TAG, "ble_gap_disc failed: %d", rc);
return ESP_ERR_INVALID_STATE;
}
return ESP_OK;
}
esp_err_t StopScan()
{
int rc = ble_gap_disc_cancel();
if (rc != 0)
{
//(DeviceLayer, "ble_gap_disc_cancel failed: %d", rc);
return ESP_ERR_INVALID_STATE;
}
// mDelegate->OnScanComplete();
return ESP_OK;
}
Code: Select all
case chip::DeviceLayer::DeviceEventType::kServerReady:
ESP_LOGI(TAG, "Server ready");
StartScan();
break;
I commissioned it so that wifi would start
Code: Select all
I (574396) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6440 RSSI 196 Temp 2129 Humid 37 Battery 3371
I (574506) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6440 RSSI 200 Temp 2129 Humid 37 Battery 3371
I (574616) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6440 RSSI 199 Temp 2129 Humid 37 Battery 3371
I (575516) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6441 RSSI 200 Temp 2129 Humid 37 Battery 3371
I (575626) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6441 RSSI 200 Temp 2129 Humid 37 Battery 3371
I (576436) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6442 RSSI 200 Temp 2129 Humid 37 Battery 3371
I (576546) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6442 RSSI 200 Temp 2129 Humid 37 Battery 3371
I (576646) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6442 RSSI 200 Temp 2129 Humid 37 Battery 3371
I (577456) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6443 RSSI 200 Temp 2129 Humid 37 Battery 3371
I (577566) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6443 RSSI 200 Temp 2129 Humid 37 Battery 3371
I (577666) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6443 RSSI 200 Temp 2129 Humid 37 Battery 3371
I (583686) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6449 RSSI 199 Temp 2130 Humid 37 Battery 3371
I (595826) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6461 RSSI 195 Temp 2129 Humid 37 Battery 3371
I (595936) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6461 RSSI 198 Temp 2129 Humid 37 Battery 3371
I (597976) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6463 RSSI 199 Temp 2130 Humid 37 Battery 3371
I (598886) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6464 RSSI 199 Temp 2130 Humid 37 Battery 3371
I (598996) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6464 RSSI 199 Temp 2130 Humid 37 Battery 3371
I (599096) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6464 RSSI 199 Temp 2130 Humid 37 Battery 3371
I (599906) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6465 RSSI 199 Temp 2130 Humid 37 Battery 3371
I (600016) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6465 RSSI 199 Temp 2130 Humid 37 Battery 3371
I (600116) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6465 RSSI 199 Temp 2130 Humid 37 Battery 3371
I (600926) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6466 RSSI 199 Temp 2130 Humid 37 Battery 3371
I (601036) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6466 RSSI 199 Temp 2130 Humid 37 Battery 3371
I (601146) ble_advert: BLE 34:f1:ae:d4:10:00 Count 6466 RSSI 199 Temp 2130 Humid 37 Battery 3371
This is 100% espressif code except for the file above and it is on a S3 WROOM dev board.
Are Matter and MDNS coordinating on wifi coexistence?
Who is online
Users browsing this forum: Google [Bot], letter57 and 214 guests