Выходные в конце мая в Екатеринбурге ознаменовали начало лета, и понедельник нас поприветствовал 39-и градусной жарой в небольшой комнате с двумя серверными стойками. Причина банальна — отказал один из кондиционеров, от старости. Обошлось малой кровью и почти никто из 250 сотрудников проблем не почувствовал.
Захотелось как-то если не управлять ситуацией, то хотя-бы ее мониторить. Вариант приобретения готового девайса притормозился, а потом и отменился его ценой. Но вспомнилось волшебное слово Arduino, если интересно что получилось прошу под кат.

Ардуино уно, и два шилда (ethernet и keypad) собрались в трехслойный пирог:
image

Датчик температуры ds18b20 припаян сверху справа на keypad shield, чтобы посадить верхний шилд пришлось немного нарастить ему ноги, припаяв шедший в комплексе с ардуино разъем — гребенку.
image

И очень удачно это дело поместились в разводную коробку из строительного магазина
image

На PHP был написан скрипт для прима GET запросов и записи данных в SQL.

Один раз в минуту отправляет запрос на сервер, выглядит это так:


Как показали натурные испытания, датчик нужно выносить наружу из корпуса, иначе завышает температуру примерно на 5 градусов, но можно и программно учесть погрешность.

Посмотреть Скетч
#include <SPI.h>
#include <Ethernet.h>
#include "LiquidCrystal_1602_RUS.h"
#include <EEPROM.h>
#include <avr/interrupt.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <avr/wdt.h>

LiquidCrystal_1602_RUS lcd(8, 9, 4, 5, 6, 7 );//For LCD Keypad Shield
OneWire ds(15); DallasTemperature sensors(&ds); float temp; 
String readString = String(300); 
String message;

int opros=0; int sends=0; int sendperiod=0; int dog=0;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = "test.domain.ru";    
IPAddress ip(10, 0, 0, 177);
EthernetClient client;

void setup() 
{
  lcd.begin(16, 2);

//Подключение прерывания по переполнению Timer2 
  TCCR2A = 0; 
  TCCR2B = 0<<CS22 | 1<<CS21 | 0<<CS20; 
  TIMSK2 = 1<<TOIE2; 
  sei();
  wdt_enable(WDTO_8S);  
}

ISR(TIMER2_OVF_vect) 
{
   opros++;

//Опрашиваем датчик температуры и выводим на дисплей примерно раз в секунду
    if(opros==7500) 
    {
      sensors.requestTemperatures();
      temp = sensors.getTempCByIndex(0);
       lcd.setCursor(0,0); lcd.print(message); 
       lcd.setCursor(0,1); if(60-sendperiod<10){lcd.print(0);} lcd.print(60-sendperiod);
       lcd.setCursor(9,1); lcd.print(temp);  lcd.print(L"°C");
      opros=0;

//Сторожевой таймер сработает при зависании или через 10 минут если вдруг код запроса к сети застрянет     
     if(sends!=0){dog++;} else {dog=0;}
      if(dog<600){wdt_reset();}  
     
//Примерно раз в минуту посылам запрос на сервер
      if (sends==0 && sendperiod==0){sends=1;}  
      sendperiod++; if(sendperiod==60){ sendperiod=0;}  
          
    }
   
}

void loop() 
{

//Соединяемся с сервером и отправляем запрос
if (sends==1) 
{
  message="Connect         ";
  lcd.setCursor(0,0); lcd.print(L"Connect         ");
  sends=2; 
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) 
  {
    ; // wait for serial port to connect. Needed for native USB port only
  }  
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) 
    {
    Serial.println("connected");
    // Make a HTTP request:
    
    client.print("GET /info/temp.php?t=");
    client.print(temp);
    client.println(" HTTP/1.1");
    client.println("Host: test.domain.ru");
    client.println("Connection: close");
    client.println();
    } 
  else 
    {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
    }
  sends=3;
}  
  
//После отправки запроса обрабатываем ответ
if(sends==3)
 { 
  if (client.available()) 
  {
    
    char c = client.read();
    Serial.print(c);
      if (c != '\n'){readString+= c;}
 }

//Закрываем соединение после обработки ответа
  if (!client.connected()) 
  {
    Serial.println();
    Serial.println("disconnecting.");
    if(readString.indexOf("z666")>0)
     {message="OK ";message+= readString.substring(readString.indexOf("z666")+5,readString.indexOf("z666")+19);}
     else {message="Send error";}
    readString="";
    client.stop();
    sends=0;
  } 
 }
}

Поделиться с друзьями
-->

Комментарии (13)


  1. IronKaktus
    02.06.2016 17:43

    Когда я начинал читать, то сразу подумал «почему это датчик не был выведен наружу, хотя бы сантиметров в 5 от коробочки?».


  1. alexhott
    02.06.2016 17:44

    Лень было наращивать выводы, тут то получилось пайка совсем без проводов.


  1. Bobnecat
    02.06.2016 19:30
    +3

    Извините меня конечно но статья совсем слабенькая. Налепить щилды друг на друга любой сможет, а софтовая часть чуть выше уровня Blink и Ethernet примеров доступных в самой Arduino IDE.


  1. alexhott
    02.06.2016 20:40

    Собственно в том и суть, что минимумом затрат денег, сил и времени можно сделать вполне рабочий инструмент.


    1. Ezhyg
      02.06.2016 23:51
      +2

      В курсе, что «Написать комментарий» это совсем не то же самое, что «Ответить»? Оба раза?

      P.S. пишу здесь, потому что в личке это будет не наглядно


  1. Arxitektor
    02.06.2016 20:56

    Данная штука стоит в серверной?
    И температуру можно посмотреть в веб интерфейсе?

    А можно сделать подобное на ESP8266 ESP-03 http://www.banggood.com/ESP8266-ESP-03-Remote-Serial-Port-WIFI-Transceiver-Wireless-Module-p-961244.html
    и термодатчик DS18B20
    Пробовал ли кто подобное делать?
    Чтобы по Wi-FI данные слать.
    Или на BT 4.0 LE или менять акб раз год-два?


    1. Tonna
      02.06.2016 23:35
      +2

      Даже лучше чем у автора получится. Шьете прошивку и получаете кучу возможностей и сервисов мониторинга. Можно и SMS слать при перегреве.


    1. alexhott
      03.06.2016 06:28

      Стоит в серверной и шлет запросы на сервер. Ардуина работает как клиент и своей веб морды не имеет.
      В итоге данные в sql таблице.

      Можно посмотреть в любом интерфейсе который умеет получать данные с SQL.
      Планируется отправка СМС и почты но уже другими средствами по данным из БД


    1. miron36357
      06.06.2016 09:10

      WIFI и BT в серверной? АКБ?


    1. Ranckont
      06.06.2016 09:11

      Wi-Fi в серверной?
      Шутить изволите!
      Сигнал дальше второй-третьей стойки не уйдёт


  1. miha2
    03.06.2016 08:27

    А температуру с роутеров, свитчей и серверов по snmp снимать не?
    Понятно, что там температура повыше будет внутри оборудования. Но мониторить по 2-3 разным датчикам вполне реально.


    1. AcidVenom
      06.06.2016 09:13

      Обычно для ИБП есть выносные блоки температура + влажность. Снимается по SNMP.


  1. Foggy4
    03.06.2016 12:11

    Мы у себя используем ССM-033 для балансирования кондиционерами и GSM RC-110 для информирования. Уже более трех лет не было серьезных аварий. Серверных комнат — 6 штук. Оба прибора — отечественного производства.