• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

CH582M (СH581, CH582, СH583)

il-2

New member
Еще насчет библиотеки BLE у меня есть такое предположение (которое подтверждается на практике):
В настроиках библиотеки есть параметр BLE_BUFF_MAX_LEN, который (как описано в комментарии) связан с тем, какой ATT_MTU будет поддерживаться. При этом я убедился, что за connection interval не передается болше, чем указано в этом параметре. Переключение на PHY-2M не помогает. За connection interval передается только BLE_BUFF_MAX_LEN байт, да и то не всегда. Если будет выполнено соединение с устройством BLE ниже 4.2 (без поддержки DLE), то и этот объем данных не получится протащить.
Здесь будет уже играть роль ограничение по BLE_TX_NUM_EVENT - я экспериментально установил что за connection interval передается не более BLE_TX_NUM_EVENT + 1 пакетов.
Есть еще BLE_BUFF_NUM, который желательно установить = BLE_TX_NUM_EVENT + 1
т.е получается 2 ограничения на пропускную способность, которые действуют одновременно:
1. За connection interval может быть передано не более BLE_BUFF_MAX_LEN (или вернее - не более установленного при соединении ATT_MTU). Это судя по всему какое-то искусственное ограничения библиотеки BLE. Вывод - надо устанавливать это значение максимальным, чтобы было преимущество при соединениях с устройствами, поддерживающими ATT_MTU выше 23 байта.
2. Собственно физическое ограничение канала PHY-1M (PHY-2M не в счет). Чтобы упереться в это ограничение при определенных параметрах соединения, надо задаться - какой у вас может быть connection interval (для Win10 и своих устройств - 7.5мс, для Андроид - не помню, но там почти в 2 раза больше). Значение BLE_TX_NUM_EVENT нужно выбрать, исходя из того сколько пакетов размером 23 байта передается за 1 такой connection interval при PHY-1M. Не помню сейчас своих замеров, но у меня в настройках используется BLE_TX_NUM_EVENT = 4 (5 пакетов по 23 байта за 1 connection interval(7.5мс??? не помню). Больше не пролезало.
Если у вас connection interval более длинный, то имеет смысл увеличить BLE_TX_NUM_EVENT.
Использование PHY-2M не дает увеличения пропускной способности, ибо при его использовании вроде бы можно прогнать больше даннных за 1 connection interval, но тут вступает в действие ограничение по BLE_BUFF_MAX_LEN
Тем не менее я у себя выполняю переключение на PHY-2M, думаю что это полезно в плане времени занятия радио-каналов.
 

pvvx

Активный участник сообщества
@il-2 всё, описываемое вами, было учтено изначально.
Основными настройками в принципе являются:
#define HAL_KEY FALSE // отключить обработку этого события по софт-таймеру (незачем тратить время работы CPU и объем таблицы событий)
#define HAL_LED FALSE // отключить обработку этого события
#define BLE_CALIBRATION_ENABLE TRUE // калибровку лучше оставить
#define BLE_CALIBRATION_PERIOD 120000
#define BLE_MEMHEAP_SIZE (1024*6*2) // используйте максимум по имеющейся памяти
#define BLE_BUFF_MAX_LEN 516 // это предел, больше не выйдет
#define BLE_BUFF_NUM 16 // даже это кол-во уже не наблюдается при реальных соединениях, но пущай будет
#define BLE_TX_NUM_EVENT 16 // даже это кол-во уже не наблюдается при реальных соединениях, но пущай будет
 

pvvx

Активный участник сообщества
2. Собственно физическое ограничение канала PHY-1M (PHY-2M не в счет). Чтобы упереться в это ограничение при определенных параметрах соединения, надо задаться - какой у вас может быть connection interval (для Win10 и своих устройств - 7.5мс, для Андроид - не помню, но там почти в 2 раза больше). Значение BLE_TX_NUM_EVENT нужно выбрать, исходя из того сколько пакетов размером 23 байта передается за 1 такой connection interval при PHY-1M. Не помню сейчас своих замеров, но у меня в настройках используется BLE_TX_NUM_EVENT = 4 (5 пакетов по 23 байта за 1 connection interval(7.5мс??? не помню). Больше не пролезало.
По качеству софта и дров для BLE:
1. Для Andriod: от 7.5 мс. Advertising Interval до 10 секунд включительно. Andriod имеет самый быстрый стек и поддерживает все новые стандарты Bluetooth SIG (зависит только от времени выпуска вашего устройства) Для соединения требуется прием одного Advertising.
2. Для Windows: от 7.5 мс. Advertising Interval у многих до 7..8 секунд, зависит от адаптера. Т.е. некоторые берут и 10 секунд. Для соединения требуется не менее 2-х Advertising.
3. Для Linux: от 7.5 мс. Advertising Interval по умолчанию до 4 секунд. Но можно изменить, покопавшись в настройках. Для соединения требуется прием не менее 2-х Advertising. Частичная поддержка только BT4.2.
4. Для Aplle - от 12 и более.


См. документацию от Apple: Accessory Design Guidelines for Apple Devices ->

11.5 Advertising Interval
● 152.5 ms
● 211.25 ms
● 318.75 ms
● 417.5 ms
● 546.25 ms
● 760 ms
● 852.5 ms
● 1022.5 ms
● 1285 ms

11.6 Connection Parameters

The connection parameter request may be rejected if it does not comply with all of these rules:
● Slave Latency ≤30
● 2 seconds ≤ connSupervisionTimeout ≤ 6 seconds
● Interval Min modulo 15 ms == 0
● Interval Min ≥15 ms
● One of the following:
● Interval Min + 15 ms ≤ Interval Max
● Interval Min == Interval Max == 15 ms
● Interval Max * (Slave Latency + 1) ≤ 2 seconds
● Interval Max * (Slave Latency + 1) * 3 < connSupervisionTimeout
Note that if an accessory requests Interval Min == Interval Max == 15 ms, some devices will scale the interval
to 30 ms to balance power and performance constraints


И реально 7.5 мс не работает на многих испытуемых. Кроме того не поддерживается переключение интервалов на ходу и многое другое.
 

pvvx

Активный участник сообщества
Для Apple всё совсем плохо с BLE (и многим другим). Это связано с тем, что устанавливаются самые старые адаптеры и из-за слабых процов и малой RAM софт сокращен - всё вырезано и обглодано до предела для сохранения хотя-бы какой производительности.
 

pvvx

Активный участник сообщества
2. Собственно физическое ограничение канала PHY-1M (PHY-2M не в счет). Чтобы упереться в это ограничение при определенных параметрах соединения, надо задаться - какой у вас может быть connection interval (для Win10 и своих устройств - 7.5мс, для Андроид - не помню, но там почти в 2 раза больше). Значение BLE_TX_NUM_EVENT нужно выбрать, исходя из того сколько пакетов размером 23 байта передается за 1 такой connection interval при PHY-1M. Не помню сейчас своих замеров, но у меня в настройках используется BLE_TX_NUM_EVENT = 4 (5 пакетов по 23 байта за 1 connection interval(7.5мс??? не помню). Больше не пролезало.
Если у вас connection interval более длинный, то имеет смысл увеличить BLE_TX_NUM_EVENT.
Влезает и более. В итоге BLE_TX_NUM_EVENT лучше ставить от 12.
И как будет работать передача - одним пакетом по 500 байт или кусочками - зависит от многих факторов:
1. Кусочками - если BT адаптер прикидывается что он имеет BT5.0+ и какая ОС + дрова у него. Для всех 99% китайских USB-BT данные чипы WCH будут передавать кусочками.
2. Если адаптер реально BT5.0+ - тогда блоком по 500 байт. Наипростейший из USB-BT, поддерживающий прием-передачу большими блоками в Windows и т.д. относится RTL8761В. И большинство устройств с Android.
Часть, старое фото, использованных для тестов адаптеров USB-BT:
1759740958756.png
Ныне их уже накопилось больше...
Использование PHY-2M не дает увеличения пропускной способности, ибо при его использовании вроде бы можно прогнать больше даннных за 1 connection interval, но тут вступает в действие ограничение по BLE_BUFF_MAX_LEN
Тем не менее я у себя выполняю переключение на PHY-2M, думаю что это полезно в плане времени занятия радио-каналов.
Это практически бесполезно. Особой прибавки с описанными WCH чипами это не дает, но дико сокращает дистанцию связи. Точно не скажу, но прибавка по оценкам тестов на вскидку составляет не более 10% (за счет общей скорости обоих адаптеров). Тут необходимо делать специальные тесты со множеством адаптеров и ОС, на что нет времени и желания.
И рассчитывать, что у пользователя адаптер поддерживает BT5.0+ не стоит. По этому желательно использовать PHY 1M.


Data_Packet_Time = время передачи пустого пакета + IFS + время передачи фактического пакета данных + IFS.

При PHY: 2 Мбит / с, ATT MTU = 507 байт:

= 44 + 150 + (1 + 4 + 2 + 4 + 507 + 3) * 8 / 2 + 150 = 2428 микросекунд

При PHY: 1 Мбит / с, ATT MTU = 507 байт:

= 80 + 150 + (1 + 4 + 2 + 4 + 507 + 3) * 8 + 150 = 4548 микросекунд

Т.е. оба варианта лезут в 7.5 мс.
 

pvvx

Активный участник сообщества
Так же замечено, что иногда у WCH, с нормальным адаптером BT5.0+ проскакивает условно полтора пакета (полтора MTU) в интервал 7.5 мс. А должен быть заполнен весь интервал.

Т.е. это ограничение WCH со всех сторон. И более теоретических 507/0.0075=67600 байт в секунду на данных чипах WCH не получить. А реальное теоретическое значение для других BLE чипов находится за 140 килобайт в сек.
И у WCH имеем ограничение стека + кошмар от TMOS.
 

pvvx

Активный участник сообщества
Еще такие моменты:
- я для тестирования своих железок пишу код в VisualStudio и использую библиотеку SimpleBLE. При этом у меня цикл запрос-ответ занимает 3 connection interval. Мой коллега-программист пишет основную программу на NET (точе через какую-то библиотеку) - и у него цикл запрос-ответ занимает 2 connection interval, и скорость 310кбод именно для этого случая.
Подтверждение приема, а так-же прочие тайминги, передает/определяет сам адаптер и внешнее ПО на скорость и объем переданного потока роли не играет.
310 кбод -это всего типа 31 килобайт в секунду - для любого нормального чипа BLE это начальный уровень. Некоторые реализации OTA имеют скорости потока ограниченные самой SPI-Flash (типичное время стирания и записи сектора около 100 килобайт в сек, но надо убавить с учетом того, что во время записи и стирания код стека может быть недоступен, а работают только прерывания и части кода в RAM).
 

il-2

New member
Подтверждение приема, а так-же прочие тайминги, передает/определяет сам адаптер и внешнее ПО на скорость и объем переданного потока роли не играет.
Не-не. Цикл "запрос-ответ" - это наш протокол обмена, который я с UART заворачиваю на BLE. Запрос - это запись характеристики, ответ - это нотификация. Все это вместе длится 2 connection interval или более. Это наверное тоже ограничение даноой библиотеки BLE, связанная с тем что она ждет следующего connection interval, чтобы отправить нотификацию, приготовленую в текущем connection interval. Ну - у меня такое впечатления, что данные для отправки отсылаются в следующем connection interval.
 

pvvx

Активный участник сообщества
Не-не. Цикл "запрос-ответ" - это наш протокол обмена, который я с UART заворачиваю на BLE. Запрос - это запись характеристики, ответ - это нотификация. Все это вместе длится 2 connection interval или более. Это наверное тоже ограничение даноой библиотеки BLE, связанная с тем что она ждет следующего connection interval, чтобы отправить нотификацию, приготовленую в текущем connection interval. Ну - у меня такое впечатления, что данные для отправки отсылаются в следующем connection interval.
Дык никто так не строит протокол. При прямом запрос-ответ вы словите все задержки по всему пути, включая верхний уровень программы на компе.
 

pvvx

Активный участник сообщества
Итог с INA228 таков – предел 10 килобайт в секунду.
И уже изредка наблюдаются артефакты стека WCH (ляпы кусков от других замеров в передаваемых данных).
1759755688035.png
Функция GATT_Indication()п уже практически непрерывно орет ошибкой 0x16 - blePending: A confirmation is pending with this client

При соединении согласовано: MTU exchange: 512, Current MTU = 512:512, PHY update Rx: 2M Tx: 2M

C учетом разметки потока по блокам имеем около 10 килобайт передаваемых байт данных в секунду, передается 3571 замера в сек по 20 бит (по 3 байта). Итого 1785.5 измерений по току и напряжению.
1759755705557.png

Передача потока в RF идет по 9 мелких блоков – СВЧ диод рядом с антенной модуля CH582F:
1759755710827.png
Так WCH согласует соединение c адаптером RZ616 на PCIE имеющим BT5.2 в Windows.
Это ещё одна странность. Есть и ещё :)
 

pvvx

Активный участник сообщества
Цикл "запрос-ответ" - это наш протокол обмена, который я с UART заворачиваю на BLE.
Вы в курсе, что самый крутой CPU на компе не способен обеспечить побайтный прием из UART на скорости 115200 baud?
При прерывании низкого уровня опустошается вся кэш CPU и лазание через PCIe с отложенными транзакциями по таймауту UART не позволяют так часто выходить из пользовательского уровня приложения в системный и прочие, каждый раз сбрасывая все состояния и регистры CPU. Плюс ещё сам софт...
По этому в прошлом веке в UART встроили FIFO :p
И всё надо делить на потоки, но это всё равно не даст сверх ускорения, т.к. обмен между потоками...
 

pvvx

Активный участник сообщества
Все USB-BT адаптеры сидят на USB2.0FS. Это тайминг опроса в 1 ms. Плюс используется аппаратное FIFO для USB3.0 - это килобайты. И передача данных в пользовательский уровень идет по заполнению или таймауту. То есть только тут вы имеете паузу от 1 ms между приемом и передачей и не можете организовать запрос-ответ-запрос-ответ... с уже готовыми данными или обработкой.
В итоге ловите лишние connection interval...
 

pvvx

Активный участник сообщества
Для без паузного обслуживания BLE по типу запрос-ответ, требуется готовый ответ за время до 150 мкс после приема последнего бита сообщения. Т.к. после передачи последнего бита через 150+ мкс ожидается прием. И если его нет (не готов) – следующие транзакции будут через интервал соединения.
 

il-2

New member
Для без паузного обслуживания BLE по типу запрос-ответ, требуется готовый ответ за время до 150 мкс после приема последнего бита сообщения. Т.к. после передачи последнего бита через 150+ мкс ожидается прием. И если его нет (не готов) – следующие транзакции будут через интервал соединения.
Такой быстрый ответ у меня есть!!! Я много чего упускаю при описании, вы за меня додумываете... неправильно :) Тем не менее, я вижу по обмену интересную картину - текущий connection interval отрабатывает только те пакеты, которые были выданы на предыдущем connection interval. Если мне прилетел запрос на текущем интервале и я по быстрому (мгновенно) формирую ответ - этот ответ уйдет только в следующем интервале. Я думаю - это такая фича данной библиотеки BLE, они таким образом упростили для себя обработку обмена.
 

il-2

New member
Еще хочу написать про свои наблюдения и наработки - насчет калибровки LSI и настройки этой калибровки по температуре.
Для калибровки LSI используется спец функция. Не буду подробно останавливаться на том, что эта функция делает (это отдельный разговор), главное то, что время ее работы составляет несколько (десятки) мс. Все это время программа простаивает в циклах ожидания, стек BLE и TMOS не будет получать управление, а это плохо.
Я сделал свою процедуру калибровки, которая не делает таких задержек (максимальная задержка - 1/2 периода LSI для синхронизации). Идея такова:
Процедура калибровки состоит из 2 этапов - запуска и (через определенное кол-во тактов TMOS) - обработку результатов. Для успешной работы требуется еще один таймер, который работает от HSE. Я использую SysTick, как показала практика он считает ровно, нигде в TMOS и в библиотеках не перегружается, его значение можно использовать для точного определения временных интервалов.
1. Старт калибровки. При старте выполняется синхронизация по 1/2 периода LSI и запоминается текущее значение счетчика SysTick. Так-же запускается таймер TMOS для задания интервала калибровки. Данный интервал зависит от требуемой точности калибровки (требуемого кол-ва тактов SysTick)
2. По событию TMOS (окончание интервала измерения) выполняется синхронизация по 1/2 периода LSI и определение интервала времени (SysTick). Таким образом мы отслеживаем интервал измерения с ДИСКРЕТНОСТЬЮ 1/2 периода LSI и узнаем кол-во тактов SysTick (с ТОЧНОСТЬЮ до нескольких тактов SysTick!!!), которые пришлись на этот интервал.
Ну а дальше - выполняется рассчет и корректировка регистра калибровки.
Все прекрасно работает, задержки в коде не превышают 1/2 периода LSI. Для калибровки с приемлемой точностью хватает интервала в несколько десятков тысяч тактов SysTick (единицы мс)
Есть одно ограничение, связанное со спящим режимом. Если используется спячка с остановкой HSE, то результаты калибровки следует забраковывать. Но с этим тоже проблем не возникает - либо надо воздержаться от спящего режима при калибровке, либо забраковывать калибровку и запускать ее снова.
Если есть интерес к данной теме - буду отвечать подробнее по мере возникновения вопросов
Ну и про то, как в библиотеке реализована (точнее - НЕ реализована) термокомпенсация напишу позже...
 

pvvx

Активный участник сообщества
Калибровка актуальна при режиме энергосбережения и она выполняется во время передачи маяков. А там хоть секунду занимай CPU - ничего не случится, кроме разряда батареи.
И все оптимизации необходимо выполнять с учетом потребления, а не какой-то загрузки.
Для этого необходимо исключить все лишние пробуждения по таймеру. Незачем SoC просыпаться просто для выполнения считывания температуры. На этом теряется 2 мс с токами 4..5 мА.
Если это перенести на процедуру пробуждения для маяка, то потеря энергии составит всего работу CPU на пару микросекунд. Т.е. в 1000 раз меньше.
 

pvvx

Активный участник сообщества
SYS_DisableAllIrq(&irqv); и SYS_RecoverIrq(irqv); в процедуре Calibration_LSI выполняется на время менее 1 такта RTC.
А при BLE соединении всё работает по прерываниям и это не особо мешает, кроме создания дыр, пока CPU находится в процессе Calibration_LSI().
К примеру для UART это вообще не критично. Там нет нужды делать опрос каждые 50 мкс регистров I2C внешнего чипа типа INA228 (если требуется шаг оцифровки в 20 кГц).
 

pvvx

Активный участник сообщества
Можно вообще плюнуть на калибровку, уменьшив интервал соединения. Калибровка сказывается только при интервалах соединения более 1 секунды - там набирается уход и соединение будет потеряно. А при коротком интервале % ухода не сильно сказывается на окно приема/передачи.
 

pvvx

Активный участник сообщества
Тем не менее, я вижу по обмену интересную картину - текущий connection interval отрабатывает только те пакеты, которые были выданы на предыдущем connection interval.
Всё верно - вы должны подготовить ответ до приема сообщения :p
Аналогично в nFR24 и прочих протоколах связи.
 
Сверху Снизу