-=FISHER=-

DS18B20 выдает неадекватные показания при паразитном питании

79 сообщений в этой теме

Способ управления выходом шины 1-wire изменением направления передачи довольно распространённый способ. Лично я использую два пина для подключения датчиков ds18b20 (один вход и один выход) и схему активной подтяжки.

http://forum.cxem.net/index.php?/topic/165405-помогите-с-датчиком-dallas/&tab=comments#comment-2456067

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
6 часов назад, technik-1017 сказал:

я предлагал установить режим с помощью внешней программы, но видимо необходимо это реализовать в устройстве

Да хотелось бы это реализовать именно в устройстве, чтобы при замене термодатчика, он автоматически вставал в 9 битный режим. Дак как же это сделать единожды?

6 часов назад, technik-1017 сказал:

у вас это проверка датчика на линии

Получается вот эта функция?

dt_testdevice(void)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    500
Только что, -=FISHER=- сказал:

он автоматически вставал в 9 битный режим

Да не проблема, но зачем?! Чем не устраивает 12-битный режим, установленный с завода?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
2 часа назад, -=FISHER=- сказал:

Да хотелось бы это реализовать именно в устройстве, чтобы при замене термодатчика, он автоматически вставал в 9 битный режим. Дак как же это сделать единожды?

у вас по схеме есть свободные ввода, повесте на один из входов кнопку (микрик) и инициализируйте датчики при нажатии на кнопку

 

2 часа назад, -=FISHER=- сказал:

Получается вот эта функция?

да

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Геннадий    1 032

Мы не ищем легких путей? Разве после сброса влом прочитать регистр датчика, проверить режим и (по необходимости) выставить требуемый?

Изменено пользователем Геннадий

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
13 минуты назад, Геннадий сказал:

Разве после сброса влом прочитать регистр датчика, проверить режим и (по необходимости) выставить требуемый?

такой вариант уже был, автора пока не устроил:

10 часов назад, -=FISHER=- сказал:

Неужели придётся читать байт конфигурации и сравнить его значение с интересующим меня значением 0x1F (0b00011111)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Геннадий    1 032

Вы уверены, что автора устроит - "неужели придется допаивать кнопку, инициализировать линию порта, добавлять функцию опроса кнопки и сравнивать ее состояние с вкл/выкл"?:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

вообще я предполагал, как вариант, замыкание микрика (или перемычки) перед подачей питания:
нажали кнопку, подали питание, проверили кнопку, инициализировали датчики (возможно ещё что-нибудь инициализировали - "первое включение"))

вообще решать не нам

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
15 часов назад, ARV сказал:

Чем не устраивает 12-битный режим, установленный с завода?

Огромной задержкой в 750 мс

13 часа назад, Геннадий сказал:

Разве после сброса влом прочитать регистр датчика, проверить режим и (по необходимости) выставить требуемый?

 

13 часа назад, technik-1017 сказал:

такой вариант уже был, автора пока не устроил:

Этот вариант я вижу как единственный возможный, но я читал даташит и как я понял чтение из регистра конфигурации - задача не из лёгких. Не могли бы вы пожалуйста привести пример?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    500
Только что, -=FISHER=- сказал:

Огромной задержкой в 750 мс

У вас же как бы часы многофункциональные? Я угадал? Огромная задержка в 1 секунду для часов вас не смущает? Или вы и время выводите каждые 100 мс?

Только что, -=FISHER=- сказал:

как я понял чтение из регистра конфигурации - задача не из лёгких

Самая сложная задача - это поиск адресов нескольких 1-wire устройств, сидящих на одной шине, все остальное примитивно, как таблица умножения, и в даташите крайне детально расписано.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
10 минут назад, ARV сказал:

Я угадал?

В яблочко :)

 

10 минут назад, ARV сказал:

Огромная задержка в 1 секунду для часов вас не смущает?

Смотрите, если я буду выводить на дисплей и время и температуру и при этом часы будут иметь кнопки, чтобы сработала кнопка, придётся её удерживать значительное время. Вот в этом заключается неудобство 12 битного режима в частности. А ещё у меня уже появился спортивный интерес программно перевести DS18B20 в 9 битный режим, потому что конкретного примера на Си, мне не удалось найти в Сети.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    500
Только что, -=FISHER=- сказал:

В яблочко

Готовлюсь у битве экстрасенсов :)

Теперь по сути: категорически ошибочный подход "тупо" ждать конца преобразования при помощи задержки. Это допустимо только в особых случаях, например, в термометрах без органов управления, но даже в этом случае это "моветон".

В своих проектах я всегда заводил с DS1307 сигнал INT в режиме меандра, по которому определял, что прошла секунда (или меньше - там можно настроить период меандра) - и только в этом случае обновлял показания индикатора, остальное время можно было делать, что угодно.

В вашем случае куда практичнее опрашивать часы и проверять, прошла секунда или нет. Если прошла - можно обновлять показания. И, естествено, считывать показания датчика, запущенного "прошлый раз". То есть алгоритм примерно таков:

if (прошла_секунда){
  temp = read_temperature();
  start_conversion();
  show_time();
  show_temperature();
}

Если вставить это в основной цикл, то обработка кнопок и все прочее будет происходить с весьма высокой скоростью, ждать датчика, мешая остальному, не придется.

Ну на счет спортивного интререса - это я не осуждаю, но логику алгоритма все-таки стоит подправить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
44 минуты назад, ARV сказал:

все остальное примитивно, как таблица умножения, и в даташите крайне детально расписано.

Боюсь даташитов, сам не знаю почему...

5b6d2576722f2_.JPG.9a8633ef72b2d84234a65a6653d6787e.JPG

В общем прочитал про чтение.

5b6d25add4275_.JPG.b42329fa7c267a3f3240dc724776d6e3.JPG

В голове сложилась вот такая последовательность:

char dt_readcbyte(void) // функция, которая вернет значение регистра конфигурации
{
	char c_byte; //объявим переменную в которую будет считан байт конфигурации
	dt_testdevice(void) //ШАГ 1. Определим, есть ли устройство на шине
	dt_sendbyte(0xCC); //ШАГ 2. Пропустим идентификацию
	dt_sendbyte(0xBE); //ШАГ 3. Команда чтения
	for(int i=0; i<5; i++) // последовательно прочитаем 5 байт в одну и ту же переменную
      						// и остановимся на пятом (Configuration Register)
	{
		c_byte=dt_readbyte();
	}
//дальше чиать память нет необходимости, значит нужно послать импульс сброса, вот так?
	DDRTEMP |= 1<<BITTEMP; //притягиваем шину к 0
	_delay_us(485); //задержка как минимум на 480 микросекунд
	DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
	return c_byte;
}

Сработает такая последовательность?

Изменено пользователем -=FISHER=-

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    500

Вы допускаете традиционную для многих ошибку - не считываете ВСЕ байты, возвращаемые датчиком. Не смотря на "убедительный" факт, что "и так работает", так делать нельзя. Всегда нужно вычитывать все 9 байтов, выдаваемых датчиком (кроме случаев, когда это на самом деле оговорено в даташите) и обязательно проверять CRC всего массива. Любые дальнейшие манипуляции над данными делать только в том случае, если CRC всех 9 байт равна нулю, иначе игнорировать результат обмена.

В вашем алгоритме есть разного рода ошибки - от странных до грубых.

Только что, -=FISHER=- сказал:

ШАГ 1. Определим, есть ли устройство на шине

Определим - это значит узнаем, есть оно или нет, что подразумевает оператор if над результатом определения. У вас же просто определим и наплюем на результат - хоть есть, хоть нет, будем делать дальше.

Только что, -=FISHER=- сказал:

последовательно прочитаем 5 байт в одну и ту же переменную

Про это уже написал: считаем 9 байт и по мере считывания вычислим CRC, потом проверим CRC на 0, и если ноль на самом деле - пойдем далее.

Много-много лет назад я писал статью про этот интерфейс: воды утекло с тех пор много, и статья не безгрешная, но, вероятно, вам поможет...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
55 минут назад, -=FISHER=- сказал:

Смотрите, если я буду выводить на дисплей и время и температуру и при этом часы будут иметь кнопки

я вам ранее давал ссылку на один из моих примеров работы с датчиком ds18b20,там есть и работа с ds1307 + меню
http://forum.cxem.net/applications/core/interface/file/attachment.php?id=433564

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
1 час назад, ARV сказал:

У вас же просто определим и наплюем на результат - хоть есть, хоть нет, будем делать дальше.

Поторопился...

char dt_readcbyte(void) // функция, которая вернет значение регистра конфигурации
{
	char c_byte[8]=0; //объявим переменную в которую будет считан байт конфигурации
  	if(dt_testdevice()==1) //ШАГ 1. Определим, есть ли устройство на шине
	{
		dt_sendbyte(0xCC); //ШАГ 2. Пропустим идентификацию
		dt_sendbyte(0xBE); //ШАГ 3. Команда чтения
		for(int i=0; i<9; i++) // последовательно прочитаем 5 байт в одну и ту же переменную
      						// и остановимся на пятом (Configuration Register)
		{
          	if(i==4){c_byte=dt_readbyte();}
          	else{dt_readbyte();}
		}
    }
	return c_byte;
}

А вы можете намекнуть, как проверить CRC? (Это контрольная сумма, я правильно понял?)

Изменено пользователем -=FISHER=-

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    500
Только что, -=FISHER=- сказал:

А вы можете намекнуть, как проверить CRC?

А чего тут намекать? Я прямо скажу: в avr-gcc стандартно включен модуль поддержки CRC util/crc16.h, подключив который, вы поимеете в распоряжении функцию _crc_ibutton_update(uint8_t __crc, uint8_t __data), при помощи которой и считается CRC: заводите переменную uint8_t crc, обнуляете её перед считыванием, затем каждый считанный байт data пропускаете через эту функцию: crc = _crc_ibutton_update(crc, data), а потом смотрите, что там в crc посчиталось.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
3 часа назад, ARV сказал:

затем каждый считанный байт data пропускаете через эту функцию: crc = _crc_ibutton_update(crc, data), а потом смотрите, что там в crc посчиталось.

Данные будут достоверны, только если после считывания всех байтов, crc останется равной 0 ? А если не останется, то? И почему настолько важно считать CRC?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Darth_Vader    64
6 минут назад, -=FISHER=- сказал:

А если не останется, то?

То, что данные приняты с ошибкой.

6 минут назад, -=FISHER=- сказал:

И почему настолько важно считать CRC?

Вам без разницы с какими данными работать?

Изменено пользователем Darth_Vader

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
KomSoft    375
16 minutes ago, -=FISHER=- said:

если не останется, то?

Вы прочитали погоду на Марсе. Один или несколько байтов неправильные. Или наводки на линию, илм временные интервалы не соблюдены. Обрабатывая такие данные, можете получить что угодно и долго мучаться вопросом, почему так получилось.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
13 минуты назад, Darth_Vader сказал:

Вам без разницы с какими данными работать?

Ну хотелось бы с правильными)) Я верно описал суть это проверки с помощью 

 

4 часа назад, ARV сказал:

модуль поддержки CRC util/crc16.h

?

Только что, KomSoft сказал:

Вы прочитали погоду на Марсе. Один или несколько байтов неправильные.

А потом на Марсе начинают происходить события по мотивам DOOM3 )))

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    500

Если вы читали описание стандарта 1-wire, вы должны понимать, что надежного обмена он принципиально не гарантирует - оставлять логический уровень в линии на откуп заряда распределенной емкости через подтягивающее сопротивление - это очень малонадежный способ. Кроме того, стандарт допускает, что в линию в любой момент может быть добавлено еще одно устройство, которое начинает с того, что выдает PRESENCE_PULSE, т.е. тупо утягивает линию в 0 на сотню микросекунд, не менее. Что будет с данными, которые вы в это время считывали?

Поэтому единственная гарантия, что вы на самом деле получили информацию от датчика, а не от солнечного ветра или грозовых разрядов, является проверка CRC. А единственная гарантия, что датчик получил от вас какую-то инфу, это повторное вычитывание этой инфы из него (но к термодатчику это относится не особо сильно).

Лучше раз и навсегда сделать правильные функции, чем потом гадать, почему иногда что-то странное происходит...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
20 минут назад, ARV сказал:

Лучше раз и навсегда сделать правильные функции, чем потом гадать, почему иногда что-то странное происходит...

В частности вы имеете ввиду добавить функцию проверки контрольной суммы при чтении данных?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас