STM32 и гирлянда датчиков температуры TMP05

b4-0

Хоть и думал это как блог по hardware-статьям в основном сделать, первая заметка будет таки о программировании.
Собственно, для одного проекта необходимо было простой блок, который крепиться на дин-рейку, имеет на борту простой RS-485, отзывается и настраивается по Modbus, а так же сам по себе опрашивает заданное количество датчиков температуры TMP05, включенных в «daisy-channel» режиме. О последних и пойдет речь.

Хоть я и не программист, скорее пограмист-железячник, но таки выставлю на показ и критику свою реализацию библиотеки для работы с этими датчиками. :)

Итак, смотрим в даташит TMP05, находим, что их можно включать последовательно, как гирлянда:

b4-1-dch

Для включения этого режима надо пин FUNC подтянуть к питанию, а вход и выход датчиков соединять последовательно, сколько душе угодно.(пробовал до 48 шт. на проводах ~15см у каждого датчика — работает отлично!)

Вот пример соединения для 2 шт. и полученных сигналов:

B4-2 Dch.PNG

Ага, нам надо значит специальный Start-Impulse дать на вход первого датчика в гирлянде и потом уже по прерываниям считать чего же мы там намерили (с космоса). Смотрим как необходимо его генерировать:

b4-3-start-impulse

И последнее, что понадобиться, так это как потом высчитать полученное время импульсов в температуру. Формула не замысловатая и что удобно — не обязательно привязываться к конкретным меры времени, можно условно считать по тикам таймера, нам важно именно отношение Th \ Tl.

B4-4 temp.PNG

И пока разбирался с кодом, нашел ошибку в даташите. Вообще не критичную, работать должно и так, но попробуйте найти различие в формуле выше и кодом ниже. ;)

B4-5 temp err.PNG

Подключение датчиков реализовано крайне просто, но в тоже время с защитой линии и питания. Приведен кусок схемы c МК STM32F103 (для других линеек F* серий возможно потребуется значительные переделывания захватывающей импульсы части кода), напрямую относящейся к подключению линии данных для датчиков.

b4-6-sch

На схеме R21, R22 — RC0805JR-0710RL, а FV2 — Супрессор CD143A-SR3.3. Из особенностей подключения:

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

А так же топорная схема самих датчиков, установленных на небольшой плате с клеммами для оперативного монтирования\замены\подключения:

Это слайд-шоу требует JavaScript.

На схеме С1 — GRM188R71C104KA01D, а в качестве XP1 — ECH381R-04P

Подключаются датчики соответственно в порядке «выход первого датчика\МК» ко «входу следующего датчика\МК» и так до необходимого количества.

В библиотеке реализована поддержка до 50 шт. датчиков (можно и больше, если есть свободная RAM на контроллере или если выкинуть сглаживание), так же сделана возможность включения и регулирования окна скользящего сглаживания. Библиотека внутри считает температуру и наружу выдает в формате float, если была ошибка чтения, то выдается прошлое значение. Так же обозначены места, где можно вставить обработку флагов ошибок или мигание статусными светодиодами.

Чтение последнего значения и обновление температуры с датчиков можно выполнять в разных потоках, библиотека использовалась в прошивке с использованием RTOS от Keil.

Функции, реализованные в библиотеке:

// Инициализация библиотеки, пинов, таймера
void TMP05_Init(void);
// Чтение температуры со всех датчиков и обновление в окне сглаживания
void TMP05_Read(void);
// Получение температуры с конкретного датчика после сглаживания
float TMP05_GetTempreture(uint16_t num);

// Настройки библиотеки, которые можно менять динамически во время работы

// Установить кол-во датчиков в линии, возвращает 1 - если успешно
uint8_t TMP05_SetNumReadSensors(uint8_t num);
// Установить величину окна сглаживания, возвращает 1 - если успешно
uint8_t TMP05_SetWidthSlidingWindow(uint8_t width);
// Вернуть кол-во датчиков в линии
uint8_t TMP05_GetNumReadSensors(void);
// Вернуть величину окна сглаживания
uint8_t TMP05_GetWidthSlidingWindow(void);

Так же следует учитывать при применении библиотеки, что при вызове функции TMP05_Read(void) внутри нее есть задержка, равная TMP05_CYCLETIME * TMP05_NumReadSensors, т.е. если у Вас 10 датчиков, то 10 * 0,15сек = в функции программа прождет аж 1,5 секунды ! Для реализации прошивки с использованием RTOS это абсолютно не страшно и я выделил один поток просто на обновление температуры в цикле. В противном случае эту функцию придется переделывать…

Перед использованием в своём проекте также необходимо зайти в TMP05.h и проверить стандартные настройки библиотеки пинов, таймера и параметров:

// К каким пинам подключены вход\выход
#define TMP05_DATAOUT_PIN GPIO_Pin_0
#define TMP05_DATAIN_PIN GPIO_Pin_1
#define TMP05_DATA_PORT GPIOA

// настройки хардварного таймера
// необходимо смотреть по даташиту,
// что на TMP05_DATAIN_PIN пине есть вход этого таймера!
#define TMP05_CAP_TIM TIM2
#define TMP05_CAP_CHANNEL TIM_Channel_2
#define TMP05_CAP_IRQ TIM2_IRQn
#define TMP05_CAP_IRQ_H TIM2_IRQHandler
#define TMP05_CAP_RCC RCC_APB1Periph_TIM2

// как минимум нам надо уметь считать десятые доли миллисекунд,
// настраиваем таймер на 0.1ms ! --- (SystemClock(kHz)/10) - 1
#define TMP05_CAP_PRESCALER (3200 - 1)

// время максимального цикла для одного датчика (ms) - из даташита
// это время таймаута, для определения обрыва или замыкания в линии
#define TMP05_CYCLETIME 150

// сколько всего максимум включено датчиков по daisy-channel ?
// если есть много памяти - можно и больше ставить :)
#define TMP05_N 50
// это значение по-умолчанию кол-ва датчиков опрашиваемых в линии
#define TMP05_N_READ 10 

// это значение по-умолчанию окна усреднения
#define TMP05_RAW_APPR 5

Ну и для использования библиотеки в своей программе требуется минимальные усилия:

#include "TMP05.h"

float temp = 0.0;

int main(void)
{
// .... код инициализации МК

TMP05_Init(); //инициализируем библиотеку
TMP05_SetNumReadSensors(2); // настраиваем
TMP05_SetWidthSlidingWindow(2);

for(;;)
{
 TMP05_Read(); // выполняем цикл чтения, во время которого функция НЕ отдаст управление!!
temp = TMP05_GetTempreture(0); // получаем температуру датчика 0 (первого в линии)
}
}

Если будут предложения по оптимизации или хотите сообщить о найденной ошибке — пишите, буду рад!

Спасибо, что прочитали ;)

Ах да, ссылка для скачивания библиотеки — TMP05 Library (по лицензии WTFPL :D)

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s