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

BLE модули TB-04/TB-03F (TLSR8253F512)

pvvx

Активный участник сообщества
Как итог – у “авторов” принимающих “патчи” к ядру Linux нет шарящих в BT/BLE. По этой причине они не могут принять чужие коррекции или дописанный код и полной поддержки стандарта BT4.2 вышедшего в 2014 году так и нет. Аналогично дела обстоят со всем остальным функционалом в Linux – развития там нет уже десятилетия и бесполезно даже что-то писать и передавать...Остается только один путь - ждать полной редакции Linux от китайцев :p
 

Slacky

Member
На форуме телинка кто-то интересовался, как на 825х использовать внутренний датчик температуры. Они его отправили в примеры driver_sdk_825x. Но! Там есть примеры только для B80 и B87. Для B85 примеров нет. В общем я по аналогии сделал, только немного поигрался в прескаллер, взял не 1, а 1F8, так как в других вариантах возвращалось число меньше 130. Ну и в процессе проверки с феном и нагревом немного подкорректировал коэффициент с 0.51 на 0.58. В таком варианте температура возвращается более менее с близким к реальныму значением. Большая точность не нужна, нужно отследить критичное повышение температуры, например возгорание.
В общем не зря они не положили примеры для внутреннего температурного сенсора для TLSR8258. У меня три чипа показывают на одном и том же коде разные значения. Причем конкретно разные. -16, -23, +24. Решил прикрутить самый простой внешний сенсор на DS18B20. Посмотрел примеры для разных чипов, ничего вроде сложного. Перписал под 8258. Не работает. Все время возвращает температуру 0.

Вопрос - функцию для GPIO выбираем, как AS_GPIO?

Сам код вроде работает, импульсы посылаются ...
Скриншот 17-09-2023 173607.jpg
 

Slacky

Member
А есть уверенность что датчик рабочий?
Ныне клонов DS18B20 толпы и брака у них куча...
Рабочий. Я его к esp8266 подключил и через Ардуину с либами OneWire и DallasTemperature он сразу завелся. К тому же он старый, я его лет 5 назад на всякий случай купил, он так и валялся без дела ...

Вот такой - https://aliexpress.ru/item/1005006014680117.html
 

pvvx

Активный участник сообщества
Я не пользую эти датчики, т.к. они не годятся для 3В питания и оригинальных уже нет более 5 лет. А китайские не имеют проверки на производстве - от этого и цена в 6 раз меньше.
И по описаниям часто дохнут после помещения в температуру от +100С.
Вот люди тестят, что продается:
В наших покупках на eBay в 2018–2019 гг. водонепроницаемых датчиков DS18B20 из Китая, Германии и Великобритании большинство партий имели датчики семейства B1, а каждая третья покупка имела датчики семейства D. Ни в одной из партий не было датчиков семейства A1 или C.
 

pvvx

Активный участник сообщества
Скорее всего где-то что-то напутали и с GPIO подсказать нечего - в TLSR82xx с GPIO проблем никогда не было. Есть все варианты переключений состояний...
 

pvvx

Активный участник сообщества
Если датчик на п.плату, рядом с SoC или типа, и не требуется сверх точность температуры, то проще поставить что-то типа tmp100 (I2C) или TMP36 (к ADC). Меньше места, проводков и прочих заморочек...
А для батарейного питания (СR2032 и типа) это тоже не годится - тут проще какой датчик влажности с температурой - у них рабочее падение питания до 1.8В.
 

pvvx

Активный участник сообщества
За более 20 лет на наших тысячах уже работающих пром. установках ни один TMP36 не глючил... Т.е. никогда и ни разу с ними не было никаких проблем при сборке, тестах и т.д.
А с DS18B20 (в чужом оборудовании) постоянные заморочки...
 

Slacky

Member
Скорее всего где-то что-то напутали и с GPIO подсказать нечего - в TLSR82xx с GPIO проблем никогда не было. Есть все варианты переключений состояний...
Тогда может глянете, что я накалякал? Я взял пример из ссылки с форума Телинка, там уже кто-то спрашивал про OneWire. GPIO - PC3.
C:
static void OneWireHigh() {

    /* Set as output */
    drv_gpio_output_en(GPIO_TEMP, true);
    drv_gpio_input_en(GPIO_TEMP, false);

    /* Set high */
    drv_gpio_write(GPIO_TEMP, 1);

//    BUSDIR = 0; // Set as output
//    BUSOUT = 1; // Set high
}

static void OneWireRelease() {

    /* Set as output */
    drv_gpio_output_en(GPIO_TEMP, true);
    drv_gpio_input_en(GPIO_TEMP, false);

    /* Set low */
    drv_gpio_write(GPIO_TEMP, 0);

//    BUSDIR = 0; // Set as output
//    BUSOUT = 0; // Set low
}

static u8 OneWireRead() {
    drv_gpio_output_en(GPIO_TEMP, false);
    drv_gpio_input_en(GPIO_TEMP, true);
    return drv_gpio_read(GPIO_TEMP);
//    return BUSIN;
}

static u8 OneWireReset() {
    OneWireRelease();
    WaitUs(480); // 480uS Delay
    OneWireHigh();
    WaitUs(70); // wait 70 uS before reading
    u8 OW = OneWireRead(); // check for OneWire
    WaitUs(410); // 410 uS delay
    OneWireHigh(); // give bus back to OneWire
    return OW;
}


static void OneWireWriteBit(u8 b){
    if(b){
        OneWireRelease();
        WaitUs(6); // wait 6uS
        OneWireHigh();
        WaitUs(64); // wait 64uS
    }
    else{
        OneWireRelease();
        WaitUs(60); // wait 60uS
        OneWireHigh();
        WaitUs(10); // wait 10uS
    }
}

static u8 OneWireReadBit(){
    OneWireRelease();
    WaitUs(6); // wait 6uS
    OneWireHigh();
    WaitUs(9); // wait 9uS
    u8 out = OneWireRead();
    WaitUs(55); // wait 55uS
    return out;
}

static void OneWireWriteByte(u8 b){
    for(u8 i = 0; i < 8; i++){
        OneWireWriteBit(b & 0x01); // send LS bit first
        b = b >> 1;
    }
}

static u8 OneWireReadByte(void){
    u8 out = 0;
    for(u8 i = 0; i < 8; i++){ // read in LS bit first
        out = out >> 1; // get out ready for next bit
        if(OneWireReadBit() & 0x01) // if its a one
            out = out | 0x80; // place a 1
    }
    return out;
}

u16 OneWireTemp() {

    u8 reset = OneWireReset(); // Reset Pulse
    printf("1 return WireReset: %d\r\n", reset);
    OneWireWriteByte(0xCC); // Issue skip ROM command (CCh)
    OneWireWriteByte(0x44); // Convert T command (44h)
    while(!OneWireRead()); // DS will hold line low while making measurement
    reset = OneWireReset(); // Start new command sequence
    printf("2 return WireReset: %d\r\n", reset);
    OneWireWriteByte(0xCC); // Issue skip ROM command
    OneWireWriteByte(0xBE); // Read Scratchpad (BEh) - 15 bits
    u8 LSB = OneWireReadByte();
    u8 MSB = OneWireReadByte();
    reset = OneWireReset(); // Stop Reading
    printf("3 return WireReset: %d, LSB: %d, MSB: %d\r\n", reset, LSB, MSB);
    u16 data = MSB;
    u16 temperature = (data << 8) | LSB;
    return temperature;

}

void OneWireInit() {

    drv_gpio_up_down_resistor(GPIO_TEMP, PM_PIN_PULLUP_10K);
    drv_gpio_irq_dis(GPIO_TEMP);

    // Leave the pin low initially.
    OneWireRelease();
}

При подключенном к PC3 датчике
Код:
1 return WireRreset: 0
2 return WireRreset: 0
3 return WireRreset: 0, LSB: 0, MSB: 0
Temperature: 0
При отключенном PC3 от датчика
Код:
1 return WireRreset: 8
2 return WireRreset: 8
3 return WireRreset: 8, LSB: 0, MSB: 0
Temperature: 0
 

pvvx

Активный участник сообщества
drv_gpio_input_en(GPIO_TEMP, false); - это только отказ от функционирования чтения GPIO - отключение логики чтения. Просто не будет читаться вход.
Включать чтение с GPIO можно сразу и не трогать.
 

pvvx

Активный участник сообщества
И проще описать начальную конфигурацию GPIO в app_config.h по типу:
Код:
#define PC3_INPUT_ENABLE    1
#define PC3_DATA_OUT        0 // 1 ?
#define PC3_OUTPUT_ENABLE    0
#define PC3_FUNC            AS_GPIO
#define PULL_WAKEUP_SRC_PC3    PM_PIN_PULLUP_10K
#define PC3_DATA_STRENGTH    1  // увеличение тока вывода - "1" равно по умолчанию, см. "gpio_default_8258.h"
Это будет выставляться при старте и не увеличивает размер кода, т.к. при старте (и выходе из sleep) инициализируются все GPIO по данным define.
 

pvvx

Активный участник сообщества
Такой OneWireRead() у вас не отработает. Там сразу после отключения Out enable производится чтение, а уровень на GPIO ещё не установился за несколько нс от выходного значения - DS18B20 имеет громадную входную емкость...
 

pvvx

Активный участник сообщества
DS18B20 - Read Data Valid tRDV 15 µs - время за которое датчик выставляет выходной уровень в "1" после "0", без учета емкости линии.
DS18B20 - это чип по технологии того века, а на входе у него ещё и источник тока из элементов в сотни нанометров....
 

pvvx

Активный участник сообщества
Посмотрел примеры для разных чипов, ничего вроде сложного. Перписал под 8258.
Если переписываете с Arduino, то необходимо всегда учесть что там любые функции с GPIO отрабатывают за миллисекунды, даже не за микро. :)
И никогда не берите детали которые идут для Arduino - это отстой, который никогда не используется при нормальном производстве, т.к. требуются большие партии, а данное барахло делают во время простоя конвеера или на полностью износившемся оборудовании в палатке в Китае мелкими партиями и без контроля...
 

Slacky

Member
Такой OneWireRead() у вас не отработает. Там сразу после отключения Out enable производится чтение, а уровень на GPIO ещё не установился за несколько нс от выходного значения - DS18B20 имеет громадную входную емкость...
Я победил этот датчик :))

Код:
OTA mode enabled. MCU boot from address: 0x0
Read config from flash address - 0x40000
ds18b20_reset: 1
Temperature: 21.75C
Temperature: 21.62C
Temperature: 21.62C
Temperature: 21.62C
Temperature: 21.62C
Temperature: 21.62C
Temperature: 21.62C
Temperature: 21.62C
 

pvvx

Активный участник сообщества
Slacky - При инициализации необходимо опустить шину в ноль, а в момент отпускания измерить время, через которое на шине будет “1”. Это время необходимо прибавить к типовой задержке опроса после строба. Другие варианты требуют фиксированного времени к 100 мкс. Но это не будет работать на сверх длинном шнурке или будет тратить лишнее время на опрос. Решения в Arduino не учитывают линию и часто имеют только типовую задержку с балды, от этого нифига не работает на шнурках или глючит.
 

Slacky

Member
Slacky - При инициализации необходимо опустить шину в ноль, а в момент отпускания измерить время, через которое на шине будет “1”. Это время необходимо прибавить к типовой задержке опроса после строба. Другие варианты требуют фиксированного времени к 100 мкс. Но это не будет работать на сверх длинном шнурке или будет тратить лишнее время на опрос.
Да мне внутренность прибора измерять, типа не загорелся ли распределительный шкаф. Для дома. В личное пользование. Не для промышленности. Работает. Осталось с минусовой температурой разобраться, хотя в доме не бывает минуса :)
 

pvvx

Активный участник сообщества
Да мне внутренность прибора измерять, типа не загорелся ли распределительный шкаф. Для дома. В личное пользование. Не для промышленности. Работает. Осталось с минусовой температурой разобраться, хотя в доме не бывает минуса :)
А если выложите где, то детки повторят и будут ругаться - "что я сделал не так?" :p
И во время измерения, если уже запущен BLE стек, то нужно запретить прерывания.
 

pvvx

Активный участник сообщества
Не для промышленности.
Для пром. применения там надо ещё постоянно следить за паузой ответа и корректировать находу. Плюс все проверки и перезапуски при сбоях с набором статистики всего этого бардака :p
Сравнение результатов с минимальным и максимальным аварийным (ошибки датчика) значением, да с нормированными для получения результата достоверности показаний....
А для более серьезных применений + ещё схему дублирования и сравнения результатов с резервными блоками :p
 
Сверху Снизу