Обсуждение на http://www.forumnov.ru/viewtopic.php?f=29&t=1289
Собрал конструкцию, вот что получилось:
Фотогалерея
Остальные фотографии на Я.Фотках |
Некоторые замечания по схеме:
- Не все вентиляторы нормально работают с этой схемой на маленьких оборотах, хотя они же нормально работают с регулятором на МВ. Причина в пульсации ШИМ регулятора. Лечение – установить конденсатор параллельно вентилятору. Я поставил 47mF x 16V, хотя, на мой взгляд, лучше 100 – 220 mF (Не влезли на готовую плату).
- Начинают греться транзисторы на низких оборотах. Очевидно «затянутые» фронты (осциллографом не смотрел). Лечение без переделки платы придумать не смог, поэтому прикрутил к ним небольшой радиатор (один на все через слюдяную прокладку). Если буду делать еще одну плату, поставлю на выход полевые транзисторы, надо только продумать цепи затвора.
- И еще одно, для себя. На фото видно, что на плату запаяны стабилитроны VD3, VD4 на 4,7V – так делать не надо! По спецификации USB напряжение на линиях Data + и – 3,3V, поэтому надо ставить стабилитроны на 3,3 – 3,6V, иначе в них пропадает всякий смысл.
При прошивке МК фьюзы поставил так:
Протокол обмена:
работа с собакой == 0x01
0x01 0x01 nn - установка собаки на время nn секунд
0x01 0x02 xx - что делает собака при сработке
-- 0x01 0x02 0x00 - собака при сработке ничего не делает - только пищит - отладка
-- 0x01 0x02 0x01 - собака при сработке делает "reset"
-- 0x01 0x02 0x02 - собака при сработке делает "power off" и "power on"
0x01 0x03 - обнуление собаки (т.е. периодически обнуляем, иначе сработает)
0x01 0x04 - сброс предыдущего срабатывания собаки (с удалением этой инфо из еепром)
0x01 0x05 xx - установка звука собаки каждую 1сек.
-- 0x01 0x05 0x00 - установка звука собаки каждую 1сек. выключен
-- 0x01 0x05 0x01 - установка звука собаки каждую 1сек. включен
0x01 0x06 xx - установка моргания светодиода собаки каждую 1сек.
-- 0x01 0x06 0x00 - выключен
-- 0x01 0x06 0x01 - включен
работа с фанами = 0x02
0x02 0x01 xx xx xx - работа с фанами - значения мощности на вентиляторах
0x02 0x02 xx xx xx - работа с фанами - значения порога мощности на вентиляторах, если меньше =0
0x02 0x03 xx - работа с фанами - значения шага мощности в сек при плавном старте
0x02 0x04 - работа с фанами - сохранить значения в памяти
работа с датчиками температуры = 0x03
0x03 0x01 xx - время (0.256мс) повторного измерения температуры, т.е. макс = 65сек если 0 - то одноразовое измерение
0x03 0x02 xx - звук при опросе 1/0
0x03 0x03 - сохранить значения (времени) в памяти
работа с бесперебойником по УАРТ = 0x04
0x04 0x01 xx - время (0.256мс) повторного опроса упса. если 0 - то одноразовый опрос
0x04 0x02 xx - звук при опросе 1/0
0x55 xx - запись текущих настроек в еепром
0xf4 xx - led при опросе usb 1/0
0xf5 xx - звук при опросе usb 1/0
0xf6 xx - отладочный сигнал на "reset" 1/0
0xf7 xx - отладочный сигнал на "power" 1/0
0xf8 xx - отладочный сигнал на led1 1/0
0xf9 xx - отладочный сигнал на led2 1/0
0xfa xx - отладочная установка и запись "предыдущего срабатывания собаки"
Управляющий скрипт.
Вот скрипт, который управляет скоростью вентиляторов:
#! /usr/bin/php
#<?php
/****************************************************************************************/
/* Настройки */
/****************************************************************************************/
$disk_fan_2 = array("hda","hdd"); // Список дисков за Fan 2
$disk_fan_3 = array("sda"); // Список дисков за Fan 3
$temperature_min = 30; // Минимальная температура дисков
$temperature_max = 35; // Максимальная температура дисков
$host_hddtemp = "127.0.0.1"; // IP-адрес, по которому запрашивать hddtemp.
$port_hddtemp = "7634"; // Порт, на котором отвечает hddtemp.
/****************************************************************************************/
/* Получаем температуру HDD */
/****************************************************************************************/
$hddtemp = explode("|",get_URL_by_socket ($host_hddtemp,$port_hddtemp,""));
# $hddtemp[1] - /dev/hdd
# $hddtemp[2] - ST380011A Тип HDD
# $hddtemp[3] - 26 Температура HDD
# $hddtemp[4] - C Единици измерения температуры
# Следующий диск +5
/****************************************************************************************/
/* Получаем текущие параметры Fan'ов */
/****************************************************************************************/
unset($wd);
unset($watchdog);
exec("sudo hidtool read",$wd);
$watchdog[0] = explode(" ",$wd[0]);
$speed_fan_1 = hexdec($watchdog[0][3]); // Текущая скорость Fan 1
$speed_fan_2 = hexdec($watchdog[0][4]); // Текущая скорость Fan 2
$speed_fan_3 = hexdec($watchdog[0][5]); // Текущая скорость Fan 3
$speed_fan_1_min = hexdec($watchdog[0][6]); // Минимальная скорость Fan 1
$speed_fan_2_min = hexdec($watchdog[0][7]); // Минимальная скорость Fan 2
$speed_fan_3_min = hexdec($watchdog[0][8]); // Минимальная скорость Fan 3
$acc_fan = hexdec($watchdog[0][9]); // Скорость разгона в сек.
/****************************************************************************************/
/* Fan 1 */
/****************************************************************************************/
# Пока не подключен.
/****************************************************************************************/
/* Fan 2 */
/****************************************************************************************/
$temperature = 0;
for ($disk = 1; $disk < count($hddtemp); $disk = $disk + 5){ // Перебор дисков, которые "видит" hddtemp
for ($num = 0; $num < count($disk_fan_2); $num++){ // Перебор списка дисков, за Fan 2
#echo "\n\$hddtemp[".$disk."] = ".$hddtemp[$disk]." ; \$disk_fan_2[".$num."] = "."/dev/".$disk_fan_2[$num]."\n";
if ($hddtemp[$disk] == "/dev/".$disk_fan_2[$num] and $temperature < $hddtemp[$disk + 2]){
#echo "Совпадение!\n";
$temperature = $hddtemp[$disk + 2]; // Сохраняем максимальную температуру диска, за Fan 2
}
}
}
if ($temperature < $temperature_min) {
$speed_fan_2 = $speed_fan_2 - 5;
if ($speed_fan_2 < 1){$speed_fan_2 = 0;}
}
if ($temperature > $temperature_max) {
$speed_fan_2 = $speed_fan_2 + 5;
if ($speed_fan_2 < $speed_fan_2_min){$speed_fan_2 = $speed_fan_2_min + 1;}
if ($speed_fan_2 > 255){$speed_fan_2 = 255;}
}
/****************************************************************************************/
/* Fan 3 */
/****************************************************************************************/
$temperature = 0;
for ($disk = 1; $disk < count($hddtemp); $disk = $disk + 5){ // Перебор дисков, которые "видит" hddtemp
for ($num = 0; $num < count($disk_fan_3); $num++){ // Перебор списка дисков, за Fan 3
if ($hddtemp[$disk] == "/dev/".$disk_fan_3[$num] and $temperature < $hddtemp[$disk + 2]){
$temperature = $hddtemp[$disk + 2]; // Сохраняем максимальную температуру диска, за Fan 3
}
}
}
if ($temperature < $temperature_min) {
$speed_fan_3 = $speed_fan_3 - 5;
if ($speed_fan_3 < 1){$speed_fan_3 = 0;}
}
if ($temperature > $temperature_max) {
$speed_fan_3 = $speed_fan_3 + 5;
if ($speed_fan_3 < $speed_fan_3_min){$speed_fan_3 = $speed_fan_3_min + 1;}
if ($speed_fan_3 > 255){$speed_fan_3 = 255;}
}
/****************************************************************************************/
/* Запись вычисленных значений в Fan'ы */
/****************************************************************************************/
#echo "\n\nhidtool write 0x02 0x01 ".$speed_fan_1." ".$speed_fan_2." ".$speed_fan_3."\n\n";
exec("sudo hidtool write 0x02 0x01 ".$speed_fan_1." ".$speed_fan_2." ".$speed_fan_3."");
/****************************************************************************************/
/* Функции */
/****************************************************************************************/
function get_URL_by_socket ($host,$port,$path) {
//Получает URL $path с хоста $host через сокеты.
# Добавить проверку - Запущен-ли hddtemp. Иначе ошибка:
#
Warning: fsockopen() [function.fsockopen]: unable to connect to
127.0.0.1:7634 (Connection refused) in /var/www/watchdog/parser.php on
line 10
# Не могу получить данные с url http://127.0.0.1/
$fp = fsockopen($host,$port,$errno,$errstr);
if (!$fp) {
echo "ERROR: $errno - $errstr\n";
die ("Не могу получить данные с url http://$host/$path\n");
}
else {
$out = "GET $path HTTP/1.0\r\n";
$out .= "Accept: image/gif, application/xhtml+xml, */*\r\n";
$out .= "Accept-Language: ru\r\n";
$out .= "Host: $host\r\n";
//Имитируем браузер Opera Mini:
$out .= "User-Agent: Opera/8.01 (J2ME/MIDP; "."Opera Mini/2.0.4509/1716; ru; U; ssr)\r\n";
$out .= "Cache-Control: no-cache\r\n"; //Не кэшировать
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
$headers = "";
while ($str = trim(fgets($fp)))
$headers .= "$str\n";
/* $body = "";
while (!feof($fp))
$body .= fgets($fp);
echo "\$body = ".$body."<br>";
fclose($fp);
}
return $body; */
fclose($fp);
}
return $headers;
}
#?>
Скрипт запускается по крону с интервалом 5 минут. Месяц его работы не выявил каких-либо недочетов или багов.
Добавлено 7.07.2012
Прошло полтора года, девайс работает без проблемм в режиме 24х7...
Дублирую сдесь файлы с форума www.forumnov.ru :
- https://www.dropbox.com/s/rtsx5c3bt2v8l7l/20100210_watchdog.zip - авторский вариант печатной платы
- https://www.dropbox.com/s/rgrtgztqy4p9ifg/watchdog%20v3.rar - мой вариант печатной платы
- https://www.dropbox.com/s/hbgoegc20lex5ca/watchdog.rar - мой скрипт (тот, что в статье)
- https://www.dropbox.com/s/gglqmjifnvsiu6m/main.zip - прошивка ATmega8
- https://www.dropbox.com/s/27kzqjntz4ww2r5/hidtool.rar - утилита HIDTool для управления устройством
Позже, если Вадим (автор устройства) разрешит, выложу исходники...
Ответ Вадима: "Про исходники без проблем. Стыдно конечно немного за неотлаженный код, но кому сильно надо, сумеет понять."