Официальный сайт компании Arduino по адресу arduino.cc
Мониторинг климата в серверной.
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Пилотный проект, на который на работе выдедлили средства.
Использовались:
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()); } }
Тут выдает ошибку, что-то с кавычками не понятное