Перейти к содержанию

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


-=FISHER=-

Рекомендуемые сообщения

Здравствуйте!

 

В своей поделке применил датчик DS18B20, чтобы сэкономить провода, решил подключить его по двум проводам или при помощи так называемого паразитного питания. Однако, он всегда выдает мне температуру 27,5 С, и не изменяет показания при нагреве. Если же подключить его тремя проводами с отдельным питанием, то он сразу же начинает правильно измерять температуру. Опытные люди, будьте добры, подскажите в чём может быть проблема? Код и схема во вложении. Заранее спасибо!

Схема:

Скрытый текст

1.thumb.jpg.f6685d34d6fc443574e3bdc4ffe00442.jpg

Код для работы с DS18B20:

Скрытый текст

 


#include "DS18B20.h"

//функция определения датчика на шине
char dt_testdevice(void) //dt - digital termomether | определим, есть ли устройство на шине
{
	char stektemp=SREG;// сохраним значение стека
	cli(); //запрещаем прерывание
	char dt;
	DDRTEMP |= 1<<BITTEMP; //притягиваем шину
	_delay_us(485); //задержка как минимум на 480 микросекунд
	DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
	_delay_us(65); //задержка как максимум на 60 микросекунд
	if ((PINTEMP & (1<<BITTEMP))==0)//проверяем, ответит ли устройство
	{
		dt=1;//устройство есть
	} 
	else dt=0;//устройства нет
	SREG = stektemp;// вернем значение стека
	_delay_us(420); //задержка как минимум на 480 микросекунд, но хватит и 420, тк это с учетом времени прошедших команд
	return dt; //вернем результат
}


//функция записи бита на устройство
void dt_sendbit(char bt)
{
	char stektemp=SREG;// сохраним значение стека
	cli(); //запрещаем прерывание
	DDRTEMP |= 1<<BITTEMP; //притягиваем шину
	_delay_us(2); //задержка как минимум на 2 микросекунды
	if(bt)
		DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
	_delay_us(65); //задержка как минимум на 60 микросекунд
	DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
	SREG = stektemp;// вернем значение стека
}
//функция записи байта на устройство
void dt_sendbyte(unsigned char bt)
{
	char i;		
	for(i=0;i<8;i++)//посылаем отдельно каждый бит на устройство
	{
		if((bt & (1<<i)) == 1<<i)//посылаем 1
			dt_sendbit(1);
		else //посылаем 0
			dt_sendbit(0);
	}	
}

//функция чтения бита с устройства
char dt_readbit(void)
{
	char stektemp=SREG;// сохраним значение стека
	cli(); //запрещаем прерывание
	char bt; //переменная хранения бита
	DDRTEMP |= 1<<BITTEMP; //притягиваем шину
	_delay_us(2); //задержка как минимум на 2 микросекунды
	DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
	_delay_us(13);
	bt = (PINTEMP & (1<<BITTEMP))>>BITTEMP; //читаем бит
	_delay_us(45);
	SREG = stektemp;// вернем значение стека
	return bt; //вернем результат
}

//функция чтения байта с устройства
unsigned char dt_readbyte(void)
{
	char c=0;
	char i;
	for(i=0;i<8;i++)
		c|=dt_readbit()<<i; //читаем бит
	return c;
}

//функция преобразования показаний датчика в температуру
int dt_check(void)
{
	unsigned char bt;//переменная для считывания байта
	unsigned int tt=0;
	if(dt_testdevice()==1) //если устройство нашлось
	{
		dt_sendbyte(NOID); //пропустить идентификацию, тк у нас только одно устройство на шине
		dt_sendbyte(T_CONVERT); //измеряем температуру
		_delay_ms(750); //в 9 битном режиме преобразования - 750 милисекунд
		dt_testdevice(); //снова используем  те же манипуляции с шиной что и при проверке ее присутствия
		dt_sendbyte(NOID); //пропустить идентификацию, тк у нас только одно устройство на шине
		dt_sendbyte(READ_DATA); //даем команду на чтение данных с устройства
		bt = dt_readbyte(); //читаем младший бит
		tt = dt_readbyte(); //читаем старший бит MS
		tt = (tt<<8)|bt;//сдвигаем старший влево, младший пишем на его место, тем самым получаем общий результат
	}
	return tt;
}

//преобразование температуры в единицы
char converttemp (unsigned int tt)
{
	char t = tt>>3;//сдвиг и отсечение части старшего байта
	return t;
}

 

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

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

А вы подаете на линию данных 5 вольт "без резистора" - чтобы паразитно его запитать?

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

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

А вы подаете на линию данных 5 вольт "без резистора"?

С подтяжкой 4,7к... В даташите правда говорят что нужно ещё мосфет для увеличения тока в момент конвертации и чтения температуры, однако я встречал схемы и без мосфета, где со слов автора паразитное питание и так работает.

321.JPG.60699a60d1469b0a3c6ce08e73c2a8a1.JPG

Вывод - уменьшить номинал подтягивающего резистора?

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

какая длина провода до датчика? Подключите датчик пока прямо на разъём.

и что-то странное у вас в коде с сохранением и восстановлением стека, можете получить большие проблемы используя такой код на Си. Похоже код переводили с asm на Си. Лучше сохранять только флаг прерывания (I).

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

В чем смысл сохранять стек? Да и с запретом прерываний все странно.

Включение и выключение pull-up резистора - зачем?

Изменено пользователем Darth_Vader
Ссылка на комментарий
Поделиться на другие сайты

Без принудительного соединения линии данных с 5в (отдельный MOSFET не нужен, у вас МК может выполнить эту функцию) работают только датчики с маркировкой DS18B20P или PAR.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

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

стр.11

Convert T [44h]

If the device is being used in parasite power mode, within 10μs (max) after this command is issued the master must enable a strong pullup on the 1-Wire bus for the duration of the conversion (t CONV) as described in the Powering the DS18B20 section.

видимо надо подавать "честную" единичку на 10 мкс после команды конвертации [44h]

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

35 минут назад, technik-1017 сказал:

видимо надо подавать "честную" единичку на 10 мкс после команды конвертации [44h]

Только не на 10 мкс, а максимум 10 мкс спустя подачи команды, и держать её не менее длительности измерения.

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

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

какая длина провода до датчика? Подключите датчик пока прямо на разъём.

Испытываю поделку на столе, длинна провода не более 10 см.

12 часа назад, Darth_Vader сказал:

В чем смысл сохранять стек? Да и с запретом прерываний все странно.

Код работы с датчиком писал не я, взял с урока про программированию МК. С обычным подключением этот код хорошо отрабатывает...

 

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

видимо надо подавать "честную" единичку на 10 мкс после команды конвертации [44h]

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

Только не на 10 мкс, а максимум 10 мкс спустя подачи команды, и держать её не менее длительности измерения.

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

		dt_sendbyte(T_CONVERT); //измеряем температуру
		_delay_ms(750); //в 9 битном режиме преобразования - 750 милисекунд

Я так понимаю принудительно подать 1 на ножку, к которой подключен сигнальный контакт датчика, вот типа так?

DDRTEMP &= ~(1<<BITTEMP);

PINTEMP &= (1<<BITTEMP);

 

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

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

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

А вы можете на пальцах объяснить пожалуйста, что значит подавать честную единичку?...

По стандарту 1-wire ведущее устройство либо притягивает линию данных к нулю, формируя в ней 0, либо "отпускает" её в третье состояние, т.е. как бы бросает неподключенной, и тогда линия за счет подтягивающего резистора сама возвращается к лог.1. Подавать честную единичку - это значит, вместо "отпускания" линии выдать в неё 1 принудительно. Т.е. соединить линию с +5 не через резистор, а напрямую через порт МК.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

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

Т.е. соединить линию с +5 не через резистор, а напрямую через порт МК.

Отпустить и выдать на пин 1 так?:

DDRTEMP &= ~(1<<BITTEMP);

PINTEMP &= (1<<BITTEMP);

 

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

DDRTEMP &= ~(1<<BITTEMP); устанавливает в соответствующем DDR-бите НОЛЬ, т.е. "отпускает" пин в третье состояние. А следующая команда у вас испортит регистр. А надо просто вывести 1 в оба регистра:

PINTEMP |= (1<<BITTEMP);
DDRTEMP |= (1<<BITTEMP);

А после замера вернуть, как было.

Причем именно в том порядке, как я написал: сначала вывести 1, т.е. включить внутреннюю подтяжку, а потом перевести порт на вывод "жесткой" единицы, иначе у вас кратковременно в линии пролетит 0 - мало ли, как датчик на него среагирует...

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

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

 


DDRTEMP |= (1<<BITTEMP);

PINTEMP |= (1<<BITTEMP);

А после замера вернуть, как было.

Я правильно понял смысл, что необходимо отпустить шину и выставить на ней 1 и так продержать весь промежуток вот этой задержки? Как раз пока идёт заполнение регистров датчика?

_delay_ms(750); //в 9 битном режиме преобразования - 750 милисекунд

 

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Правильно - датчик будет питаться от этой линии.

Обратите внимание: я подкорректировал свое сообщение - ваша цитата уже не соответствует истине!

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

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

Правильно

Спасибо! Я сейчас пробежался по функциям и понял, что перед тем как "уйти в задержку" на 750мс, шина "отпущена", то есть достаточно дописать только вторую строчку перед задержкой и вот такую после, так?

PINTEMP |= (1<<BITTEMP); //выставляем 1 на шине, шина к этому моменту уже отпущена
_delay_ms(750); //в 9 битном режиме преобразования - 750 милисекунд
PINTEMP &= ~(1<<BITTEMP); //выставляем 0 на шине

 

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

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

то есть достаточно дописать только вторую строчку перед задержкой и вот такую после, так?

Не так. Шина отпущена - это значит, режим пина "ввод", а надо ВЫВОД.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

@ARV Чтобы не создавать отдельную тему, не могли бы Вы глянуть схему, приведенную мной в первом посте. Всё вроде бы работает, но почему-то наблюдается писк дросселя... Дроссель вроде как рекомендуют включать для дополнительной точности опорного напряжения.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

КАК может пищать дроссель, по которому не течет силовой пульсирующий ток?! 

5b6fd0cb62e048e48d26b04993b96622_2440a91

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

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

КАК может пищать дроссель?! 

Но если его убрать с платы, писк пропадает... Я кстати использую SMD дроссель.

И ещё плата потребляет 120-140 мА (мне кажется это многовато или нет?), да так что МС L78M05CDT ощутимо греется, хотя рассчитана на ток до 500мА.

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

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Какой ток через сегменты задает MAX? 7 сегментов по 15мА - это 105мА. (например). А (12-5)*0.12 - 0.8Вт, это много для работы без радиатора, будет ощутимо греться, что вы и получаете. Тут главное не ток, а рассеиваемая мощность. 

Судя по резистору R1 вы задали ток через сегменты 30-40мА. Увеличьте его - яркость упадет, но ток уменьшится. Если использован нормальный индикатор, то 40мА даже пикового тока - это много. Если яркость устраивает, то можно увеличивать его до 60кОм (примерно)

Screenshot_2018-08-08-10-21-01-653_com.google.android.apps.docs.png

Настоящему коту и в декабре март!

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

Если дроссель пищит, это однозначно свидетельствует о том, что через него течет пульсирующий ток. Это может быть только в одном случае: у вас по питанию гуляют страшные пульсации - больше взяться току через дроссель не из-за чего, потребление опорного источника AVR мизерное. Так же я могу предположить, что на С6 тоже пульсации будут - проконтролируйте осциллографом. Если там окажутся пульсации больше 2 мВ - это будет свидетельствовать о том, что толку от ADC будет не много. 

В качестве теста отключите программно индикацию - пропадет писк? Если пропадет, вы выяснили причину. Вероятно, проблема в плохой разводке платы... но гадать не буду.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

7 часов назад, ARV сказал:

В качестве теста отключите программно индикацию - пропадет писк?

Писка нет, если плата работает от программатора. Писк только если подключаю плату к 12В от ЛБП.

9 часов назад, ARV сказал:

Не так.

Сделал вот так, теперь показывает всегда 85 С...

		DDRTEMP |= 1<<BITTEMP; //притягиваем шину
		PINTEMP |= (1<<BITTEMP); //выставляем 1 на шине
		_delay_ms(750); //в 12 битном режиме преобразования - 750 милисекунд
		PINTEMP &= ~(1<<BITTEMP); //выставляем 0 на шине
		DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину

Что я сделал не так?

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

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

DDRTEMP &= ~ (1<<BITTEMP); // настраиваем порт на ввод. Подтяжка к "1" за счёт внешнего резистора
PINTEMP |= (1<<BITTEMP);   // включаем подтяжку к "1" внутри контроллера
DDRTEMP |= 1<<BITTEMP; 	   // настраиваем порт на вывод, появляется честная "1"
_delay_ms(750); //в 12 битном режиме преобразования - 750 милисекунд
DDRTEMP &= ~(1<<BITTEMP);  // настраиваем порт на ввод. Осталась подтяжка к "1" внутри контроллера
PINTEMP &= ~(1<<BITTEMP);  // отключаем подтяжку к "1" внутри контроллера. Осталась только подтяжка за счёт внешнего резистора

а PINTEMP это случайно не PINx?
Должно быть PORTTEMP, т.е. PORTx

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

По крайней мере, 85 - это показания датика "по умолчанию", т.е. после того, как подали на него питание, но не подали команду "старт преобразования". Иначе говоря, датчик не получил команду, но отвечает корректно.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

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

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...