pvvx
Активный участник сообщества
Модули ESP32-C3S от Ai-Thinker...
Потребовалось слепить экономичный приемник BLE рекламы с одного устройства...
В качестве испытуемого передатчика BLE рекламы взял Xiaomi LYWSD03MMC.
В принципе работает - вычисляет длительность advertising interval у передатчика и далее пытается окном принимать рекламные пакеты, а в остальное время спит (если нет пропусков и не нужна новая подстройка интервала). Спит и окном - чтобы меньше жрал.
Но ничего хорошего, как всегда c ESP, не вышло.
Вот так оно входит в light_sleep - что-то тама в черном ящике заряжается и не успевает упасть до обещанных Espressif в PDF значений в режиме light_sleep, как надо уже новую рекламку принимать...
Окно приема кушает примерно так:
Снижение частоты CPU с 160 на 80МГц ничего существенного не дает - среднее потребление в 15 мА (при приеме рекламы с интервалом 2.5 сек, как на диаграммах) падает не более чем на 1 мА.
На плате ESP32-C3-32S_Kit всё ещё хуже - при включении любого sleep врубается что-то в SERIAL_USB_JTAG и выставляет на ногу GPIO19 "1" и светит светодиодом
Что надо сделать, чтобы ток упал до обещанных Espressif для ESP3-C3?
Иначе это какой-то кошмар, т.к. любой другой чип имеет потребление при включенном BLE приемнике 5..6 мА, а если ещё держать прием окном - выйдет менее 1 мА (т.е. не менее чем в 15 раз меньше чем у ESP32-C3).
Потребовалось слепить экономичный приемник BLE рекламы с одного устройства...
В качестве испытуемого передатчика BLE рекламы взял Xiaomi LYWSD03MMC.
Код:
/*
* Test Advertisements Scanning
*/
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEScan.h>
#include "BLEDevice.h"
#include "soc/rtc_cntl_reg.h"
#include "hal/gpio_ll.h"
#define USE_LIGH_SLEEP 1 // 1 - on, 0 - off
#if USE_LIGH_SLEEP
#define eprintf // no printf
#else
#define eprintf printf
#endif
#define SCAN_TIME_DEF 21 // seconds
int scanTime = SCAN_TIME_DEF; // seconds
int stage = 0;
int delay_ms = 50;
uint32_t period_min_ms, period_max_ms;
BLEAddress inMacAddress = BLEAddress("a4:c1:38:0b:5e:ed"); // The remote data device MAC
uint32_t tik_scan, rx_all_count = 0, rx_err_count = 0;
boolean flag_delay = false;
BLEScan* pBLEScan;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
if (inMacAddress.equals(advertisedDevice.getAddress())) {
uint32_t tt = millis();
uint32_t delta = tt - tik_scan;
tik_scan = tt;
pBLEScan->stop();
pBLEScan->clearResults();
flag_delay = true;
if(stage) {
if (stage == 1) {
period_min_ms = delta;
period_max_ms = delta;
delay_ms = delta - 20;
scanTime = 1 + (period_max_ms + 250)/500; // sec
eprintf("Sheck period: %u ms, delay: %u, scanTime: %d\n", delta, delay_ms, scanTime);
stage = 2;
}
if(rx_all_count++) {
if(delta > period_max_ms) {
if(delta > period_max_ms + (period_max_ms>>2)) {
rx_err_count++;
} else
period_max_ms = delta;
} else if (delta < period_min_ms) {
period_min_ms = delta;
delay_ms = period_min_ms - 20;
scanTime = 1 + (period_max_ms + 250)/500; // sec
eprintf("Correct min period: %u ms, delay: %u, scanTime: %d\n", delta, delay_ms, scanTime);
}
}
eprintf("delta: %d ms (%u..%u), lost: %u, total: %u\n", delta, period_min_ms, period_max_ms, rx_err_count, rx_all_count);
} else {
eprintf("Start calk delta...\n");
stage = 1;
}
}
}
};
void setup() {
CLEAR_PERI_REG_MASK(USB_DEVICE_CONF0_REG, USB_DEVICE_USB_PAD_ENABLE);
#if (!USE_LIGH_SLEEP)
pinMode(PIN_X, OUTPUT);
digitalWrite(PIN_X, LOW);
Serial.begin(115200);
Serial.println("Test Scanning");
#endif
BLEDevice::init("");
pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), true);
//pBLEScan->setInterval(100); // default 100
//pBLEScan->setWindow(100); // default 100, less or equal setInterval value
eprintf("Start scan (%u sec).\n", scanTime);
tik_scan = millis();
}
void LSleep(uint32_t ms) {
#if (!USE_LIGH_SLEEP)
Serial.flush( true ); // wait for all data to be sent out UART
#else
for (int gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) {
if (GPIO_IS_VALID_GPIO(gpio_num)) {
if (gpio_num <= GPIO_NUM_5) {
REG_CLR_BIT(RTC_CNTL_PAD_HOLD_REG, BIT(gpio_num));
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
}
}
}
#endif
esp_sleep_enable_timer_wakeup (ms * 1000);
esp_light_sleep_start();
#if (USE_LIGH_SLEEP)
CLEAR_PERI_REG_MASK(USB_DEVICE_CONF0_REG, USB_DEVICE_USB_PAD_ENABLE);
#endif
}
void loop() {
pBLEScan->setActiveScan(false);
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
if(flag_delay) {
flag_delay = false;
#if (USE_LIGH_SLEEP)
if(delay_ms > 5)
LSleep(delay_ms);
else
#endif
if(delay_ms > 0)
delay(delay_ms);
} else {
eprintf("Timeout scan! Last scan %u ms.\n", millis() - tik_scan);
stage = 0;
scanTime = SCAN_TIME_DEF; // sec
}
}
Но ничего хорошего, как всегда c ESP, не вышло.
Вот так оно входит в light_sleep - что-то тама в черном ящике заряжается и не успевает упасть до обещанных Espressif в PDF значений в режиме light_sleep, как надо уже новую рекламку принимать...
Окно приема кушает примерно так:
Снижение частоты CPU с 160 на 80МГц ничего существенного не дает - среднее потребление в 15 мА (при приеме рекламы с интервалом 2.5 сек, как на диаграммах) падает не более чем на 1 мА.
На плате ESP32-C3-32S_Kit всё ещё хуже - при включении любого sleep врубается что-то в SERIAL_USB_JTAG и выставляет на ногу GPIO19 "1" и светит светодиодом
Что надо сделать, чтобы ток упал до обещанных Espressif для ESP3-C3?
Иначе это какой-то кошмар, т.к. любой другой чип имеет потребление при включенном BLE приемнике 5..6 мА, а если ещё держать прием окном - выйдет менее 1 мА (т.е. не менее чем в 15 раз меньше чем у ESP32-C3).