rss
Навигация
ИнструментыЯмаПолезные ссылкиЗачем мне блог?Рейтинг контентаКодекс админаФотогалереяi-payrss
Последние записи
Смонтировал видюху, моменты из жизни 2013-15На уазике до ск. Верблюд по Торгашинскому хребтуBreaks волна #9 осенний funkК нам на дачу пришел медведьСтарая бомба! Крутой рифмоплет
Каменты [еще]
2017-05-17 11:25:31 [articles] Владимир:
2016-12-20 17:49:41 [articles] Виталик:
2016-12-01 23:34:25 [news] Meteor:
2016-11-11 03:35:47 [articles] Tata10:
2016-07-27 14:28:19 [articles] Сергей:
2016-05-17 09:56:26 [articles] юра:
2016-04-29 18:03:48 [articles] agatsky.dn:
Теги
Друзья
Блог малова Лучшие стихи зая =) Мед в Красноярске Daniil V. Savenkoff Blog | То, что мне когда-то пригодилось... Велкам в друзья!

Настройка термо станции на FreeBSD

Августа
2011 года
30
Теги: freebsd, скрипты, паяльник, термоклиент,
Раздел: zgbox.ru -> Статьи -> TermoService aka TermoClient -> Настройка термо станции на FreeBSD
Просмотров: 3328
Статья о том как спаять схему на COM порт и подключить термодатчик DS18B20 к ПК на FreeBSD. А также орагизовать хранение данных в MySQL базе.

Эта статья является составной частью проекта TermoClient



Итак, для начала нам нужно собрать эту схему:

image


Почему эту? ну вообще в инете не мало схем для термодатчиков DS1820. Я собирал уже 4, и остановился на этой поскольку в моем опыте она оказалась самой надежной, так что собираем ее! =)

Для тех кто мало знаком с радиотехникой, скажу что слева на схеме - RS232 это COM порт, а справа датчик температуры, Zender Diode - это обычные стабилитроны, Shottkie Diode - собсно диоды шотки, кондинсатор на схеме указан тантловый, но в полне подойдет и обычный электролит (у мня на нем собрано). В общем берем паяльник, канифоль, припой, прямые руки и вперед... =)

А вот тут описание самого термодатчика:

image

Кстати о датчиках, можно использовать и DS1820 и DS18S20, но я рекомендую DS18B20 потому что он умеет показывать десятые доли градуса, а два первых - только по 0.5 градуса...

Настройка digitemp


После того как схема правильно собрана, и датчик к ней подключен, можно приступать к настройке digitemp (программа для работы с датчиками)
оффсайт: www.digitemp.com

Наши действия:
1 скачать digitemp
2 распаковать
3 откомпилить
4 найти, проинициализировать датчики
5 сохранить данные датчиков и настроек в конфиг
6 юзать конфиг и получать нужные данные
7 написать скрипт который будет пихать температуру в mysql

смотрим на оффсайте последнюю версию и качаем
#mkdir /usr/local/etc/digitemp
#cd /usr/local/etc/digitemp
#fetch http://www.digitemp.com/software/linux/digitemp-3.6.0.tar.gz
распаковываем и компилим:
#tar -xzvf digitemp-3.6.0.tar.gz
#cd digitemp-3.6.0
#gmake ds9097
после удачного компилинга выполняем
#./digitemp_DS9097
смотрим показывает ли нам digitemp свой мануал, если да то все ок.

По сути для работы с датчиками кроме этого откомпилиного файла больше ничего не нужно и все остальное можно удалить. Кстати где-то в исходниках еще лежит откомпилиный exe для windows =)

для удобства скопипуем этот файл с новым именем dt в директорию в которой будем все хранить и настраивать
#cp digitemp_DS9097 /usr/local/digitemp/dt
#cd /usr/local/etc/digitemp
пробуем проинициализировать датчики, для этого нам нужно запустить
digitemp с параметрами -q -w и указать com порт в который воткнута схема.
В freebsd com порты это /dev/cuad0, /dev/cuad1
запускаем:
#./dt -q -w -s /dev/cuad0
28050627020000D0 : DS18B20 Temperature Sensor
отсюда видно что digitemp нашел 1 датчик 28050627020000D0 : DS18B20 Temperature Sensor
если он ничего не находит значить криво собрана схема или указант не тот com порт
теперь сохраняем параметры в конфиг, для этого выполняем
#./dt -q -i -s /dev/cuad0
28050627020000D0 : DS18B20 Temperature Sensor
ROM #0 : 28050627020000D0
после чего digitemp в своем каталоге создаcт файл .digitemprc в котором лежат данные о порте, датчиках и формате вывода

Теперь чтоб посмотреть температуру достаточно выполнить
#./dt -a -q -c /usr/local/etc/digitemp/.digitemprc
формат вывода информации можно задать как в .digitemprc LOG_FORMAT
так и через параметры запуска, например -o%.1C (покажет только температуру по цельсию)

Создаем таблицы и процедуру добавления в mysql


Подразумевается что mysql (версии не ниже 5 или любой но чтоб поддерживал встренные процедуры) уже установлен и настроен, также создана произволная база и пользователь для доступа к ней. Например база у нас с именем zgdb, юзер:root пароль:123

Создаем таблицы
ds_sensors - для хранения текущих показаний датчиков
ds_temps - для хранения истории изменений температуры, например для графиков

и процедуру
update_temp - для корректного добавления и обновления данных

Суть процедуры в том чтоб проверить показание датчика чтоб температура была в пределах -60..+60, обновить показание датчика в таблице ds_sensors и добавить запись в хранилище статистики температур в таблицу ds_temps но не просто добавить а добавлять только раз в 5 мин, и если там уже добавлено значние за последние 5 мин то процедура просто обновит показание счетчика в ds_sensors

запросы на все это дело:
CREATE TABLE `ds_sensors` (
`id` smallint(6) NOT NULL AUTO_INCREMENT,
`curtemp` float NOT NULL DEFAULT '0',
`lastupdate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`place` varchar(100) DEFAULT NULL,
`model` varchar(30) DEFAULT NULL,
`top` tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=cp1251;

CREATE TABLE `ds_temps` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`sensor_id` smallint(6) NOT NULL DEFAULT '0',
`num` smallint(6) NOT NULL DEFAULT '0',
`datetime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`temp` float NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=cp1251;

CREATE PROCEDURE update_temp (IN ctemp VARCHAR(10), IN sens_id INT)
begin
set @lnum=(select max(num) from ds_temps where (date(datetime)=curdate()) and (sensor_id=sens_id));
set @cnum=(select truncate(((time_to_sec(now())/300)+1), 0));
IF @lnum = @cnum THEN
update ds_sensors set lastupdate=now(), curtemp=ctemp where id=sens_id;
else begin
if (ctemp<60) and (ctemp>-60) then insert into ds_temps (temp,datetime,num,sensor_id) values (ctemp, now(), (select truncate(((time_to_sec(now())/300)+1), 0)),sens_id);
end if;
update ds_sensors set lastupdate=now(), curtemp=ctemp where id=sens_id;
end;
end if;
end


после создания таблиц и процедуры нужно добавить в таблицу ds_sensors столько датчиков сколько у нас задумано и реализовано, ну например 3 штуки, соответственно добавляем значения в таблицу через какойнибудь БД админ софт, (я использую navicat, кто-то phpmyadmin... в общем кому как) или просто выполняем запросы залогинившись в базу zgdb
INSERT INTO ds_sensors (model, place) values ('DS18B20','home');
INSERT INTO ds_sensors (model, place) values ('DS18B20','street');
INSERT INTO ds_sensors (model, place) values ('DS18B20','server');
логинимся например так:
#mysql -uroot -p zgdb
если все ок, то переходим к следующему этапу

Скрипт добавления данных в базу


создаем скрипт такого содержания:
#!/bin/sh

db_host=localhost
db_pass=123
db_user=root
db_name=zgdb

digitemp_bin=/usr/local/etc/digitemp/dt
digitemp_conf=/usr/local/etc/digitemp/.digitemprc
digitemp_format=%.1C
digitemp_sensor=0
db_sensor_id=1

temp=`$digitemp_bin -t $digitemp_sensor -q -o$digitemp_format -c $digitemp_conf`
sql="call update_temp($temp,$db_sensor_id);"
/bin/echo $sql | /usr/local/bin/mysql -h$db_host -u$db_user $db_name -p$db_pass
назначение переменных в скрипте
digitemp_sensor=0 - какой порядковый номер датчика опрашивать digitemp'у
db_sensor_id=1=1 - с каким id запихивать показания нашего датчика в базу уникальное значения для каждого датчика)
Ну по остальным вроде все интуитивно понятно

дадим скрипту имя например digi_temp2db
сохраним и сделаем исполняемым
#chmod 777 /usr/local/etc/digitemp/digi_temp2db
Попробуем запустить и проверить как он сработал и записал данные в mysql
Если все прошло успешно то танцуем!

Если у нас несколько датчиков, то можно создать по скрипту для каждого датчика, есессно указав для каждого свои параметры digitemp_sensor и db_sensor_id но все сразу их нельзя пихать в cron. Нужно сделать один скрипт который бы выполнял скрипты датчиков по очереди. Это связано с тем что если несколько копий digitemp одновременно ломануться на com порт, то успешно сработает только первая, а остальные повиснут т.к. не смогут получить доступ к com порту. Но можно и все датчики обработать одним скриптом, как это сделать я описывать небуд ибо лень =)

Теперь осталось только добавить наш скрипт в cron на каждую минуту:
#echo "*/1 * * * * root /usr/local/etc/digitemp/digi_temp2db" >> /etc/crontab

вот и все.
Комментарии к записи:
Дмитрий 2011-10-05 16:15:35 [ответить]
Добрый день!Очень понравилась ваша разработка с датчиками температуры. Все работает. Есть один вопрос - у вас есть процедура - update_temp, а вот процедуры restore_temp нет :-(. Можно текст в студию?
Спасибо.
=ZG= 2011-10-05 16:53:27 [ответить]
спасибо =), процедуры выложил в спойлере на странице программы digi2db ( http://zgbox.ru/projects/digi2db.html )
Дмитрий 2011-10-05 19:58:09 [ответить]
Скажите пожалуйста, при каких условиях данные НЕ будут отправляться? Попробовал выдернуть сетевой шнур из компа с датчиками и воткнул обратно через 15 мин. Да, данные пишутся в sensor1.ns, после восстановления коннекта в логе видно:
05.10.2011 15:46:03 Sent failed, server not avialabe
05.10.2011 15:46:33 Sending SavedTemps (Sensor1.ns)
05.10.2011 15:46:33 [2011-10-05 15:40:05,1,34.0]
05.10.2011 15:46:33 SQL (restore): call restore_temp(34.0,1,'2011-10-05 15:40:05');
05.10.2011 15:46:33 SQL Error #2003 - Can't connect to MySQL server on '10.0.4.4' (10065)
05.10.2011 15:46:33 Sent failed, server not avialabe
05.10.2011 15:47:03 MYSQL connected
05.10.2011 15:47:08 Sent successfully!
05.10.2011 15:47:35 Sent successfully!

Но данных в БД нет... Может подскажите, в чем проблема может быть?

Спасибо
Дмитрий 2011-10-05 20:00:56 [ответить]
Т.е. следующая запись идет по времени в 15:47:08, а записи 15:40:05 нету :-(
=ZG= 2011-10-05 20:35:31 [ответить]
нашел ошибку в процедуре, дело в том что у меня процедуры привязаны к учетным записям и к датчикам, там в той процедуре что выложил была привязка к датчику с id=8, я ее убрал - процедуру обновил, попробуйте обновить процедуру, должно правильно заработать.
=ZG= 2011-10-05 20:49:34 [ответить]
данные не отправляются если не выполнился sql запрос в базу, а там уже не важно из за чего. Или прав нет,или таблиц, или конект пропал, итд итп.
Даниил 2013-01-09 18:40:07 [ответить]
А если не сложно - подскажите по схеме, какие именно диоды Шотки нужны и в каком корпусе? А то как то стремно в магазине объяснять не зная)) Заранее спасибо!
=ZG= IP:95.170.187.9 2013-01-09 19:06:32 [ответить]
Да по сути без разницы, главно чтоб выпрямительные диоды. Я собирал на 1N4007 и на 1N4005. Пришел в магаз и сказал, дайте мне простые диоды чтоб в одну сторону пропускали а в другую нет =)

http://images.deal.by/4981164_w640_h640_diody.jpg
Даниил 2013-02-14 22:03:30 [ответить]
Денис, вот вариант процедуры для MySQL 5.5 (ну у меня дома такой. Твой вариант процедуры не пошел):
DELIMITER $$
CREATE PROCEDURE update_temp (IN ctemp VARCHAR(10), IN sens_id INT)
begin
set @lnum=(select max(num) from ds_temps where (date(datetime)=curdate()) and (sensor_id=sens_id));
set @cnum=(select truncate(((time_to_sec(now())/300)+1), 0));
IF @lnum = @cnum THEN
update ds_sensors set lastupdate=now(), curtemp=ctemp where id=sens_id;
else begin
if (ctemp-60) then insert into ds_temps (temp,datetime,num,sensor_id) values (ctemp, now(), (select truncate(((time_to_sec(now())/300)+1), 0)),sens_id);
end if;
update ds_sensors set lastupdate=now(), curtemp=ctemp where id=sens_id;
end;
end if;
END$$
DELIMITER ;

Добавление комментария

Ваше имя: (Антиспам) Какой сейчас год?
Ваш комментариий: