Мониторинг климата в серверной.

ingener.solovyev
Offline
Зарегистрирован: 12.02.2013

Пилотный проект, на который на работе выдедлили средства.

Использовались:

Arduino Nano V 3.0

ENC28J60 Ethernet Shield

DHT 22 - модулем.

DS18B20 - 2 штуки.

Relay module 5v

Nano I/0 9v 2.5mm Power Sensor Expansion - в качестве распаячной платы.

Светодиод 1.37v (замерял сам) - 2шт.

Резистор 4.7кОм

 

Задача устройства такова:

Измерение и температуры и влажности с 3-х датчиков, передача данных на сервер.

В роли сервера выступает Processing

В Processinge данные обрабатываются, выводятся в терминал в  виде динамичных термометров, так же выводится информация о текущем времени, времени в работе, IP адрес Arduino и IP адрес WEB страницы с данными, которую генерирует сам процессинг. Так же каждые 30 минут записывются усредненные данные в лог файл формата .csv, раз в сутки (ровно в полночь) создается новый лог файл.

Когда температура выходит за пределы допустимых параметров:

  В Ардуино:

        Замыкается реле (подключение физической сигнализации).

  В процессинге:

       На веб страницу выводится сигнал аварии с сопровождением звукового сигнала "СИРЕНА".

Диоды:

  1. Просто информирует о включенном или выключенном состоянии устройства

  2. Горит при наличии сетевого соединения (DCHP).

 

Ну вот вроде и все. Все еще следует доробатывать и оптимизировать. В планах сделать динамичный график изменения температуры, более красивый интерфейс HTML и терминала Processing.

Спасибо за внимание.

Скетчи ниже.

Processing:

 

import processing.net.*;
PImage IMG;


//Связь с Ethernet клиентом и сервером
int html_port = 80;
int arduino_port = 82;
String IP_arduino = "10.168.2.129";
Server server;        
Client client;
int connect_arduino=0;
int connect_server=0;
//Символ до которого будем считывать данные
byte flag=62;
//Переменные с данными
float fl_data1=0.0, fl_data2=0.0, fl_data3=0.0, fl_data4=0.0, fl_data5=0.0, fl_data6=0.0, fl_data7=0.0;
String str_data[]; 
//Вывод данных в терминал
PFont font26, font36,  font36_2;
long time_previousMillis = 0;
int min_2=0, hr_2=0, day_2=0;
String data1="", data2="", data3="", data4="", data5="", data6="", data7="";
boolean start_2=true;
float y1,h1,y2,h2,y3,h3,y4,y5;
//
String climate;
//Логфайл
String filename, row_data;
PrintWriter save;
int sec, min, hr, day, month, year;
//Интервал записи в лог
long interval = 59000;
long previousMillis = 0;
boolean start=true;
//Интервал записи в массив
long array_previousMillis = 0;
int x=0;
//Массивы float численных данных за 30 минут
float DS18B20_1=0.0, DS18B20_2=0.0, DHT_T=0.0, DHT_H=0.0;
void setup()
{
  size(800, 600);
  IMG = loadImage ("theme.JPG");
  font26 = loadFont("ArialMT-26.vlw");
  font36 = loadFont("ArialMT-36.vlw");
  font36_2 = loadFont("AntiqueOlive-Italic-36.vlw");
  server = new Server(this, html_port);
  delay(3000);
  min = minute();  // Values from 0 - 59
  hr = hour();    // Values from 0 - 23
  day = day();
  month = month();
  year = year();
  filename = "DataLogger_"+hr+"_"+min+"_"+day+"_"+month+"_"+year+".csv";
  save = createWriter(filename);
  save.println("Time_Data;T1;T2;T3;H");
  save.flush (); // записывает данные, оставшиеся в файл
}

void draw()
{
  sec = second();  // Values from 0 - 59
  min = minute();  // Values from 0 - 59
  hr = hour();    // Values from 0 - 23
  day = day();
  month = month();
  year = year();
  background (208, 208, 208);
  image(IMG,0,0);
  //Прием данных с ардуино
  client = new Client(this, IP_arduino, arduino_port);
  delay (2000);
  client.write ("GET/Processing 2.0 ");
  delay (1000);
  while (client.available()>0){
    if (client !=null) {
      connect_arduino = 1; 
      String list = client.readStringUntil(flag);
      if (list != null) {
        str_data = split(list, ';');
      }
      } else {connect_arduino = 0;}
    
    client.stop ();
  
  
  //Преобразование string в float
  for (int i=1; i<5; i++){
    if (str_data[1] != null) {fl_data1=float(str_data[1]);}
    if (str_data[2] != null) {fl_data2=float(str_data[2]);}
    if (str_data[3] != null) {fl_data3=float(str_data[3]);}
    if (str_data[4] != null) {fl_data4=float(str_data[4]);}
    if (str_data[5] != null) {fl_data5=float(str_data[5]);}
    if (str_data[6] != null) {fl_data6=float(str_data[6]);}
    if (str_data[7] != null) {fl_data7=float(str_data[7]);}   
  }   
 
}

  // Вывод данных на экран
//  for (int i=1; i<9; i++) {
//      println (str_data[i]);}

  // Запускаем html СЕРВЕР
  Client thisClient = server.available();
   if (thisClient != null) {
     connect_server = 1;
     String whatClientSaid = thisClient.readString();
     if (whatClientSaid != null) {
          server.write ("<!DOCTYPE HTML>");
          server.write ("<html>");
          server.write ("<head> ");
          server.write ("<meta http-equiv= refresh  content=60;>");
          server.write ("<meta http-equiv='Content-Type' content='text/html; charset='utf-8' /> ");
          server.write ("</head> ");
          server.write ("<body>");
          server.write ("<b><font size='+3'>Микроклимат серверной: ");
          if (str_data[8].equals("bad")) {
             server.write ("<FONT color='#ff0000'>АВАРИЯ!!!</FONT>");
             server.write ("<audio autoplay='autoplay' loop='loop'>");
             server.write ("<source src='http://allsoundsaround.com/files/sounds/allsoundsaround.com-1270097130-Warning%20Siren-AllSoundsAround.com.mp3' type='audio/mpeg'>");
             server.write ("<source src='http://allsoundsaround.com/files/sounds/allsoundsaround.com-1270097130-Warning%20Siren-AllSoundsAround.com.wav' type='audio/wav'>");
             server.write ("</audio>"); }
          if (str_data[8].equals("good")) {server.write ("норма");}  
          server.write ("</font></b>");
          server.write ("<br> ");
          server.write ("<b>Датчик №1</b>");
          server.write ("<br> ");
          server.write ("Температура: ");
          server.write (str_data[1]);
          server.write (" *C");
          server.write ("<br>");
          server.write ("Влажность:   ");
          server.write (str_data[2]);
          server.write (" %");
          server.write ("<br> ");
          server.write ("<b>Датчик №2</b>");
          server.write ("<br> ");
          server.write ("Температура: ");
          server.write (str_data[3]);
          server.write (" *C");
          server.write ("<br> ");
          server.write ("<b>Датчик №3</b>");
          server.write ("<br> ");
          server.write ("Температура: ");
          server.write (str_data[4]);
          server.write (" *C");
          server.write ("<br> ");
          server.write ("<hr>");
          server.write ("<b><font size='+1'>Уставки сигналов аварии:</font></b>");
          server.write ("<br> ");
          server.write ("Верхний предел температуры: ");
          server.write (str_data[5]);
          server.write (" *C");
          server.write ("<br> ");
          server.write ("Нижний предел температуры: ");
          server.write (str_data[6]);
          server.write (" *C");
          server.write ("<br> ");
          server.write ("Аварийный максимум влажности воздуха: ");
          server.write (str_data[7]);
          server.write (" %");
          server.write ("<br> ");
          server.write ("<hr>");
          server.write ("</body></html>");
          server.disconnect(thisClient);
         
        }
       } else {connect_server=0;} //Конц html сервера
 // расчет средней температуры за период времени
 //запись данных в лог
if(millis() - array_previousMillis > interval) {
   array_previousMillis = millis();
   x++; 
   DHT_T +=fl_data1;
   DHT_H +=fl_data2;
   DS18B20_1 +=fl_data3;
   DS18B20_2 +=fl_data4;
   println (DHT_T);
   println (DHT_H);
   println (DS18B20_1);
   println (DS18B20_2);
   println (x);
    if (min == 29 || min == 59 || start == true) {
      DHT_T = DHT_T/x;
      DHT_H = DHT_H/x;
      DS18B20_1 = DS18B20_1/x;
      DS18B20_2 = DS18B20_2/x;
      row_data=hr+":"+min+" "+day+"."+month+";"+DHT_T+";"+DS18B20_1+";"+DS18B20_2+";"+DHT_H;
      save.println(row_data);
      println (row_data);
      save.flush (); // записывает данные, оставшиеся в файл   
      start=false;
      DHT_T = 0.0;
      DHT_H = 0.0;
      DS18B20_1 = 0.0;
      DS18B20_2 = 0.0;
      x=0;
    }
  }

 // Создание нового лог файла
if(millis() - previousMillis > interval) {
   previousMillis = millis(); 
   if (hr==0 && min==0) {
        save.close ();
        filename = "DataLogger_"+hr+"_"+min+"_"+day+"_"+month+"_"+year+".csv";
        save = createWriter(filename);
        save.println("Time_Data;T1;T2;T3;H");
        save.flush ();
      }
    }
//Вывод в граффическое окно
  //Расчет времени
    //Время текущее
if (day<10) {data1 = ""+"0"+day;}else{data1=""+day;}
if (month<10) {data2 = ""+"0"+month;}else{data2=""+month;}
if (hr<10) {data3 = ""+"0"+hr;}else{data3=""+hr;}
if (min<10) {data4 = ""+"0"+min;}else{data4=""+min;}
    //Время в работе
if(millis() - time_previousMillis > interval || start_2 == true) {
   time_previousMillis = millis(); 
   min_2++;
   start_2 = false;
   if (min_2 > 59) {hr_2++; min_2=0;}  
   if (hr_2 >23) {day_2++; hr=0;}
   if (day_2<10) {data5 = ""+"0"+day_2;}else{data5=""+day_2;}
   if (hr_2<10) {data6 = ""+"0"+hr_2;}else{data6=""+hr_2;}
   if (min_2<10) {data7 = ""+"0"+min_2;}else{data7=""+min_2;}
}
textFont(font26, 26);
fill (0);
text (Server.ip(), 197, 175); //Server IP
text (html_port, 467, 175); //Server port
text (IP_arduino, 197, 207); //Arduino IP
text (arduino_port, 467, 207); //Arduino IP
text (data1+"."+data2+"."+year+" "+data3+":"+data4, 128, 100);
text (data5+" days   "+data6+":"+data7, 569, 100);
textFont(font36, 36);
text (str_data[2]+"%", 632, 383); //Влажность
textFont (font36_2, 28);
if (connect_arduino == 1) { 
  fill (0, 255, 0);
  text ("Ok", 527, 207);}
else {fill (255, 0, 0); text ("Not", 527, 207);}
if (connect_server == 1) { 
  fill (0, 255, 0);
  text ("Ok", 527, 175);}
else {
      fill (255, 0, 0);
      text ("Not", 527, 175);}
      //Термометры
fill(235,29, 31);
stroke(235,29, 31);
y1 = 438-12*(fl_data1-15);
h1 = 438-y1;
rect(93, y1, 15, h1);
y2 = 438-12*(fl_data3-15);
h2 = 438-y2;
rect(262, y2, 15, h2);
y3 = 438-12*(fl_data4-15);
h3 = 438-y3;
rect(430, y3, 15, h3);
     //Уставки на термометрах
y4= 438-12*(fl_data5-15);
line (116, y4+1, 136, y4+1);
line (116, y4 , 136, y4);
line (285, y4+1, 305, y4+1);
line (285, y4 , 305, y4);
line (453, y4+1, 473, y4+1);
line (453, y4 , 473, y4);
stroke(38,38, 255);
y5= 438-12*(fl_data6-15);
line (116, y5+1, 136, y5+1);
line (116, y5 , 136, y5);
line (285, y5+1, 305, y5+1);
line (285, y5 , 305, y5);
line (453, y5+1, 473, y5+1);
line (453, y5 , 473, y5);
}
 

Arduino:

#include <EtherCard.h>
#include "DHT.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include <EEPROM.h>

// DHT 22
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
float h, t;
char H[5];
char T[5];

//DS18B20
#define ONE_WIRE_BUS 5
#define TEMPERATURE_PRECISION 9
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float t1, t2;
char T1[6];
char T2[6];

//Реле 1шт
int Relay=6;

//EEPROM Уставки сигналов аварий 1-в.пред.темп, 2-н.пред.темп, 3-в.пред.вл.
float sp1, sp2, sp3;
int simbol;
char U1[3], U2[3], U3[3];


//Ethernet
static byte mymac[] = {0x00, 0x04, 0xA3, 0x21, 0xCA, 0x38};
byte Ethernet::buffer[1024];

//временной интервал
long previousMillis = 0;
long interval = 10000;
boolean x=true;
//Уставки
char* climate;

// PROGMEM
char good [] PROGMEM = 
       "good";
char bad [] PROGMEM = 
       "bad"; 
  
//LED ON/OFF, Ethernet_connect
  int LED_ON = 9; //
  int LED_E_C = 3; //
  int brightness = 66;  //яркость светодиода на 1.3v


// SETUP
 void setup () {
  Serial.begin(9600);
  dht.begin();//DHT22
  
  sensors.begin(); //DS18B20
  
  //Реле 1 шт.
    pinMode(Relay, OUTPUT);
    digitalWrite(Relay, HIGH);
    
  //LED ON/OFF, Ethernet_connect
    pinMode(LED_ON, OUTPUT);
    pinMode(LED_E_C, OUTPUT);
    analogWrite(LED_ON, brightness);
         
  //EEPROM
    sp1 = EEPROM.read(1);
    dtostrf(sp1, 2, 0, U1);
    Serial.println (sp1);
    sp2 = EEPROM.read(2);
    dtostrf(sp2, 2, 0, U2);
    Serial.println (sp2);
    sp3 = EEPROM.read(3);
    dtostrf(sp3, 2, 0, U3);
    Serial.println (sp3);
        
  if (!ether.begin(sizeof Ethernet::buffer, mymac, 10)){
  Serial.println( "No");}
  else{ 
   Serial.println("Ok");
   }
  if (!ether.dhcpSetup()){
    Serial.println("No");
    }
  else {
    Serial.println("Ok");
  
  ether.printIp("IP:\t", ether.myip);
  ether.printIp("Mask:\t", ether.mymask);
  ether.printIp("Host:\t", ether.gwip);
  Serial.println();
  ether.hisport = 82;
  analogWrite(LED_E_C, brightness);
  }
 }
  

void loop() {
  
 //Смена уставок
 if(Serial.available()){
    simbol=Serial.read ();
    if (simbol==117) {
      
     byte t[3] = {0, 0, 0};
     for(byte i = 1; i < 4; i++)
     {
       t[i] = Serial.parseInt();
       EEPROM.write(i, t[i]);
     }
      for(byte i = 1; i < 4; i++)
    {
      t[i] = EEPROM.read(i);
      Serial.print(t[i]);
      if(i < 1) Serial.print(',');
      else Serial.println();
    }
   }
  }
  
 //Снятие показаний с датчиков
   //Установка интервала считывания
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval || x==true) {
   previousMillis = currentMillis; 
   x=false;
   //DHT22
   h = dht.readHumidity();
   dtostrf(h, 4, 1, H);
   t = dht.readTemperature();
   dtostrf(t, 4, 1, T);  
  
   //DS18B20
   sensors.requestTemperatures();
   t1 = sensors.getTempCByIndex(0);
   delay (50);
   dtostrf(t1, 5, 2, T1);
   t2 = sensors.getTempCByIndex(1);
   delay (50);
   dtostrf(t2, 5, 2, T2);
    
    Serial.println();
    Serial.print("T= ");
    Serial.println(T);
    Serial.print("H= ");
    Serial.println(H);
    Serial.print("T1= ");
    Serial.println(T1);
    Serial.print("T2= ");
    Serial.println(T2);
 }
   
 //Аварии
  if (t < sp2 || t1 <sp2 || t2 <sp2 || h > sp3) {
   digitalWrite (Relay, HIGH);
   climate=bad;
     } 
       else 
         { if (t > sp1 || t1 > sp1 || t2 > sp1 || h > sp3) {
             digitalWrite (Relay, HIGH);
             climate=bad;
            }
              else
              { 
                digitalWrite (Relay, LOW);
                climate=good;}
         }
    
  //Ethernet
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  
  if(pos) {
  
    
//   Serial.println("---------------------------------------- NEW PACKET ----------------------------------------");
//   Serial.println((char *)Ethernet::buffer + pos);
//   Serial.println("--------------------------------------------------------------------------------------------");
//   Serial.println();
   
        
    BufferFiller bfill = ether.tcpOffset();
    bfill.emit_p(PSTR(";$S;$S;$S;$S;$S;$S;$S;$F;>")
         , T, H, T1, T2, U1, U2, U3, climate);
    ether.httpServerReply(bfill.position());
   }
 }

 

4ulabek
Offline
Зарегистрирован: 05.05.2016