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

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


-=FISHER=-

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

В 10.08.2018 в 08:19, ARV сказал:

У вас же как бы часы многофункциональные?

 

В 10.08.2018 в 08:32, -=FISHER=- сказал:

В яблочко :)

Введите коррекцию хода. Разместите одну ячейку в ЕЕПРОМ, куда запишете размер коррекции хода часов (в секундах). При переходе на следующие сутки (в полночь) можете корректировать время автоматически на записанный размер. Таким способом можно повысить точность хода часов.

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

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

1 минуту назад, Геннадий сказал:

 

Введите коррекцию хода.

А значение подбирать эксперементально?

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

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

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

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

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

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

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

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

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

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

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

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

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

А значение подбирать эксперементально?

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

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

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

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

  • 1 год спустя...

Всем здравствуйте!

Спустя несколько лет я вернулся к этому проекту и заметил странную "штуку". Вкратце напомню, основной проблемой была настройка DS18b20 на 9 битный режим измерения. У меня это в целом получилось, теперь время измерения температуры составляет 100 мс, вместо 750 мс. Сразу же приведу код:

DS18B20.c

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

#include "DS18B20.h"

char Cminus;

//функция определения датчика на шине
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(SkipROM); //пропустить идентификацию, тк у нас только одно устройство на шине
		dt_sendbyte(ConvertT); //измеряем температуру
		DDRTEMP &= ~ (1<<BITTEMP); // настраиваем порт на ввод. Подтяжка к "1" за счёт внешнего резистора
		PORTTEMP |= (1<<BITTEMP);   // включаем подтяжку к "1" внутри контроллера
		DDRTEMP |= 1<<BITTEMP; 	   // настраиваем порт на вывод, появляется честная "1"
		_delay_ms(100); //в 9 битном режиме преобразования - 100 милисекунд
		DDRTEMP &= ~(1<<BITTEMP);  // настраиваем порт на ввод. Осталась подтяжка к "1" внутри контроллера
		PORTTEMP &= ~(1<<BITTEMP);  // отключаем
		dt_testdevice(); //снова используем  те же манипуляции с шиной что и при проверке ее присутствия
		dt_sendbyte(SkipROM); //пропустить идентификацию, тк у нас только одно устройство на шине
		dt_sendbyte(ReadScratchpad); //даем команду на чтение данных с устройства
		bt = dt_readbyte(); //читаем младший бит LS
		tt = dt_readbyte(); //читаем старший бит MS, здесь знак -
		tt = (tt<<8)|bt;//сдвигаем старший влево, младший пишем на его место, тем самым получаем общий результат
	}
	return tt;
}

//преобразование температуры в единицы
char converttemp (unsigned int tt)
{
	char t = tt>>4;//сдвиг и отсечение части старшего байта
	if(t&(1<<7))
	{
		t=~t;
		if(t==0x00){Cminus=0;}
		else{Cminus=1;}
	}
	else
	{Cminus=0;}
	return t;
}

void Set_Resolution (void)
{ 
	if(dt_testdevice()==1) //если устройство нашлось
	{ 
//********************ЗАПИСЬ В ОЗУ**************************
		DDRTEMP &= ~(1<<BITTEMP);  // настраиваем порт на ввод
		dt_sendbyte(SkipROM); //пропустить идентификацию, тк у нас только одно устройство на шине
		dt_sendbyte(WriteScratchpad); //отправляем команду записи в память
		dt_sendbyte(0); //записываем нули в TH регистр
		dt_sendbyte(0); //записываем нули в TL регистр
		dt_sendbyte(Resolution9bit); //записываем нули в регистр конфигурации R0=0, R1=0, разрешение 9 бит
//********************КОПИРОВАНИЕ ОЗУ В ПЗУ (EEPROM)**************************
		DDRTEMP &= ~ (1<<BITTEMP); // настраиваем порт на ввод. Подтяжка к "1" за счёт внешнего резистора
		dt_sendbyte(CopyScratchpad); //отправляем команду копирования ОЗУ в EEPROM
		PORTTEMP |= (1<<BITTEMP);   // включаем подтяжку к "1" внутри контроллера
		DDRTEMP |= 1<<BITTEMP; 	   // настраиваем порт на вывод, появляется честная "1"
		_delay_ms(10);  // задержка 10 млсек (необходима после выполнения команды COPY_SCRATCHPAD)
		DDRTEMP &= ~(1<<BITTEMP);  // настраиваем порт на ввод. Осталась подтяжка к "1" внутри контроллера
		PORTTEMP &= ~(1<<BITTEMP);  // отключаем подтяжку к "1" внутри контроллера. Осталась только подтяжка за счёт внешнего резистора  
	}
}

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

 

DS18B20.h

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

#ifndef DS18B20_H_
#define DS18B20_H_

#include "main.h"

#define SkipROM 0xCC //Определение датчика на шине
#define ConvertT  0x44 //Команда измерения температуры
#define ReadScratchpad 0xBE //Команда чтения ОЗУ
#define WriteScratchpad 0x4E //Команда записи в ОЗУ
#define CopyScratchpad 0x48 //Команда копирования ОЗУ в EEPROM
#define Resolution9bit 0x1F //значение конфигурационного регистра для расрешения 9 бит
#define Resolution12bit 0x7F //значение конфигурационного регистра для расрешения 12 бит

#define PORTTEMP PORTB
#define DDRTEMP DDRB
#define PINTEMP PINB
#define BITTEMP 1

int dt_check(void); //функция преобразования показаний датчика в температуру
char converttemp (unsigned int tt); //преобразование температуры в единицы
void Set_Resolution (void); //функция установки разрешения
char dt_readscratchpad(void); //функция чтения из ОЗУ значение битов разрешения

#endif /* DS18B20_H_ */

 

Сейчас я наблюдаю такую ситуацию: если в начале программы я запускаю функцию проверки того, какой режим сейчас включен, то в таком случае температура отображается корректно.

if (dt_readscratchpad()==Resolution12bit){Set_Resolution();} //если устанолено разрешение 12 бит, то установим 9 бит

Но ведь эта информация должна по идее заноситься в EEPROM датчика DS18B20 ? И достаточно, чтобы функция SetResolution() выполнилась только один раз для одного и того же датчика? Однако, если я эту строчку потом убираю, то после сброса питания датчик начинает выдавать 85 градусов... Проверьте пожалуйста и скажите, где же я ошибся?

 

Получается что данные записываются в EEPROM датчика, но не сохраняются? Или они не записываются в EEPROM, а остаются в ОЗУ?

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

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

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

(понимаю, что так разговор начинать нельзя, типа сам не делал, но учу. Но...) Непосредственно программированием 18В20 не занимался, а вот сейчас ради интереса залез в даташит. А там написано: Clipboard01.png.4c43d12842765fbee337070cfbd4433c.png

т.е. данные сохраняются в еепром и считываются при включении питания. Или могут быть загружены в любой момент командой Recall E2.

А вот на следующей странице написано вот так: CONFIGURATION REGISTER
Byte 4 of the scratchpad memory contains the configuration register, which is organized as illustrated in
Figure 8. The user can set the conversion resolution of the DS18B20 using the R0 and R1 bits in this
register as shown in Table 2. The power-up default of these bits is R0 = 1 and R1 = 1 (12-bit resolution).

Т.е. состояние при включении питания - 12-битное разрешение. Вот и пойми этих разработчиков!

А вы после установки разрешения записываете данные в еепром командой Copy Scratchpad [48h]? Попробуйте насильно после включения загрузить данные из еепром (вместо задания разрешения). Иначе ничего не останется, как задавать разрешение каждый раз при инициализации.

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

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

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

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

Но ведь эта информация должна по идее заноситься в EEPROM датчика DS18B20 ?

что мешает после выполнения 0x48 //Команда копирования ОЗУ в EEPROM

отправить команду 0xB8 // загрузка  EEPROM в ОЗУ

и прочитать что фактически записалось в EEPROM ?

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

21 минуту назад, IMXO сказал:

что мешает

А сама процедура записи правильная?

53 минуты назад, KomSoft сказал:

Т.е. состояние при включении питания - 12-битное разрешение. Вот и пойми этих разработчиков!

А для чего же тогда нужен EEPROM интересно?

 

54 минуты назад, KomSoft сказал:

А вы после установки разрешения записываете данные в еепром командой Copy Scratchpad [48h]?

Да, вы можете посмотреть, я там выше код выложил

1 час назад, KomSoft сказал:

Иначе ничего не останется, как задавать разрешение каждый раз при инициализации.

Не хотелось бы, ведь количество циклов записи EEPROM ограничено...

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

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

7 минут назад, IMXO сказал:

нет

Хммм...но ведь у меня заработал таки 9 битный режим. Измерение температуры занимает 100 мм и корректно отображается, значит хоть что-то верно?...

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

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

да никто не станет делать две прошивки - чтобы одной прошивкой записать EEPROM, а другой прошивкой пользоваться только данными из EEPROM.

гораздо разумнее в начале прошивки записать конфигурацию в ОЗУ, а про EEPROM забыть.

Мудрость приходит вместе с импотенцией...

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

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

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

гораздо разумнее в начале прошивки записать конфигурацию в ОЗУ, а про EEPROM забыть.

Слушайте...а ведь и правда!

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

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

8 минут назад, Starichok сказал:

гораздо разумнее в начале прошивки записать конфигурацию в ОЗУ, а про EEPROM забыть.

угу... и в процессе работы при отключении и включении датчика получить на выход 12бит вместо 9и

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

может, у кого-то и есть необходимость отключать и подключать датчик "на ходу", тогда эти люди пусть записывают конфигурацию в EEPROM.

лично я такую необходимость не вижу нужной.

Мудрость приходит вместе с импотенцией...

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

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

1 hour ago, -=FISHER=- said:

ведь количество циклов записи EEPROM ограничено...

Хорошо. При инициализации читаете разрешение. Если оно 9 бит - работаете, если 12 - записываете нужное. Таким образом при подключении нового датчика вы установите нужное разрешение, а при подключении уже "прошитого" - EEPROM насиловать не будете. Код чуть усложниться.

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

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

23 минуты назад, KomSoft сказал:

Код чуть усложниться.

У меня на данный момент так и реализовано.

30 минут назад, IMXO сказал:

у меня на производстве стоит 9 контроллеров

В таком случае конечно, только EEPROM, но для моей любительской поделки сойдет вариант и с ОЗУ. :)

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

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

А в чем проблема всегда после подачи питания загружать настройки из EEPROM в ОЗУ? А потом проверить режим и, если не 9-бит, тогда обновлять EEPROM и ОЗУ?

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

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

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

всегда после подачи питания загружать настройки из EEPROM в ОЗУ

зачем? они сами при подаче питания туда загружаются или нет?

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

5 часов назад, IMXO сказал:

зачем? они сами при подаче питания туда загружаются или нет?

Я не помню даташит наизусть... Но раз есть проблема с режимом, значит, что-то тут не так...

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

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

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

А в чем проблема всегда после подачи питания загружать настройки из EEPROM в ОЗУ

Тогда может быть и правда проще всего каждый раз при подаче питания загружать 9 битный режим в ОЗУ самостоятельно и никакого EEPROM?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Сообщения

    • Согласен, очень криво объяснил. Это работа трёх вольтовой линии, просто на диод шотки сдвоенный, на один анод приходит сигнал напрямую с трансформатора, а на второй через дроссель. Вольт/деление 5 вольт в клетке, тайминг по моему 10 МС. Третья фотография это сигнал на катодах уровень земли ровно по центру экрана. Но все линии по итогу в порядке 3.3 в, 5, в, 12 в и -12 в. Нагрузить все линии не могу сразу ,так как тут же выгорают транзисторы (имеется нагрузка 250 ватт по 10 ампер на каждую линию за исключением-12в), поэтому нагружаю 3.3 вольтовую линию на 10 ампер,  подключаю переменный резистор 50 ватт на 15 ом на 5 вольтовую линию и постепенно довожу до той той картины с перекосом (это гдето  50 ватт общее). По поводу микросхемы, вверху имеется скрин где между импульсами проскакивает мини импульс, если так можно сказать, он проскакивает и на одной  и на второй ноге (7,8). Микросхема не tl 494, а lw4933/abx942.1/c9421646. Далее они приходят на базы транзисторов 945g  коллекторы этих транзисторов соединены с  выводами трансформатора. Просто схема типовая, легче мне кажется просто привести фото самого блока, для тех кто разбирается будет гораздо информативне.  Диод шотки по 12 вольтовой линии был подгоревший, заменил на донора. Приводить скрины не буду что бы не захламлять тему. В итоге, пока все так же, при достижении определенной нагрузки суммарно где-то 50 ватт, появляется этот "выброс и перекос". По этому имеются мысли на два варианта, это микросхема , этот мини импульс между периодами, на низкой нагрузке особо не влияет, но при достижении определенной приводит с самовозбуждению входной цепи и непроизвольному открытию транзистора нижнего плеча. Либо дело в "горячей части", плавающий дефект в обвязке силовых ключей.  Спасибо за ответ.
    • @Gomerchik а вы контролировали как меняется уровень сигнала на А1 ардуины?
    • Спасибо за совет. Автором данного проекта я не являюсь, мне нужно было воссоздать уличный датчик для метеостанции взамен пропавшего(( Из разного найденного в интернете этот проект работает с моей станцией Орегон (спасибо автору). В понедельник попробую последовать Вашему совету. Но все равно куча непоняток  как блин это работает)) Если дело в неправильной отправки команды, то как на это влияет подключение датчика температуры? Если совсем не подключать таймер, то передача идет один раз (как и прописано в программе), станция принимает и отображает, но минут через сколько-то естественно станция уже ни чего не показывает, но с таймером питание полностью не пропадает с ардуинки, но передача сигнала каким-то образом работает по таймеру.  В моем понимании данная команда подается один раз потому, что таймер должен отключать питание МК после передачи сигнала и каждые 43 сек снова подавать питание (так того требует станция).  Ардуино передает показания температуры отключается полностью и 43 секунды мк не работает.  Сейчас у меня питание пока сделано на подпитке от солнечной батареи, но пару пасмурных дней и аккумулятор съедается до отключения(
    • thickman Так и сделаю. Вытащу из бу БП.  Буду знать, как отличить. Благодарю. Заменил транзисторы на IRFB20N50K. Картина стала, совсем другой.  Похоже трудность не в драйвере, на момент подвозбуда, переходные процессы, в нем, завершены. Увеличил затворные резисторы до 50ом, стало немного лучше.  Не понятно, почему верхний ключ греется несколько сильнее. Возможно, стоит посмотреть ток в коллекторе.  Снабберные емкости временно удалил, изменений не произошло.  Замена ТГР на другой, на кольце MSTN-16A-TH, так же, результата не принесла.   irfb20n50k.pdf
    • А что нить из ассортимента активных щупов производства СССР..))
    • Типа такого: https://aliexpress.ru/item/2044864227.html?sku_id=58855020183
×
×
  • Создать...