• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

BLE модуль JDY-10 на чипе TLSR8266

pvvx

Активный участник сообщества
Без подтверждения приема:
Например, при измерении пропускной способности обратной петли, если устройство получает 234 байта данных в одном событие соединения, но не может быстро обработать полезную нагрузку, то для следующего события соединения вы будете оштрафованы событием соединения, которое осталось неиспользованным... Вот это и дает у меня на USB-брелке от 4- событий (4-х Connection interval). Тормоза штатные дрова и js.
 

pvvx

Активный участник сообщества
Есть и другие варианты - полу-дуплексные:
К примеру передаем запрос на чтение регистров и принимаем ответ. Тут скорость наверно будет меньше, т.к. требует не менее 2-х событий Connection interval + всякая обработка и подтверждение...
Так-же есть варианты без подтверждений, типа UDP... Про них уже указано ранее в ссылках.

Для большей скорости берем TLSR8269 и приемник BT5.2. Тогда к сотне килобайт в сек... т.е. почти уровень USB1.1
USB-BT тоже USB1.1 и сильно ограничен...
 
Для запуска локального html в Chrome в смарте надо чтобы всё было в одном файле!
Не "прокатило", ошибка осталась. Это что-то с настройками телефона. Самая первая версия Вашей программы один раз запустилась на телефоне и потом не смог повторить. :confused:
Попытки нарисовать из кубиков (MIT App) для Андройд программу связи с этим модулем, с AT прошивкой, не получилось - опять ошибка соединения:mad:
ричина - кто-то кого-то не слышит. Дешевый USB-cвисток BT ver 4.2 имеет TX 0 Дб, минимальный RX - неизвестен.
Я даже и не сомневался, либо антенну нормальную припаять (для RX), и поставить усилитель мощности(TX).
Для скайпа 7 лет назад делал антенну "двойной квадрат" с PC BT1.0 до наушника прекрасно работала до 30м. без шумов(y)
Правда печь микроволновка глушила, сразу начинала "ширкать".
На Али предлагают BT V5.0 (по спецификации дальше будет работать), но судя по отзывам похоже на обман...
 

pvvx

Активный участник сообщества
На Али предлагают BT V5.0 (по спецификации дальше будет работать), но судя по отзывам похоже на обман...
Это точно обман:
1581499987051.png
BT4.2, вообще ни с чем не соединяется и глухой от рождения (RX ужасен). Дрова нужны свои...
Остальные все на али BT4.2. Часто с дровами от Win 3.1 only :)

Надежда была на nRF52840 dongle, но не нашел прошивки и дров от Nordic.
 

pvvx

Активный участник сообщества
Не "прокатило", ошибка осталась. Это что-то с настройками телефона. Самая первая версия Вашей программы один раз запустилась на телефоне и потом не смог повторить. :confused:
Попытки нарисовать из кубиков (MIT App) для Андройд программу связи с этим модулем, с AT прошивкой, не получилось - опять ошибка соединения:mad:
Телефон может иметь старый модуль BT. Тогда надо править минимальный Connection interval. На старой версии был спецом ограничен для 500 sps.
1581500503990.png
iPhone = всегда стоит дешевая бяка :eek::oops:
 

pvvx

Активный участник сообщества
js в HTML имеет два варианта расчета sps.
В логе - по кол-ву отработанных в модуле чтений от подачи команды старта семплирования и приему статистики (опрос каждые 20 сек)
И в выводе графика, где считает у усреднением к последней секунде...
1581501494839.png
Там-же, в логе выводится на какой connection interval адаптировано соединение под конкретный sps.
От connection interval зависит потребление, т.к. модуль должен включить приемник на начало каждого интервала... Не может спать и должен услышать что ему говорит ведущий и возмождно и ответить, а потом уже спать до следующего интервала...
 

pvvx

Активный участник сообщества
На Windows 10 помогает перезагрузка (отклюение-включение BT в опциях или путем выдергивания-втыкания в USB) USB-брелка... :)
Иногда оно не хочет прокачивать даже 1000 sps. Дрова мекомягких и всё такое....
Надо писать свой адаптер на TLSR8269 или nRF52840...
 

pvvx

Активный участник сообщества
Если таймер у BLE уходит, то будут дикие потери. Ему нужно держать connection interval с точностью в us. По этому при больших интервалах с неверно откалиброванными часами участников соединения оно может рушится или иметь много потерь...
 

pvvx

Активный участник сообщества
Для смарт с ограничением у дров Connection interval в 11.25 ms и BT4.2, почти предельный 2 ksps (4 килобайта):
1581506345458.png
Вложен полный HTML
 

Вложения

Телефон может иметь старый модуль BT. Тогда надо править минимальный Connection interval. На старой версии был спецом ограничен для 500 sps.
100% старый - очистка старых запасов чипов со складов, мой Галактика J4, бюджетный даже нет светодиода "Зарядка", гигантская экономия:mad:,нет NFCи тд...
Купился на супер OLED, работает лучше чем у старших моделей, видимо OLED из старых запасов. В магазине выложили 5 телефонов от7 до 60 тр.
Взял за 7- очень понравился OLED, остальное все на 3 .
Интересно другое, первый раз запустил на телефоне Вашу старую программу и заработала:(. Потом купил свисток в Ашане- работает, а вот повторить запуск на телефоне не удалось- загадкаo_O
 

pvvx

Активный участник сообщества
Зачем нужно включать гео данные при запуске этой программы?
Это возможно для включения BT, а не GPS :)
У меня не спрашивает, а спрашивает "включить BT?", если не включен при запуске.
B во вторых это Chrome хочет, а не js в HTML. Может в его настройках надо покопать...
 

pvvx

Активный участник сообщества
Добился стабильных на старом смарте 3333 sps (6724 байта в сек)... На компе 5 ksps (10 килобайт в сек).
----
1581526164974.png
В итоге забрал всё время BT на одно устройство - выставив LL latency connection events в 8(!)
 

pvvx

Активный участник сообщества
Вот передатчик шурует каждые 11.5 ms
1581526814545.png
Sleep пришлось пожертвовать для ADC... Но и разница не сверх - SAR шурует на 4MHz CLK + 32MHz DFIFO + всякие таймеры и ожидание что скажет управляющий BLE за latency connection и всё это жрет как CPU у TLSR8266.
Смысл гасить CPU мал - падает с 9 мА до 7 мА и иногда не успевает высосать DFIFO т.к. спит, что иногда дает ошибку в замеры - перехлестываются новые данные на старые в кольцевом буфере DFIFO :)
Короче прогу для TLSR8266 обновил и ввел ещё доп. фичи...
 

pvvx

Активный участник сообщества
Размер DFIFO не увеличить - мало RAM у TSLR8266.
Сделал фичу адаптации длины пакета семплов ADC под загрузку BLE...
Информация по реальным делам в BLE и устройствам медленно раскрывается. Полных описаний то нема...
 

pvvx

Активный участник сообщества
Та и вообще всё что связано с USB и ADC на TLSR8266 без каких-либо описаний. Сделано методом "аппаратного реверса" :p
 

pvvx

Активный участник сообщества
В доках и SDK от Telink нет ничего про это. А про ADC + DFIFO + PGA в описании к SDK скромно сказано - используйте TLSR8269, а на TLSR8266 вот вам пример замера батарейки с делителем на двух R и гуляйте. Есть ещё упоминания, что не работает в PGA второй канал... Это вся инфа.
Где-то в нутрах чипа есть ещё компаратор, звуковой DAC и просыпание по активизации USB (но это пока не разобрал)
 

pvvx

Активный участник сообщества
Такая шняга ныне с ADC+DFIFO+PGA у TLR8266:
C:
// analog regs PGA
#define rega_aud_ctrl            0x86
enum {
    FLDA_AUD_PWDN_LEFT =         BIT(0),
    FLDA_AUD_PWDN_RIGHT =         BIT(1),
    FLDA_AUD_MUTE_RIGHT =         BIT(2),
    FLDA_AUD_MUTE_LEFT =         BIT(3),
    FLDA_AUD_PRE_GAIN_RIGHT =     BIT_RNG(4,5),
    FLDA_AUD_PRE_GAIN_LEFT =     BIT_RNG(6,7),
};
#define rega_aud_ctrl2            0x87
enum {
    FLDA_AUD_PST_GAIN_RIGHT =     BIT_RNG(0,3),
    FLDA_AUD_PST_GAIN_LEFT =     BIT_RNG(4,7),
};
// Структура конфигурации опроса и инициализации устройства ADC
// Выходной пакет непрерывного опроса формируется по данному описанию
// CMD_DEV_CAD Get/Set CFG/ini ADC & Start measure
typedef struct __attribute__((packed)) _dev_adc_cfg_t {
    uint8_t pktcnt;    // минимальное кол-во передаваемых значений ADC в одном пакете передачи (автоподстройка до мах SMPS_BLK_CNT)
    uint8_t chnl;     // Channel
    uint16_t sps;     // период adc chl0
    uint8_t pga20db;
    uint8_t pga2db5;
} dev_adc_cfg_t; // [7]
extern dev_adc_cfg_t cfg_adc; // store in eep
#define ADC_DFIFO_SIZE        512    // dfifo size: 64,128,256,512...
u16    dfifo_rd_ptr;
s16 dfifo[ADC_DFIFO_SIZE];
#define SOFT_OUT_SCALE        1    // 1, 2, 4
#if (MCU_CORE_TYPE == MCU_CORE_8266)
// 8266 Hardware parameters :
#define ADC_DFIFO_FCLK    16000000 // CLK FIFO
#define MAX_DFIFO_SCALE    8 // DFIFO decimation max
#define MIN_DFIFO_SCALE    1 // DFIFO decimation min
#define MAX_PERIOD_CH0    4095 // Max ADC auto channel 0 (Misc) period max (adc_period_chn0 * system clocks)
#define MIN_PERIOD_CH0    77     // channel ADC period (adc_period_chn0 * system clocks)
#define MAX_PERIOD_CH1    255 // ADC auto channel 1 (L)& 2 period max (adc_period_chn12 * 16 system clocks)
#define MIN_PERIOD_CH1    15 // ADC auto channel 1 (L)& 2 period min (adc_period_chn12 * 16 system clocks)
#define MIN_OUT_SPS (ADC_DFIFO_FCLK/(MAX_DFIFO_SCALE*SOFT_OUT_SCALE)/(MAX_PERIOD_CH0 + MAX_PERIOD_CH1*16))
#define MAX_OUT_SPS_D1 (ADC_DFIFO_FCLK/(1*SOFT_OUT_SCALE)/(MIN_PERIOD_CH0 + MIN_PERIOD_CH1*16))
#define MAX_OUT_SPS_D2 (ADC_DFIFO_FCLK/(2*SOFT_OUT_SCALE)/(MIN_PERIOD_CH0 + MIN_PERIOD_CH1*16))
#define MAX_OUT_SPS_D4 (ADC_DFIFO_FCLK/(4*SOFT_OUT_SCALE)/(MIN_PERIOD_CH0 + MIN_PERIOD_CH1*16))
#define MAX_OUT_SPS_D8 (ADC_DFIFO_FCLK/(8*SOFT_OUT_SCALE)/(MIN_PERIOD_CH0 + MIN_PERIOD_CH1*16))
/**
* @brief This function initializes ADC in sps
* @param  sps = (245..50473)/SOFT_OUT_SCALE, x1 -> 245..50473 sps
* @return <= 0 - error
*/
int init_adc_dfifo(dev_adc_cfg_t * p) {
u32 sps = p->sps;
u8 chnl = p->chnl;
u32 per, per12;
    if(sps < MIN_OUT_SPS
        || sps > MAX_OUT_SPS_D1)
        return 0;
    /** adc stop**/
     reg_adc_ctrl = 0;
    /** dfifo stop**/
     reg_dfifo_ana_in = 0;
    /**enable adc clock**/
    reg_rst_clk0 |= FLD_CLK_ADC_EN;
    /**set adc clock **/
    adc_SetClkFreq(ADC_CLK_4M);

    WriteAnalogReg(0x88,0x0f);    // select 192M clk output
    WriteAnalogReg(0x05,0x60);    // power on pll
    WriteAnalogReg(0x06,0xfe);    // power on sar

    // set sample rate
    if(sps > MAX_OUT_SPS_D2) {
        per = ADC_DFIFO_FCLK/SOFT_OUT_SCALE;
        reg_dfifo_scale = 0x00; // DFIFO decimation 1
        reg_aud_alc_vol = 40;
    }
    else if(sps > MAX_OUT_SPS_D4) {
        per = (ADC_DFIFO_FCLK/SOFT_OUT_SCALE)>>1;
        reg_dfifo_scale = 0x11; // DFIFO decimation 2
        reg_aud_alc_vol = 28;
    }
    else if(sps > MAX_OUT_SPS_D8) {
        per = (ADC_DFIFO_FCLK/SOFT_OUT_SCALE)>>2;
        reg_dfifo_scale = 0x33; // DFIFO decimation 4
        reg_aud_alc_vol = 16;
    }
    else {
        per = (ADC_DFIFO_FCLK/SOFT_OUT_SCALE)>>3;
        reg_dfifo_scale = 0x77; // DFIFO decimation 8
        reg_aud_alc_vol = 4;
    }
    per /= sps;
    per12 = (per - MIN_PERIOD_CH0) >> 4;
    if(per12 > 255)
        per12 = 255;
     reg_adc_period_chn12 = per12;
     per -= per12<<4;
     reg_adc_period_chn0 = per;

     // dfifo mode
     reg_aud_hpf_alc = 11 | FLD_AUD_IN_HPF_BYPASS; // | FLD_AUD_IN_ALC_BYPASS;

     // PGA on ?
    if((chnl&0x1f) == FLD_ADC_CHN_PGA_R || (chnl&0x1f) == FLD_ADC_CHN_PGA_L) {
        // PGA on
        reg_clk_en2 |= FLD_CLK2_DIFIO_EN | FLD_CLK2_AUD_EN;
        WriteAnalogReg(rega_aud_ctrl, cfg_adc.pga20db); //(PGA_GAIN_PREAMP << 6));
        WriteAnalogReg(rega_aud_ctrl2,cfg_adc.pga2db5);// (PGA_GAIN_POSTAMP << 4));
        // select the input channel
        // PGA set left channel ANA_C<1> and right channel ANA_C<2>
        reg_adc_pga_sel_l = 0x21;
    } else {
        // PGA off
        reg_clk_en2 |= FLD_CLK2_DIFIO_EN;
        reg_adc_pga_sel_l = 0;
    }
    reg_adc_pga_sel_m = 0;
//    reg_adc_pga_sel_r = 0; // none 8266?

    /// set the adc's mode && channels
    //    adc_AnaChSet(chnl); // reg_adc_chn_m_sel
    //    adc_AnaModeSet(SINGLEEND); // reg_adc_chn_m_sel
    REG_ADDR32(0x002c) = 0 // chnl GPIO_PC4
         | (ADC_CHN_GND)         // reg_adc_chn_m_sel
         | ((chnl | 0x80) << 8)    // reg_adc_chn_l_sel
         | (ADC_CHN_GND << 16)   // reg_adc_chn_r_sel
         | ADC_SAMPLING_RES_14BIT << 24;             // reg_adc_res_lr
    /// set the reference voltage
    //    adc_RefVoltageSet(ADC_REF_VOL_1V3); // ADC_REF_VOL_1V3, ADC_REF_VOL_AVDD
    reg_adc_ref = MASK_VAL(FLD_ADC_REF_M, ADC_REF_VOL_AVDD) // adc_RefVoltageSet(RV_1P428);
        | MASK_VAL(FLD_ADC_REF_L, ADC_REF_VOL_1V3) // !!! // RV_1P428, RV_AVDD, RV_1P224
        | MASK_VAL(FLD_ADC_REF_R, ADC_REF_VOL_AVDD);
    /// set resolution, sample cycle
    //    adc_ResSet(ADC_SAMPLING_RES_14BIT); // reg_adc_samp_res
    //    adc_SampleTimeSet(ADC_SAMPLING_CYCLE_12);// ADC_SAMPLING_CYCLE_6); reg_adc_samp_res
    reg_adc_samp_res = MASK_VAL(FLD_ADC_CHNM_SAMP_RESOL, ADC_SAMPLING_RES_14BIT)
        | MASK_VAL(FLD_ADC_CHNM_SAMP_CYCLE, ADC_SAMPLING_CYCLE_12)
        | MASK_VAL(FLD_ADC_CHNLR_SAMP_CYCLE, 0);

    // set dfifo buf
    reg_dfifo0_addr = (u16) ((u32)&dfifo);
    reg_dfifo0_size = (ADC_DFIFO_SIZE>>3)-1;

    // start dfifo
    // Bit[3]: disable D-MIC channel
    reg_dfifo_ana_in = BIT(3) | FLD_DFIFO_MIC_ADC_IN | FLD_DFIFO_AUD_INPUT_MONO | FLD_DFIFO_WPTR_CLR;
    dfifo_rd_ptr = 0;
    reg_dfifo_ana_in = BIT(3) | FLD_DFIFO_MIC_ADC_IN | FLD_DFIFO_AUD_INPUT_MONO;

    // start adc
    reg_adc_ctrl = FLD_ADC_CHNL_AUTO_EN | FLD_ADC_AUD_DATAPATH_EN | MASK_VAL(FLD_ADC_AUD_MODE, 1); //= 0x15; 0: no audio; 1: mono; 2: stereo;
    return 1;
}
void deinit_adc(void) {
    reg_adc_ctrl = 0;
    reg_dfifo_ana_in = 0; // dfifo disable
    reg_clk_en2 &= ~(FLD_CLK2_DIFIO_EN | FLD_CLK2_AUD_EN );
    WriteAnalogReg(rega_aud_ctrl, FLDA_AUD_PWDN_LEFT | FLDA_AUD_PWDN_RIGHT); //(PGA_GAIN_PREAMP << 6));
    REG_ADDR32(0x002c) = 0 // chnl GPIO_PC4
     | (ADC_CHN_GND)         // reg_adc_chn_m_sel
     | (ADC_CHN_GND << 8)    // reg_adc_chn_l_sel
     | (ADC_CHN_GND << 16)   // reg_adc_chn_r_sel
     | ADC_SAMPLING_RES_14BIT << 24;             // reg_adc_res_lr
    ADC_MODULE_CLOSED;
    reg_rst_clk0 &= ~FLD_CLK_ADC_EN;
}
...
#if SOFT_OUT_SCALE == 1
unsigned int get_adc_dfifo_len(void) {
    return((reg_audio_wr_ptr - dfifo_rd_ptr) & (ADC_DFIFO_SIZE - 1)) >> 1;
}
// В dfifo пишется по 2 семпла! (L и R канал)
// Для выборки семпла надо делать 2 шага, через один семпл.
int get_adc_dfifo(u16 * pbuf, unsigned int cnt) {
    int i = 0;
    unsigned int cur_size = ((reg_audio_wr_ptr - dfifo_rd_ptr) & (ADC_DFIFO_SIZE - 1)) >> 1;
    if (cur_size > cnt)    {
        do {
            dfifo_rd_ptr &= ADC_DFIFO_SIZE - 1;
            u16 * p = (u16 *)&dfifo[dfifo_rd_ptr];
            dfifo_rd_ptr += 2;
#if 0
            pbuf[i++] = *p + 0x8000;
#else
            s32 x = p[0] + p[1];
            pbuf[i++] = (x >> 1) + 0x8000;
#endif
        } while(i < cnt);
    }
    return i;
}
unsigned int get_adc_dfifo_len(void) {
    return((reg_audio_wr_ptr - dfifo_rd_ptr) & (ADC_DFIFO_SIZE - 1)) >> 1;
}
 

pvvx

Активный участник сообщества
Очередное баловство:
Диод Д223A и резистор 4k7 в 3.3В, диод нагрет рукой (примерно +30C), PGA +20дБ, остывание до температуры и моих движений на столе:
1581538731075.png
 
Сверху Снизу