Pull to refresh

Температурный датчик NST1002 от компании Novosense

Level of difficultyMedium
Reading time5 min
Views3K

Датчик заявлен как высокоточный, +/- 0.1 градуса для 0…+85 град. С, в корпусе DFN-2L. Для всего диапазона температур -40 … +150 градусов точность несколько хуже, до +/- 0.5 градуса. У датчика 15-ти битное АЦП, восемь разрядов на градусы и семь на дробную часть, что дает разрешающую способность 1/128 или 0.0078125 градуса. Время преобразования и считывания данных порядка 32-х миллисекунд. Подключается он по шине 1-Wire и имеет два варианта конструктивного исполнения: DFN-2L (1.6 x 0.8 мм) и TO-92S-2L (4.0 x 3.0 mm).

 

Типовая схема подключения показана на Рис.1 и требует 2 ножки микроконтроллера. GPIO1 используется для управления обменом, GPIO2 для считывания данных. Параметры микросхемы приведены для +25°C, напряжении питания от +1.7V до +5.5V и резисторе подтяжки 4.7 кОм.

Рис. 1 Схема подключения NST1002

 Обмен с микроконтроллером показан на Рис. 2. Его начало инициируется сбросом питания (GPIO1) в ноль на время 200 микросекунд. Этот импульс запускает в датчике процесс преобразования температуры. Он длится около 30 миллисекунд и по его окончании датчик выдает 17-ти микросекундный импульс (показан на рисунке пунктиром), который микроконтроллер считывает по линии GPIO2.

Рис. 2 Обмен данными с микроконтроллером

Это означает, что процесс завершен корректно и датчик готов передавать данные. Передача данных происходит побитно, сбросом линии питания (GPIO1) в ноль на время порядка 1-2 микросекунды. При этом датчик удерживает нулевой потенциал примерно либо 7…10 микросекунд (что означает «1»), либо 18…21 микросекунду (что означает «0»). Интервал между импульсами сброса должен быть не менее 60-ти микросекунд, таким образом 24 бита данных передадутся минимально за 1440 микросекунд. Данные считываются соответственно по линии GPIO2, их формат показан на Рис. 3.

Рис. 3 Формат принимаемых данных

Первые 16 бит это данные, из которых старший бит – это знак; следующие 8 бит – CRC код в формате Maxim/Dallas. Отрицательные значения температуры передаются в дополнительном коде. Пример вычисления CRC показан на Рис.4 ниже. Не обязательно также считывать все 24 бита. Для получения температуры в целых градусах достаточно считать первые 9 бит.

Следует отметить, что процесс считывания данных должен начаться не позднее 5-ти миллисекунд после импульса готовности. Иначе датчик перейдет в дежурный режим (idle state), и будет выдавать все время одни и те же данные -> 0x18 0x6E 0xE0.

 

Рис. 4 Пример вычисления CRC

 

Импульс готовности, чтение 16 бит данных и затем стартовый импульс, снятые логическим анализатором, показаны на Рис. 5 ниже.

 

Рис. 5 Данные с датчика NST1002-CDNR

 Чтение данных было организовано с помощью микроконтроллера STM32F103C8T6 c тактовой частотой 72 МГц. С помощью прерывания от таймера была получена временная сетка с шагом 5 микросекунд. Формирование сигналов и чтение данных организовано в обработчике прерывания. Для того чтобы минимизировать в нем количество проверок, был создан массив задержек от начала последовательности для фронтов arr[25]  (PB1 -> “0”; PB1 -> ”1”) и массив задержек для чтения данных brr[24]. С их помощью сначала формируется импульс 300 мкс для сброса датчика NST1002; затем примерно через 31 миллисекунду, когда датчик гарантировано выдает импульс окончания преобразования, формируются импульсы побитного считывания данных.

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

Код формирования массивов приведен ниже. Они объявлены как const и располагаются во Flash памяти, возможно размещение их в ОЗУ позволит несколько убыстрить работу обработчика.

	uint32_t index_arr = 0, index_brr = 0, index_data = 0;
	uint32_t arr_data[90] = {0};
	const uint32_t arr[25*2] = {
		100/5, 400/5,
		(31500+(60* 0))/5, (31505+(60* 0))/5, 
		(31500+(60* 1))/5, (31505+(60* 1))/5,
		(31500+(60* 2))/5, (31505+(60* 2))/5,
		(31500+(60* 3))/5, (31505+(60* 3))/5,
		(31500+(60* 4))/5, (31505+(60* 4))/5,
		(31500+(60* 5))/5, (31505+(60* 5))/5,
		(31500+(60* 6))/5, (31505+(60* 6))/5,
		(31500+(60* 7))/5, (31505+(60* 7))/5,
		(31500+(60* 8))/5, (31505+(60* 8))/5,
		(31500+(60* 9))/5, (31505+(60* 9))/5,
		(31500+(60*10))/5, (31505+(60*10))/5,
		(31500+(60*11))/5, (31505+(60*11))/5,
		(31500+(60*12))/5, (31505+(60*12))/5,
		(31500+(60*13))/5, (31505+(60*13))/5,
		(31500+(60*14))/5, (31505+(60*14))/5,
		(31500+(60*15))/5, (31505+(60*15))/5,
		(31500+(60*16))/5, (31505+(60*16))/5,
		(31500+(60*17))/5, (31505+(60*17))/5,
		(31500+(60*18))/5, (31505+(60*18))/5,
		(31500+(60*19))/5, (31505+(60*19))/5,
		(31500+(60*20))/5, (31505+(60*20))/5,
		(31500+(60*21))/5, (31505+(60*21))/5,
		(31500+(60*22))/5, (31505+(60*22))/5,
		(31500+(60*23))/5, (31505+(60*23))/5
	};
	
	const uint32_t brr[24] = {
		(31515+(60* 0))/5, 
		(31515+(60* 1))/5,
		(31515+(60* 2))/5,
		(31515+(60* 3))/5,
		(31515+(60* 4))/5,
		(31515+(60* 5))/5,
		(31515+(60* 6))/5,
		(31515+(60* 7))/5,
		(31515+(60* 8))/5,
		(31515+(60* 9))/5,
		(31515+(60*10))/5,
		(31515+(60*11))/5,
		(31515+(60*12))/5,
		(31515+(60*13))/5,
		(31515+(60*14))/5,
		(31515+(60*15))/5,
		(31515+(60*16))/5,
		(31515+(60*17))/5,
		(31515+(60*18))/5,
		(31515+(60*19))/5,
		(31515+(60*20))/5,
		(31515+(60*21))/5,
		(31515+(60*22))/5,
		(31515+(60*23))/5
	};

Для этого каждые 60 мкс линия питания датчика опускается в “0” на 5 микросекунд, затем поднимается в “1” и так 24 раза подряд. Датчик NST1002 удерживает линию в “0” либо на время около 10 микросекунд (бит = "1"), либо на 20 микросекунд (бит = "0").

Для чтения бита мы считываем PB2 в момент, отстоящий на 15us от падающего питания PB1 -> “0”. Считанный бит плюсуется к переменной, затем ее биты сдвигаются влево, и так 23 раза (кроме последнего). Код обработчика прерывания приведен ниже.

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim){
		if(ccc == 1){
			//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 0);
			aaa++;
				if(aaa == arr[index_arr]){
					if((index_arr & 0x01) == 0) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, 0);
					else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, 1);
					
					index_arr ++;					
				}
				
				if(aaa == brr[index_brr]){
					if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2)) dataBRR ++;
					if(index_brr != 23) dataBRR = dataBRR << (1);				
					index_brr ++;	
				}
				
				
				if(index_brr == 24){
					if(index_data < 90){
						arr_data[index_data] = dataBRR;
					}else{
						ccc = 0;
					}
				index_data ++;	
				dataBRR = 0;
				aaa = 0; 
				index_arr = 0;
				index_brr = 0;				
		}
		//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 1);	
	}
}

С точки зрения использования аппаратных ресурсов микроконтроллера данное решение не является оптимальным, но вполне работоспособным. Время нахождения в обработчике примерно 1,2 микросекунды из 5-ти, что позволяет микроконтроллеру выполнять и другие задачи.

Экспериментальные данные температуры, полученные от NST1002-CDNR со скоростью чтения примерно 30 раз в секунду, представлены ниже на Рис. 6. Сам датчик находился при комнатной температуре в неподвижном воздухе и для достижения стабильных показаний был обернут фольгой.

Рис 6 Данные температуры с датчика NST1002

Заявленный Novosense температурный дрейф –> 0.4 градуса после 1000 часов наработки при +125 градусах С. Таким образом, NST1002 представляет вполне достойную альтернативу температурным датчикам американских и европейских производителей.

Выражаю отдельную благодарность компании MTsystem за предоставленные образцы NST1002-CDNR.

High-precision Single-BUS Digital Temperature Sensor

Tags:
Hubs:
Total votes 3: ↑3 and ↓0+4
Comments34

Articles