Мониторинг температуры в серверной с помощью Arduino

    Выходные в конце мая в Екатеринбурге ознаменовали начало лета, и понедельник нас поприветствовал 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
      0
      Когда я начинал читать, то сразу подумал «почему это датчик не был выведен наружу, хотя бы сантиметров в 5 от коробочки?».
        0
        Лень было наращивать выводы, тут то получилось пайка совсем без проводов.
          +3
          Извините меня конечно но статья совсем слабенькая. Налепить щилды друг на друга любой сможет, а софтовая часть чуть выше уровня Blink и Ethernet примеров доступных в самой Arduino IDE.
            0
            Собственно в том и суть, что минимумом затрат денег, сил и времени можно сделать вполне рабочий инструмент.
              +2
              В курсе, что «Написать комментарий» это совсем не то же самое, что «Ответить»? Оба раза?

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

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

              А можно сделать подобное на 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 или менять акб раз год-два?
                +2
                Даже лучше чем у автора получится. Шьете прошивку и получаете кучу возможностей и сервисов мониторинга. Можно и SMS слать при перегреве.
                  0
                  Стоит в серверной и шлет запросы на сервер. Ардуина работает как клиент и своей веб морды не имеет.
                  В итоге данные в sql таблице.

                  Можно посмотреть в любом интерфейсе который умеет получать данные с SQL.
                  Планируется отправка СМС и почты но уже другими средствами по данным из БД
                    0
                    WIFI и BT в серверной? АКБ?
                      0
                      Wi-Fi в серверной?
                      Шутить изволите!
                      Сигнал дальше второй-третьей стойки не уйдёт
                      0
                      А температуру с роутеров, свитчей и серверов по snmp снимать не?
                      Понятно, что там температура повыше будет внутри оборудования. Но мониторить по 2-3 разным датчикам вполне реально.
                        0
                        Обычно для ИБП есть выносные блоки температура + влажность. Снимается по SNMP.
                        0
                        Мы у себя используем ССM-033 для балансирования кондиционерами и GSM RC-110 для информирования. Уже более трех лет не было серьезных аварий. Серверных комнат — 6 штук. Оба прибора — отечественного производства.

                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                        Самое читаемое