Датчик заявлен как высокоточный, +/- 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.