Цифровой датчик температуры TSic: адреса, пароли, явки

в 9:10, , рубрики: Блог компании ЭФО, программирование микроконтроллеров, продам датчик, продам микроконтроллер, Промышленное программирование, Разработка для интернета вещей, Разработка робототехники

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

Цифровой датчик температуры TSic: адреса, пароли, явки - 1Герой сегодняшней статьи, на первый взгляд, не представляет собой ничего особенного — мало ли мы видели цифровых датчиков температуры. Однако у серии TSic есть два необычных свойства: действительно высокая точность (до ±0.07°C у старшей модели) и малоизвестный однопроводной интерфейс ZACwire.

Под катом подробно описываем номенклатуру стандартных датчиков TSic и кастомные решения, разбираемся в особенностях коммуникационного протокола, смотрим примеры программ для МК. Словом, делаем всё чтобы убедить уважаемого читателя в том что датчики TSic стоят своих денег.

TSic — это серия цифровых датчиков температуры, которые в прошлом выпускались под брендом ZMDI, а сейчас принадлежат швейцарской компании IST AG.

Чувствительным элементом датчика служит высокоточный источник опорного напряжения с выходом, пропорциональным температуре (bandgap reference with a PTAT (proportional-to-absolute-temperature). Как и другие интегральные датчики температуры, TSic также содержит АЦП, схему обработки сигнала, EEPROM с данными для калибровки и выходной интерфейс.

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

Цифровой датчик температуры TSic: адреса, пароли, явки - 2

Рабочий диапазон температур и точность


Датчики TSic 20x и TSic 30x имеют рабочий диапазон температур от -50 до +150°C и три «зоны точности». На графике показана максимальная погрешность датчиков на различных диапазонах температуры.

Цифровой датчик температуры TSic: адреса, пароли, явки - 3

Датчики TSic 50x предназначены для более узкого диапазона температур — от -10 до +60°C. На участке повышенной точности шириной 40 градусов датчики TSic 50x обеспечивают точность ±0.1°C, на остальном диапазоне — ±0.2°C.

Цифровой датчик температуры TSic: адреса, пароли, явки - 4

Самый дорогой высокоточный датчик TSic — это модель TSic 716. На узком 20-градусном участке этот элемент обеспечивает ±0.07°C.

Цифровой датчик температуры TSic: адреса, пароли, явки - 5

Отличием датчика TSic 716 также является более высокая разрядность (разрешение). Если в датчиках TSic 206, TSic 306 и TSic 506 встроен 11-битный АЦП, то TSic 716 оснащен 14-разрнядным преобразователем.
Таким образом, разрешение датчиков TSic 206 и TSic 306 составляет $frac{(50 + 150)[°C]}{2^{11}} ≈ 0.1[°C]$,
разрешение TSic 506 составляет $ frac{(10 + 50)[°C]}{2^{11}} ≈ 0.034[°C]$,
разрешение TSic 716 составляет $ frac{(10 + 50)[°C]}{2^{14}} ≈ 0.004[°C]$.

Кастомная калибровка

Выше описаны стандартные исполнения датчиков TSic, однако диапазон повышенной точности любого из датчиков TSic может быть «сдвинут» при производстве элемента. Так, например, под заказ доступны датчики TSic 50x с повышенной точностью на участке от -10 до 30°C или от 13 до 53°C. Аналогично для других моделей TSic.

Цифровой датчик температуры TSic: адреса, пароли, явки - 9

Корпус


Датчики серии TSic выпускаются в корпусах SOP-8 и TO92, распиновка доступна в документации.

Цифровой датчик температуры TSic: адреса, пароли, явки - 10Цифровой датчик температуры TSic: адреса, пароли, явки - 11

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

Цифровой датчик температуры TSic: адреса, пароли, явки - 12

Подключение датчика


Для подключения любой модели TSic понадобятся соединения по питанию и земле, а также одна сигнальная линия.

Цифровой датчик температуры TSic: адреса, пароли, явки - 13

Рабочее напряжение датчика — от 3 до 5.5В. Часто датчик удобнее запитать от одного из GPIO управляющего контроллера. Во-первых, это позволяет свести к нулю энергопотребление датчика вне цикла измерений, а во-вторых, упрощается детектирование начала посылки, если используется датчик TSic с цифровым выходом.

В случае питания датчика от ножки контроллера производитель рекомендует позаботиться об исключении влияния шумов и добавить на линию питания RC-цепочку.

Выходной сигнал


Датчики TSic 20x, TSic 30x и TSic 50x могут иметь аналоговый, ратиометрический или цифровой выход. В первом случае напряжение на выходе изменяется от 0 до 1 В пропорционально температуре среды, во втором случае — от 10 до 90% от напряжения питания. Датчики с цифровым выходом используют протокол ZACWire, о котором мы подробно поговорим чуть ниже.

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

Для датчиков TSic с аналоговым выходом:

$T=Vвых * (Th - Tl) + Tl$

Для датчиков TSic с ратиометрическим выходом:

$T=frac{frac{Vвых}{V^+}- 0.1}{0.8}* (Th - Tl) + Tl$

Для датчиков TSic с цифровым выходом:

$T=frac{DS}{2^{11}}* (Th - Tl) + Tl $

или

$T=frac{DS}{2^{14}}* (Th - Tl) + Tl$

где

  • $T$ — температура, °C
  • $Vвых$ — выходное напряжение датчика, В
  • $V^+$ — напряжение питания, В
  • $DS$ — выходной цифровой сигнал
  • $Th$ — верхняя граница диапазона рабочих температур, °C
    $Th$ = +150°C для TSic 20x и TSic 30x, $Th$ = +60°C для TSic 50xF и TSic 716
  • $Tl$ — нижняя граница диапазона рабочих температур, °C
    $Tl$= -50°C для TSic 20x и TSic 30x, $Th$ = -10°C для TSic 50xF и TSic 716

Примеры сигналов на выходе датчиков TSic приведены в таблице.

Для датчиков TSic 20x / TSic 30x
Измеряемая температура, °C Аналоговый выход Ратиометрический выход Цифровой выход
-50 0.000В 10% V+
(0.5В при V+=5В)
0x000
-10 0.200В 26% V+
(1.3В при V+=5В)
0x199
0 0.250В 30% V+
(1.5В при V+=5В)
0x200
+25 0.375В 40% V+
(2.0В при V+=5В)
0x2FF
+60 0.550В 54% V+
(2.7В при V+=5В)
0x465
+125 0.875В 80% V+
(4.0В при V+=5В)
0x6FE
+150 1.000В 90% V+
(4.5В при V+=5В)
0x7FF
Для датчиков TSic 50xF / TSic 716
  11-бит
(TSic 506F)
14-бит
(TSic 716)
-10 0.000В 10% V+
(0.5В при V+=5В)
0x000  0x0000
0 0.143В 21.4% V+
(1.07В при V+=5В)
0x124  0x0924
+25 0.500В 50% V+
(2.5В при V+=5В)
0x3FF  0x01FF
+60 1.000В 90% V+
(4.5В при V+=5В)
0x7FF  0x3FFF

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

Очевидный минус датчика TSic с цифровым выходом — нестандартный интерфейс, для которого на ваш МК ещё нет готовой библиотеки. Очевидный плюс — этот интерфейс очень простой.

Протокол ZACWire


ZACWire — однопроводной протокол, использующий кодировку, напоминающую Манчестерскую.

Датчик с заранее определенной частотой передаёт данные о температуре — два восьмибитных пакета данных. Каждый из пакетов начинается стартовым битом и заканчивается битом чётности. В зависимости от модели датчика, в каждой посылке либо 11, либо 14 значащих разрядов, первым идет старший бит.

Цифровой датчик температуры TSic: адреса, пароли, явки - 28

Пассивным состоянием лини данных является высокий уровень. Каждый бит посылки TSic начинается со спада сигнала и занимает 125 микросекунд. Состояние линии данных фиксируется на середине этого интервала — если по прошествии 62.5 мксек со спада сигнала на линии высокий уровень, то записываем логическую «1», если низкий, то логический «0». Коэффицент заполнения в первом случае равняется 75%, в втором — 25%.

Цифровой датчик температуры TSic: адреса, пароли, явки - 29

Коммуникационный интерфейс ZACWire не использует отдельного тактового сигнала, поэтому отсчёт тактов производится на стороне микроконтроллера.

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

С другой стороны, для стандартных датчиков TSic значение Tstrobeизвестно заранее
и равно 125 / 2 = 62.5 мксек, поэтому на практике стартовый бит просто детектируют и пропускают.

Цифровой датчик температуры TSic: адреса, пароли, явки - 30

Биты чётности декодируются так же, как и биты данных. В отсутствии внешних помех и небольшой длине соединения (до 2 метров) контроль целостности, как правило, не требуется. Между окончанием первого пакета и вторым стартовым битом на линии установлен высокий уровень.

Чтобы внести окончательную ясность, рассмотрим осциллограмму пакета данных датчика TSic 306.

Цифровой датчик температуры TSic: адреса, пароли, явки - 31

Посылка начинается со стартового бита, далее идут незначащие биты данных, которые всегда равны «0», далее идут старшие биты данных — «011», далее бит чётности, соответственно равный «0». Второй пакет начинается через один период (Tstrobe * 2) и содержит стартовый бит, восемь младших бит данных «00011000» и бит чётности, соответственно равный «0».

Цифровой датчик температуры TSic: адреса, пароли, явки - 32

В результате получаем на выходе 01100011000bin = 792dec и по приведенной выше формуле вычисляем значение температуры.

$T=frac{DS}{2^{11}}* (Th - Tl) + Tl=frac{792}{2^{11}}* (150 - (-50)) + (-50)=27.3°C$

Если говорить о частоте, с которой датчик TSic передаёт такие посылки с данными, то она устанавливается при производстве компонента и не может быть изменена по ходу использования датчика. Для моделей TSic 206, TSic 306, TSic 506 частота равляется 10 Гц, для TSic 716 — 1 Гц. Под заказ доступны датчики с нестандартной частотой измерений — 250, 10, 1 и 0.1 Гц.

Если задача не предполагает опроса датчика с максимально возможной частотой и на микроконтроллере есть свободная линия, то имеет смысл использовать эту линию для питания датчика. Таким образом, каждый раз когда требуется получить данные с датчика, можно подать питание на датчик и ожидать спада на линии данных — стартового бита первого пакета. Между подачей питания на TSic и передачей посылки пройдет менее 85 микросекунд, а после приёма двух пакетов данных питание датчика можно отключить.

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

В порядке эксперимента я подключаю две стандартные модели TSic 306 TO92 и TSic 506 TO92 к отладочной плате EFM32ZG-STK3200. По нажатию на кнопку на датчик подаётся питание, принимается одна посылка с данными о температуре, данные обрабатываются, результат выводится на установленный на плату LCD дисплей, после чего датчик от питания отключается.

Отладочная плата EFM32ZG-STK3200 выпускается компанией Silicon Labs (SiLabs)
для работы с микроконтроллерами EFM32 Zero Gecko.

EFM32 Zero Gecko — младшая серия семейства EFM32. Эти микроконтроллеры построены на базе ядра ARM Cortex-M0+, имеют стандартный набор встроенный периферии и разные интересные модули для снижения энергопотребления контроллера. Мы уже публиковали на хабре подробную статью об особенностях этой платформы и средствах отладки для EFM32 Zero Gecko.

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

Итак, от МК нам понадобятся

  • Три GPIO: подключенный к кнопке PC9 и свободные PC0 и PC1 для линий питания и данных TSic
  • Таймер для тактирования линии данных TSic
  • SPI для работы со встроенным дисплеем. SPI я упоминаю просто для порядка, т.к. вся работа с выводом данных проводится с помощью SiLabs-овской библиотеки glib, содержимое которой мне не очень интересно

На отладочной плате, соответственно, мы используем

  • Микроконтроллер EFM32ZG222F32
  • USB-отладчик SEGGER J-Link USB
  • Механическую кнопку PB1
  • Разъем expansion header, на котором доступны нужные GPIO и земля
  • Дисплей 128x128 пикселей — исключительно симпатичный LCD

Итак, по прерыванию от кнопки подаём на датчик питание, принимаем посылку и отключаем питание. Если при приёме данных возникла ошибка — выдаём соответствующее сообщение, иначе вычисляем температуру в градусах Цельсия и показываем результат на LCD.

void ReceiveTempAndShowIt(void) {
	GPIO_PinOutSet(TSIC_VDD_PORT, TSIC_VDD_PIN);
	int8_t TSic_result = receiveTSicData();
	GPIO_PinOutClear(TSIC_VDD_PORT, TSIC_VDD_PIN);

	if (TSic_result == TSIC_IS_OK) {
		float temperatureCelsius = calculateCelsius(fullTSicTransmission);
		Display_ShowTemperature(temperatureCelsius);
	} else if (TSic_result == TSIC_PARITY_ERROR) {
		Display_ShowParityError();
	} else if (TSic_result == TSIC_TIMING_ERROR) {
		Display_ShowTimingError();
	}
}

Важно!

Здесь пора отметить, что рассмотренный в этой статье код — совершенно не оптимален. То есть совсем-совсем не оптимален. Ниже вы увидите, как фронты и спады сигнала детектируются с помощью while, как временные интервалы отсчитываются без использования прерываний и прочая, прочая.

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

Итак, функция приёма данных receiveTSicData() — это приём двух пакетов данных, вычленение из каждого из них бита чётности и проверка целостности для обоих пакетов.

int8_t receiveTSicData(void) {
	uint16_t firstTSicPacket = 0;
	uint16_t secondTSicPacket = 0;
	bool firstParityBit = 0;
	bool secondParityBit = 0;

	/* Time critical section [all interrupts disable]:
	 * Receive two data packets from TSic sensor
	 */
	INT_Disable();
	if (readTSicPacket(1) == PACKAGE_READING_OK) {
		firstTSicPacket = currentTSicPacket;
	} else {
		INT_Enable();
		return TSIC_TIMING_ERROR;
	}
	if (readTSicPacket(0) == PACKAGE_READING_OK) {
		secondTSicPacket = currentTSicPacket;
	} else {
		INT_Enable();
		return TSIC_TIMING_ERROR;
	}
	INT_Enable();

	/* Decode received packets */
	/* Get parity bit from first packet */
	firstParityBit = firstTSicPacket & 0x01;
	/* Get 3 data bits from first packet */
	firstTSicPacket = firstTSicPacket & 0x0007;
	/* Delete first parity bit */
	firstTSicPacket >>= 1;
	/* Get parity bit from second packet */
	secondParityBit = secondTSicPacket & 0x01;
	/* Delete second parity bit */
	secondTSicPacket >>= 1;

	/* Check parity errors and assemble full temperature transmission from TSic */
	if (checkParity(firstTSicPacket, firstParityBit) == PARITY_OK
			&& checkParity(secondTSicPacket, secondParityBit) == PARITY_OK) {
		fullTSicTransmission = (firstTSicPacket << 8) + secondTSicPacket;
		return TSIC_IS_OK;
	} else {
		return TSIC_PARITY_ERROR;
	}
}

Функция readTSicPacket(), возвращающая currentTSicPacket, может выглядеть следующим образом.

int8_t readTSicPacket(bool isTheFirstPacket) {
	currentTSicPacket = 0;

	/* Wait until start bit occurs, return error if it takes too long
	 */
	if (isTheFirstPacket) {
		/* If we are waiting after powering up the sensor */
		myTIMER_Start(PRESCALER_1024);
		while (TSIC_DATA_HIGH) {
			if (TIMER_COUNTER >= WAITING90MS_TICKS) {
				return NO_SIGNAL_OCCURS;
			}
		}
		myTIMER_Stop();
	} else {
		/* If we are waiting just for time between first and second packet */
		myTIMER_Start(NO_PRESCALER);
		while (TSIC_DATA_HIGH) {
			if (TIMER_COUNTER >= TSTROBE_TICKS * 4) {
				return NO_SECOND_PACKAGE;
			}
		}
		myTIMER_Stop();
	}

	/* Check if start bit has occurred:
	 *
	 * As Tstrobe = 125 us / 2 = 62.5 us,  we need to check if the signal is
	 * low for about Tstrobe time and then goes high for about Tstrobe time.
	 */
	myTIMER_Start(NO_PRESCALER);
	while (TSIC_DATA_LOW) {
		if (TIMER_COUNTER >= TSTROBE_TICKS * 1,1) {
			return START_BIT_ERROR;
		}
	}
	while (TSIC_DATA_HIGH) {
		if (TIMER_COUNTER >= TSTROBE_TICKS * 2,2) {
			return START_BIT_ERROR;
		}
	}
	if (TIMER_COUNTER <= TSTROBE_TICKS * 1,8) {
		return START_BIT_ERROR;
	}
	myTIMER_Stop();

	/*
	 * Receive 8 data bits + 1 parity bit
	 */
	for (uint8_t i = 0; i <= 8; i++) {

		/* Wait for exact Tstrobe time to check the line state */
		myTIMER_Start(NO_PRESCALER);
		while (TIMER_COUNTER < TSTROBE_TICKS) {
		}
		myTIMER_Stop();

		/* Read bit */
		currentTSicPacket <<= 1;
		if (TSIC_DATA_HIGH) {
			currentTSicPacket |= 1;
		}

		/* Wait until the end of one-bit-timeframe.
		 */
		if (TSIC_DATA_LOW) {
			myTIMER_Start(NO_PRESCALER);
			while (TSIC_DATA_LOW) {
				if (TIMER_COUNTER >= TSTROBE_TICKS * 0,6) {
					return PACKAGE_TIMING_ERROR;
				}
			}
			myTIMER_Stop();
		}
		/* Last bit (parity bit) doesn't end up with falling edge so we should
		 * wait for the next falling edge just for data bits.
		 */
		if (i != 8) {
			myTIMER_Start(NO_PRESCALER);
			while (TSIC_DATA_HIGH) {
				if (TIMER_COUNTER >= TSTROBE_TICKS * 1,1) {
					return PACKAGE_TIMING_ERROR;
				}
			}
			myTIMER_Stop();
		}
	}

	return PACKAGE_READING_OK;
}

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

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

Функция проверки целостности пакета TSic

int8_t checkParity(uint16_t package, bool parity) {
	uint8_t parityCounter = 0;

	for (uint8_t i = 0; i <= 7; i++) {
		if (package & (1 << i)) {
			parityCounter++;
		}
	}
	if (parityCounter % 2 == parity) {
		return PARITY_OK;
	} else {
		return PARITY_ERROR;
	}
}
Функция расчета температуры в градусах Цльсия для датиков TSic 206, TSic 306 и TSic 506

float calculateCelsius(uint16_t transmissionData) {
	/* TSic20x / 30x sensors: LT = -50, HT = 150, Digital output 11 bit */
	//float celsius = ((float) transmissionData * 200 / 2047) - 50;

	/* TSic50x sensors: LT = -10, HT = 60, Digital output 11 bit */
	float celsius = ((float) transmissionData * 70 / 2047) - 10;

	return celsius;
}

Код целиком доступен по ссылке.

Ссылки


Заключение


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

Автор: ЭФО

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js