Страница 48 из 59

Re: Всё по DS18(B/S)20.

Добавлено: Сб окт 01, 2016 16:44:23
Zhuk72
ARV писал(а):датчик всегда выдает 85, если не принял команду старта измерения. так что либо с процессом обмена что-то не то (адрес, например, не тот), либо вообще не начинается измерение
Тестовая плата с одной 3-контактной колодкой. Прошивка неизменна. По очереди вставляю "на горячую" две 1820 и две 18В20. Из этих четырех датчиков один и только один показывает 85. Программа не может работать избирательно только для одного датчика, отсутствие датчика также индицируется.

Re: Всё по DS18(B/S)20.

Добавлено: Сб окт 01, 2016 16:54:12
ARV
значит, кирдык датчику

P.S. я бы не советовал на горячую перетыкивать датчики... мало того, что можно попутать питание, так датчики обычно не очень любят, когда GND не подключен, а другие 2 пина подключены... в моей практике после такого включения на некоторое время датчик выходил из строя.

Re: Всё по DS18(B/S)20.

Добавлено: Сб окт 01, 2016 18:52:24
Аlex
Ещё не факт, что кирдык. Всё-таки, проблема может быть во временах тайм-слотов - где-то на грани находятся. Одни датчики работают, другие нет.
Zhuk72, а не могли бы Вы привести нам фрагменты кода обслуживания протокола ? Авось что-нибудь и увидим.

Re: Всё по DS18(B/S)20.

Добавлено: Сб окт 01, 2016 19:27:42
oleg110592
Аlex писал(а):Ещё не факт, что кирдык. Всё-таки, проблема может быть во временах тайм-слотов - где-то на грани находятся
Скорее всего.
С год назад у наших местных производителей всяких типа терморегуляторов для инкубаторов на DS18B20 возникла похожая проблема - у продавцов DS пошли датчики которые не работали, у некоторых вообще. По утверждению одного из производителей - при увеличении тактовой частоты с помощью калибровочной константы (микроконтроллер PIC16) начинало работать. Не знаю, насчет показывали ли они 85С, но у тех которые теперь у нас продаются, по умолчанию включен 9-битный режим,а в документации должно быть 12 бит. Лично наблюдал сей эффект при смене старого типа датчика на "новый" выборочно из большой упаковки. Причем местный разработчик инкубаторов утверждал, что если записать в еепром датчика 12 бит, со временем еепром сбивается и возвращает режим 9 бит, это я не проверял. Своим заказчикам-производителям пришлось переделать прошивку, с проверкой в каком режиме находится датчик.

Re: Всё по DS18(B/S)20.

Добавлено: Вс окт 02, 2016 06:16:46
BOB51
Надо б на сайтец максим-даллас заглянуть...
Может действительно чего нового "доупростили"...?
:dont_know:

И не стоит забывать, что было выпущено и несколько разновидностей датчиков с весьма различными структурами блокнота, плюс "паразитные"... (ds1820, ds18b20, ds18s20, ds18b20-par...)
что конкретно в лапы попало - вряд-ли кито точно скажет... :dont_know:
Сейчас также чегось про ds18b20s указано... читаньки надо...
самое последнее:
DS18B20.pdf
(484.15 КБ) 217 скачиваний
энто там же "паразит-подвох о трех лапках" (тоже из последнего):
DS18B20-PAR.pdf
(221.6 КБ) 195 скачиваний
ну и старо-дремучее по DS18S20
DS18S20.pdf
(183.27 КБ) 164 скачивания
есть еще и по "просто ds1820"... ежли когда понадобится...
страничка с "факами" от максим-даллас:
https://www.maximintegrated.com/en/supp ... 0-faq.html
:roll:

Re: Всё по DS18(B/S)20.

Добавлено: Вс окт 02, 2016 09:34:50
Zhuk72
Это общение с датчиком.
Спойлер

Код: Выделить всё

#define DQ (PORTB & 1)
#define DQ0 (PORTB &= 0xFE)
#define DQ1 (PORTB &= 0xFF)
#define DQ_OUT (TRISB &= 0xFE)
#define DQ_IN (TRISB |= 1)

bit init_ds()
{

    if (DQ)
    {
        DQ0;
        DQ_OUT;
        __delay_us(490);
        DQ_IN;
        DQ1;
        __delay_us(60);
        if (DQ)
        {
            ds_type = 0;
            return 0;
        }
            else 
            {
                t1over = 1;
                t1set(0xFF00);  // time-out timer, 512us to overflow
                while (DQ ^ t1over);
                return DQ;
            }
    }
        else
        {
            ds_type = 0;
            return 0;
        }
}

void send_ds(unsigned char ds_tx)
{
    GIE = 0;
    bit_cnt = 8;
    while (bit_cnt > 0)
    {
        DQ0;
        DQ_OUT;
        if ((ds_tx & 1) == 0)
        {
            __delay_us(60);
            DQ_IN;
            DQ1;
        } 
            else 
            {
                __delay_us(10);
                DQ_IN;
                DQ1;
                __delay_us(60);
            }
        ds_tx >>= 1;
        bit_cnt--;
        _nop();
    }
    GIE = 1;
}

void read_ds(unsigned char rx_bytes)
{
    GIE = 0;
    // rx содержит количество байт (2, 5 или все 9), которые нужно принять.
    for (byte_cnt = 0; byte_cnt < rx_bytes; byte_cnt++)
    {
        bit_cnt = 8;
        while (bit_cnt > 0)
        {
            ds_rx[byte_cnt] >>= 1;
            DQ0;
            DQ_OUT;
            __delay_us(10);
            DQ_IN;
            DQ1;
            __delay_us(10);
            if (DQ == 0) ds_rx[byte_cnt] &= 0b01111111;
                else ds_rx[byte_cnt] |= 0b10000000;
            __delay_us(60);
            bit_cnt--;
        }
    }
    GIE = 1;
}

void check_ds() // Тип датчика.
{
    if (init_ds())
    {
        send_ds(0x33);  // Read ROM
        read_ds(1); // 8-bit family code
        init_ds();  // Stop transmission.
        family = ds_rx[0];
        switch (family)
        {
            case 0x10: ds_type = 1; break;  // DS18(S)20
            case 0x28: ds_type = 2; break;  // DS18B20
        }
    }
        else
        {
//вывод на индикатор "nods" не показан
            ....
            ds_type = 0;
            family = 0;
        }
    if (ds_type == 2) config_ds();  // Там проверяется и прописывается при необходимости 9-битный режим.
}
Если у кого есть Saleae (и у кого его нет), могут посмотреть временнЫе графики с обоих датчиков.
DS18B20.rar
(2.68 КБ) 156 скачиваний
Меня эти графики заинтересовали тем, что почему-то идут 2 запроса подряд вместо одного. По коду такого быть не должно, придется в Проте пошагать, чтоб отловить.
А вообще опрос датчика делаю каждые 5 секунд (1000 обновлений индикатора).

Re: Всё по DS18(B/S)20.

Добавлено: Вс окт 02, 2016 12:08:28
WiseLord
В чём смысл макроса DQ1?

Re: Всё по DS18(B/S)20.

Добавлено: Вс окт 02, 2016 12:18:19
Zhuk72
Никакого смысла, ибо и без него работает :) Оставил на всякий случай, считать состояние порта, ведь в защёлке до этого прописался 0. Типа RMW.

Re: Всё по DS18(B/S)20.

Добавлено: Вс окт 02, 2016 12:37:47
Аlex

Код: Выделить всё

        DQ0;
        DQ_OUT;
Местами поменяйте, во всех позициях.
Нужно сначала установить направление, а потом уже защёлкой рулить.

Функция read_ds.

Код: Выделить всё

            DQ0;
            DQ_OUT;
            __delay_us(10);
            DQ_IN;
            DQ1;
            __delay_us(10);
            if (DQ == 0)  ..........
Не много 20 us до чтения бита ?
5-7 us максимум нужно, как показала практика. Не будет сенсор столько удерживать линию в нуле.

Код: Выделить всё

ds_rx[byte_cnt]
Не пишите таких весомых кодов там, где каждый такт проца играет огромную роль.
Добавьте ещё одну функцию - чтения байта и вызывайте её сколь угодно раз.

Это что на первый взгляд.
Вообще, у Вас всё как то запутанно, можно всё упростить и привести к нормальному виду. Могу помочь, если нужно ?

PS:
ведь в защёлке до этого прописался 0. Типа RMW.
Пофиг, что там было в защёлке :) Если речь идёт, как я понял, о мелких PIC'ах.
В защёлке всегда будет то состояние, которое было на входе ПИНа (физически !) с предыдущего обращения к порту. По этому, рулить просто направлением, как делают некоторые - косяк. Необходимо ещё обновлять содержимое защёлки, после установки ПИНа на выход.

Re: Всё по DS18(B/S)20.

Добавлено: Вс окт 02, 2016 14:06:26
Zhuk72
Аlex писал(а):Нужно сначала установить направление, а потом уже защёлкой рулить.
Поменял местами.
Функция read_ds. Не много 20 us до чтения бита ?
Судя по графику, не много, хотя согласен, что можно меньше.
Изображение
Это остатки экспериментов, когда я мучился с этим нерабочим датчиком. Увеличивал тайминги, решив, что он не воспринимает команды.

Код: Выделить всё

ds_rx[byte_cnt]
Не пишите таких весомых кодов там, где каждый такт проца играет огромную роль.
Добавьте ещё одну функцию - чтения байта и вызывайте её сколь угодно раз.
В термометре на асм так же делал, через косвенную адресацию. Сейчас пробежался по асм выхлопу компилятора этой функции (оптимизация ПРО). Он конечно понаписал побольше, чем я писал на асм. Пересмотрю код, хотя не знаю, что я там смогу оптимизировать.
К тому же при чтении байта отдельным куском тоже будет перерасход тактов на call и return (retlw). И здесь опять-таки косвенная адресация останется.
Вообще, у Вас всё как то запутанно, можно всё упростить и привести к нормальному виду. Могу помочь, если нужно?
Чужой код - потемки :) Но я в нем хорошо ориентируюсь. Помочь только советом, если можно, писать я должен сам.
Пусть я лучше буду эволюционировать естественным путем (если получится) :)))
Пофиг, что там было в защёлке :) Если речь идёт, как я понял, о мелких PIC'ах.
Старик 876. Даже без буквы.
В защёлке всегда будет то состояние, которое было на входе ПИНа (физически !) с предыдущего обращения к порту. По этому, рулить просто направлением, как делают некоторые - косяк. Необходимо ещё обновлять содержимое защёлки, после установки ПИНа на выход.
Ну я так и сделал. DQ_OUT -> DQ0 -> pause -> DQ_IN -> DQ1, который суть (PORTB &= 0xFF) - обновление содержимого защелки.

Re: Всё по DS18(B/S)20.

Добавлено: Вс окт 02, 2016 16:03:20
Аlex
Zhuk72 писал(а):К тому же при чтении байта отдельным куском тоже будет перерасход тактов на call и return (retlw). И здесь опять-таки косвенная адресация останется.
А это уже не важно.
Самое главное - выдержать временные интервалы в пределах работы с одним битом. Время между тайм-слотами (чтение/запись бита) не оговорено и может быть сколь угодно большим. А между байтами и подавно...
В реализации 1-Wire протокола, достаточно реализовать одну базовую функцию работы с битом, остальное - дело вкуса. Причём она может быть одной и для чтения и для записи, т.к. тайм-слоты, в обоих случаях, ничем не отличаются.
На вскидку :

Код: Выделить всё

bool wire_bit(bool tx){
bool ret=0;
    GIE=0;
    DQ_OUT(0);          // Линию в 0
    __delay_us(2);      // Задержка стартового импульса
    DQ_OUT(tx);         // Выводим в линию из tx
    __delay_us(5);      // Задержка до чтения бита
    if(DQ_IN)   ret=1;  // Читаем линию
    __delay_us(60);     // Задержка до окончания тайм-слота
    DQ_OUT(1);          // Отпускаем линию
    GIE=1;
return ret;
}
Ну а дальше уже работаем с этой единственной функцией, не парясь на счёт времён.
Создаём функцию для работы с байтом. Причём она, также, может быть одна единственная, и для чтения, и для записи.

Код: Выделить всё

unsigned char wire_byte(unsigned char tx){
unsigned char ret=0, i;
    for(i=0;i<8;i++){
        ret>>=1;
        if(wire_bit(tx&0x01))   ret|=0x80;
        tx>>=1;
    }
return ret;
}
Всё :)

Запись байта в шину :

Код: Выделить всё

wire_byte(0xCC);
Чтение :

Код: Выделить всё

unsigned char   read_byte;
read_byte = wire_byte(0xFF);
Для осознанных имён, можно создать макросы :

Код: Выделить всё

#define     wire_send_byte(b)   wire_byte(b)
#define     wire_read_byte()    wire_byte(0xFF)

Re: Всё по DS18(B/S)20.

Добавлено: Вс окт 02, 2016 16:30:56
BOB51
Может простая банальность - попалось некоторое количество DS18S20
8)

Re: Всё по DS18(B/S)20.

Добавлено: Пн окт 03, 2016 14:35:41
Zhuk72
Alex, спасибо большое за такой развернутый ответ!
Я предполагаю, что все это должно работать, но у меня пока в мозгах все это не укладывается :)
Мне требуется время, чтоб в это вникнуть и переварить, т.к., не будучи программистом, не могу схватить это на лету. Плюс еще мозги другим (не электронным) заняты, не дают сосредоточиться.

Отложу все это на некоторое время, пока не созрею.

Re: С какой точностью можно реально измерять с помощью 18b20

Добавлено: Вт окт 18, 2016 18:23:51
wellcom
Мяу! Собственно вопрос: Возможно ли (мож кто пробовал), использовать общую команду для установки разрешающей способности N датчиков 18В20?

Например, установить всем датчикам на шине одинаковую разрешающую способность:

0. Presece (питание трехпроводное)
1. шлем SKIP ROM [0xCC]
2. шлем write 3 byte [0x4E]
3. шлем byte TH
4. шлем byte TL
5. шлем byte регистр конфигурации
6. Правильность записанных данных проверяем уже по ROM коду

В даташите на счет этого ничего запретного, ровно как и разрешающего не выявил.

Re: Всё по DS18(B/S)20.

Добавлено: Вт окт 18, 2016 21:02:08
ARV
насколько я знаю стандарт, это делать можно.

Re: Всё по DS18(B/S)20.

Добавлено: Чт окт 20, 2016 08:31:38
wellcom
Еще вопрос - правильно ли я считаю Т при более низком разрешении?

Установил разрешение 11 бит, в даташите сказано, что бит 0 не имеет значения в таком случае.
1820.jpg
18b20
(168.12 КБ) 408 скачиваний
http://labkit.ru/userfiles/file/documen ... B20_RU.pdf

я в таком случае откидываю знак (биты 11-15) и сдвигаю вправо на 1.

Код: Выделить всё

fl_Temperature= (float)((sData18B20.i16_Temperature[u8_Nsensor]&0x7FF)>>1) *0.125; //res=11 bit, 0 bit neopredelen 
Или не нужно сдвигать? ....По показаниям Т вроде правильно считает, но сомневаюсь в точности....

Re: Всё по DS18(B/S)20.

Добавлено: Чт окт 20, 2016 08:58:09
WiseLord
Судя по написанному и табличке ниже, сдвигать не нужно. Нужно просто игнорировать младшие биты.

Re: Всё по DS18(B/S)20.

Добавлено: Чт окт 20, 2016 18:56:39
wellcom
да вот трактовать можно по разному, интересно то, что при сдвиге вправо на 1, температура примерно правильная (разница с другим термоментром цифровим не более 0,5 С). Если не сдвигать явно туфта, вместо 23 считает 44 С.

Re: Всё по DS18(B/S)20.

Добавлено: Чт окт 20, 2016 19:02:55
Аlex
Умножать нужно на 0.0625, а не на 0.125. Т.б. - делить на 16.
Вот Вам и лишний сдвиг (аля деление ещё на 2)...
Т.е. Вы сдвинули (поделили на 2), затем умножили на число, в 2 раза больше нужного. Двойки сократились, получился верный результат. Только в точности потеряли при сдвиге, на цену младшего бита. Но при меньшей битности, это не имеет никакого значения.

Re: Всё по DS18(B/S)20.

Добавлено: Чт окт 20, 2016 20:03:08
wellcom
Аlex писал(а):Умножать нужно на 0.0625, а не на 0.125. Т.б. - делить на 16.
Вот Вам и лишний сдвиг (аля деление ещё на 2)...
Т.е. Вы сдвинули (поделили на 2), затем умножили на число, в 2 раза больше нужного. Двойки сократились, получился верный результат. Только в точности потеряли при сдвиге, на цену младшего бита. Но при меньшей битности, это не имеет никакого значения.
т.е выходит все верно, сдвинул вправо на 1(разделил на 2) при 11 битном разрешении (0,125 град/деление).
см. ниже
1820.jpg
(40.14 КБ) 373 скачивания
берем из таблички строку с разрешением 0,125 -> +10,125 С = 00A2h, что равно числу 162. Теперь 162*0,125= 20,25/2=10,125 С
или

Код: Выделить всё

(0хА2>>1)*0.125 // = 10.125 C
или

Код: Выделить всё

0хА2*0.0625 // = 10.125 C
тогда выходит, что изменяя разрешающую способность датчика, мы только сокращаем время преобразования, но считаем как и при максимальной разр способности, т.е. 0,0625....что то я туплю...