Хоть и думал это как блог по hardware-статьям в основном сделать, первая заметка будет таки о программировании.
Собственно, для одного проекта необходимо было простой блок, который крепиться на дин-рейку, имеет на борту простой RS-485, отзывается и настраивается по Modbus, а так же сам по себе опрашивает заданное количество датчиков температуры TMP05, включенных в «daisy-chain» режиме. О последних и пойдет речь.
Хоть я и не программист, скорее пограмист-железячник, но таки выставлю на показ и критику свою реализацию библиотеки для работы с этими датчиками. :)
Итак, смотрим в даташит TMP05, находим, что их можно включать последовательно, как гирлянда:
Для включения этого режима надо пин FUNC подтянуть к питанию, а вход и выход датчиков соединять последовательно, сколько душе угодно.(пробовал до 48 шт. на проводах ~15см у каждого датчика — работает отлично!)
Вот пример соединения для 2 шт. и полученных сигналов:
Ага, нам надо значит специальный Start-Impulse дать на вход первого датчика в гирлянде и потом уже по прерываниям считать чего же мы там намерили (с космоса). Смотрим как необходимо его генерировать:
И последнее, что понадобиться, так это как потом высчитать полученное время импульсов в температуру. Формула не замысловатая и что удобно — не обязательно привязываться к конкретным меры времени, можно условно считать по тикам таймера, нам важно именно отношение Th \ Tl.
И пока разбирался с кодом, нашел ошибку в даташите. Вообще не критичную, работать должно и так, но попробуйте найти различие в формуле выше и кодом ниже. ;)
Подключение датчиков реализовано крайне просто, но в тоже время с защитой линии и питания. Приведен кусок схемы c МК STM32F103 (для других линеек F* серий возможно потребуется значительные переделывания захватывающей импульсы части кода), напрямую относящейся к подключению линии данных для датчиков.
На схеме R21, R22 — RC0805JR-0710RL, а FV2 — Супрессор CD143A-SR3.3. Из особенностей подключения:
- выход DT_OUT можно подключать на любой пин, он не требует специальной периферии;
- вход DT_IN нужно подключать обязательно на вход таймера, с поддержкой режима PWM захвата сигнала.
А так же топорная схема самих датчиков, установленных на небольшой плате с клеммами для оперативного монтирования\замены\подключения:
На схеме С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-chain? // если есть много памяти - можно и больше ставить :) #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)