Nu am experienta cu modulele arduino si nu sunt nici programator.
Nu am invatat C++ si nici html, deci este o adevarata provocare pentru mine acest project :).
Projectul nu este inca finalizat, este mai mult creat in scop personal pana la finalizare
(dar totusi este perfect functional deja :)))
Idea a pornit de la faptul ca in baie nu avem geam si ar fi nevoie de controlul umiditatii.
Codul este preluat de pe internet din mai multe locuri dupa care a fost usor modificat combinat, adaugat in proiect si schimbat ca sa si functioneze, banuiesc ca nimeni nu se va supara....
Ce ar trebui.. si ce face modulul ?
La "prima" pornire deschide un punct AP care poate fi accesat cu telefonul.
Telefonul se conecteaza la AP primeste automat un ip si se conecteaza la site-ul de configurare cu o parola simpla care in momentul de fata este 12345678 dar poate fi schimbat.
In modul AP se deschide un site unde se specifica numele retelei wifi si parola care se salveaza in memoria modulului. Dupa restart modulul se conecteaza automat la reteaua wifi existenta.
Modulul dupa repornire nu mai intreaba de retea (am avut nevoie de retea pentru afisarea ceasului care nu are modul RTC dar fiind conectat la net se actualizeaza dupa un server NTC).
Setarile de retea se pot reseta cu un buton sau prin reprogramare. (butonul inca nu este fizic montat)
In loc de ventilator si releuri momentan se cupleaza doar 4 LED-uri, in functie de scaderea temperaturii, in functie de cresterea umiditatii aerului peste un anumit nivel, manual din interfata web si senzor PIR .
Are un server http care afiseaza in timp real (intarziere de aprox 3 secunde) starea "aparatelor" conectate (momentan sunt doar LED-uri). Intarzierea se datoreaza faptului ca programul face refresh la pagina si devine deranjant daca o face prea des, din cauza ceasului am ales sa faca refresh la 3 secunde (se poate seta dupa preferinte).
Senzorul de prezenta umana PIR detecteaza orice miscare si urmeaza implementarea functiei cu care sa trimita un avertisment prin sms pe telefonul personal metoda aleasa este prin google...
PIR poate activa un dispozitiv (un bec de exemplu) si poate trimite si un avertisment prin sms in momentul in care detecteaza miscare, functioneaza si noaptea fara lumina.
Componente folosite:
- Modul NodeMCU Lua wifi V3 CH340 ~37 Ron (are 16MB)
- Breadboard 830 puncte MB102 ~9 Ron + 2 mai mici cu ~4ron
- Modul convertor sursă de alimentare 5-3.3V~ 5Ron
- Senzor temperatura si umiditate DHT11 ~9Ron
- Ecran OLED 0.96” ~23Ron (nu este necesar dar arata bine)
- Modul senzor de prezenta PIR ~8Ron
- Led -uri
- Releu-uri
- Fire de conectare
Descrierea de configurari, softuri (IDE) si librariile pentru a programa modulul vor fi pe alta pagina
/* dht, OLED, Led on off etc.. webserver */
/*definire librarii utilizate */
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` SSD1306 OLED display (128×64 Pixel)
#include "DHT.h"
#include <ESP8266WiFi.h>
#include <WiFiServer.h>
#include <WebServer.h>
#include <DNSServer.h>
#include <WiFiManager.h>
#include <NTPClient.h> /*NTP Client library forked by Taranais https://randomnerdtutorials.com/esp32-ntp-client-date-time-arduino-ide/
am folosit dar ar trebui cel oficial este la https://github.com/arduino-libraries/NTPClient */
#include <WiFiUdp.h>
/* initializare display*/
SSD1306 display(0x3c, 5, 4); // Initialize the OLED display using Wire library
/*definire pini iesire pt comanda led sau releu */
// GPIO4 GPIO5 -D1 -D2 OLED Display
int ledPin = 13; // GPIO13 -D7 LED setat prin interfata web manual
int ledPin2 = 12; // GPIO12 -D6 LED sau Releu temperatura
int ledPin3 = 14; // GPIO14 -D5 LED sau Releu umiditate
int ledPin4 = 2; // GPIO2 -D4 LED sau Releu detetor de miscare PIR
//definire pin senzor PIR
int pirSensor = 16;//GPIO16 -D0
// definire buton reset wifi to ap
const int PIN_AP = 10;
/*definire port server http */
WiFiServer server(80);
// Definire Client NTP pentru data si ore
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
// Definire Variabile pentru salvare data si timp
String formattedDate;
String dayStamp;
String timeStamp;
String timeStamp2;
String ipstring;
/* definitie senzor temperatura si umiditate DHT11 */
#define DHTPIN D3
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
int localHum = 0;
int localTemp = 0;
int varpir=0;
//DEFINIRE ALTE VARIABILE
int value = LOW;
int value2 = LOW;
int value3 = LOW;
int value4 = LOW;
/*
*
_________________________________________________________________________________________________________*
*/
// Variable to store the HTTP request
String header;
/* ________________definire setari initiale nerepetitive___________________________________________________*/
void setup()
{
Serial.begin(115200);
display.init(); // Initialising the UI will init the display too.
display.flipScreenVertically();
delay(1000);
/*__________________________________________WifiManager________________________*/
WiFiManager wifiManager;
//wifiManager.setAPStaticIPConfig(IPAddress(192,168,100,9), IPAddress(192,168,100,1), IPAddress(255,255,255,0));
wifiManager.autoConnect("AutoConnectAP","12345678");
Serial.println(WiFi.localIP());
wifiManager.getSSID();
//definire pin senzor pir ca si intrare
pinMode(pirSensor, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
pinMode(ledPin2, OUTPUT);
digitalWrite(ledPin2, LOW);
pinMode(ledPin3, OUTPUT);
digitalWrite(ledPin3, LOW);
pinMode(ledPin4, OUTPUT);
digitalWrite(ledPin4, LOW);
// Start the server
server.begin();
Serial.println("Server started");
// Print the IP address
Serial.print("Use this URL to connect: ");
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.println("/");
// Initializare ClientNTP pentru preluarea timpului
timeClient.begin();
// Set offset time in seconds to adjust for your timezone, for example:
// GMT +1 = 3600 GMT +8 = 28800 GMT -1 = -3600 GMT 0 = 0 GMT +2 (Bucuresti) = +7200
timeClient.setTimeOffset(7200);
}
/*___________________________________________________________________________________________________________*/
/* Repetari citiri scrieri in bucla */
void loop()
{
WiFiManager wifiManager;
//daca butonul a fost apasat
if ( digitalRead(PIN_AP) == HIGH ) {
Serial.println("reset"); //resetam si intram in mod ap
if(!wifiManager.startConfigPortal("AutoConnectAP","12345678") ){
Serial.println("Ne conectam");
delay(2000);
ESP.restart();
delay(1000);
}
Serial.println("Conectat la AutoConnectAP!!!");
}
// update ntc
timeClient.update();
// funtie detectare miscare cod la sfarsit
senzorPIR();
// functie preluarea temperaturii pentru a fi afisata si pentru a executa comenzi in functie de valori
getDHT();
display.clear();
drawDHT();
display.display();
delay (1000);
// functii NTP
// The formattedDate comes with the following format:
// 2018-05-28T16:00:13Z
// We need to extract date and time
formattedDate = timeClient.getFormattedDate();
// Serial.println(formattedDate);
// Extract date
int splitT = formattedDate.indexOf("T");
dayStamp = formattedDate.substring(0, splitT);
//Serial.print("DATE: ");
// Serial.println(dayStamp);
// Extract time
timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-1);
timeStamp2 = formattedDate.substring(splitT+1, formattedDate.length()-4);
//Serial.print("HOUR: ");
// Serial.println(timeStamp);
delay(1);
// Extract time
timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-1);
//
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
/*___________________________________________________________________*/
/*___________________________________________________________________*/
// Read the first line of the request
String request = client.readStringUntil('\r');
Serial.println(request);
client.flush();
float h =0.0; //Humidity level
float t =0.0; //Temperature in celcius
float f =0.0; //Temperature in fahrenheit
// Match the request
// But Wait until the client sends some data
Serial.println("new client");
while(!client.available()){
delay(1);
}
// Set ledPin according to the request
if (localTemp < 23) {
value2 = HIGH;}
else{
value2 = LOW;
}
if (localHum > 40) {
value3 = HIGH;}
else{
value3 = LOW;
}
// Return the response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println(""); // do not forget this one
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.print ("<body style=background-color:#ffffcc>");
// client.println("<meta http-equiv=\"refresh\" content=\"5\">");
// am introdus de aici
// Match the request
// if (request.indexOf("/Up=ON") != -1) {
h = dht.readHumidity(); //Read humidity level
t = dht.readTemperature()-1 ; //Read temperature in celcius corectat
f = (h * 1.8) + 32; //Temperature converted to Fahrenheit
// value = HIGH;
// }
// Return the response
client.println(""); // do not forget this one
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<h1 align=center><font color=red>Web Server cu urmatoarele functii:</h1></font><br>");
client.println("<h3 align=center>Led ori releu pornit ori oprit din interfata web<br>");
client.println("Control de temperatura & umiditate cu senzorul DHT11 & Ceas functional NTC (necesita conectare wifi)<br> + detector de miscare PIR</h3><br>");
client.print("<center>Temperatura in Celsius =");
client.println(t);
// inseram codul pentru semnul de celsius ℃
client.println("℃ \_/ Temperatura in Fahrenheit = ");
client.println(f);
// inseram codul pentru semnul Farenheit
client.println("℉<br>");
if(varpir == 1) {
client.println("<font color=\"red\", size=28>PIR Detectat miscare/prezență!!</font><br>");
} else { client.println("<font color=\"green\">PIR Nimic de raportat</font><br>");
}
//client.println("<br><br>");
// inserat de sus
client.print("Controlul manual al unui consumator Led ori releu prin interfata web :</font>");
client.print("Ledul acum este: <br>");
if(value == HIGH) {
client.print("<font color=red>Pornit</font>");
} else {
client.print("<font color=red>Oprit</font>");
}
client.println("<br><br>");
client.println("<a href=\"/LED=ON\"\"><button>Activeaza </button></a>");
client.println("<a href=\"/LED=OFF\"\"><button>Opreste </button></a><br /><br>");
// codul html pentru semnul celsius este : ℃
client.print(" Al doilea Led ori releu cupleaza cand temperatura scade sub 23 ℃ ");
client.print("Ledul este acum: <br>");
if(value2 == HIGH) {
client.print("<font color=red>Pornit</font>");
} else {
client.print("<font color=red>Oprit</font>");
}
client.println("<br><br>");
client.print("<font color=red>Temperatura locala este: </font>");
client.println("<br>");
client.println(localTemp);
client.print("℃");
client.println("<br>");
client.print("Al treilea Led ori releu cupleaza cand umiditatea este mai mare de 40% Ideal este intre 30 si 50% ");
client.print("Ledul este acum: <br>");
if(value3 == HIGH) {
client.print("<font color=red>Pornit</font>");
} else {
client.print("<font color=red>Oprit</font>");
}
client.println("<br><br>");
client.print("<font color=red>Umiditatea locala este acum de: </font>");
client.println(localHum);
client.print("%<br></br>");
// client.println("<br>");
// iar aici incerc data si ora
client.print("DATE: ");
client.println(dayStamp);
client.print("HOUR: ");
client.println(timeStamp);
// pana aici
client.println("</center></html>");
delay(1);
Serial.println("Client disonnected");
Serial.println("");
//________________________
if (request.indexOf("/LED=ON") != -1) {
digitalWrite(ledPin, HIGH);
value = HIGH;
}
if (request.indexOf("/LED=OFF") != -1) {
digitalWrite(ledPin, LOW);
value = LOW;
}
/*/ inainte de terminare dam refresh pentru citirea valorilor care se schimba si setarea caii http:// la cel initial ca sa nu afecteze alti clienti
----------------------------------------------------reusit cu chinuiala proprie :)----------------------------------------------------------------*/
client.print("<meta http-equiv='Refresh' content='2; url=http://"+WiFi.localIP().toString()+"'> ") ;
}
/***************************************************
* Get indoor Temp/Hum data
****************************************************/
void getDHT()
{
float tempIni = localTemp;
float humIni = localHum;
localTemp = dht.readTemperature()-1 ; //kijavitottam a homersekletet mert tul sokat mutatott
localHum = dht.readHumidity();
if (isnan(localHum) || isnan(localTemp)) // Check if any reads failed and exit early (to try again).
{
Serial.println("Failed to read from DHT sensor!");
localTemp = tempIni;
localHum = humIni;
return;
}
}
/***************************************************
* Draw Indoor Page
****************************************************/
void drawDHT()
{
int x=0;
int y=0;
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0 + x, 5 + y, "Hum");
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(43 + x, y, "INDOOR");
display.setFont(ArialMT_Plain_24);
String hum = String(localHum) + "%";
display.drawString(0 + x, 15 + y, hum);
int humWidth = display.getStringWidth(hum);
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(95 + x, 5 + y, "Temp");
display.setFont(ArialMT_Plain_24);
String temp = String(localTemp) + "°C";
display.drawString(70 + x, 15 + y, temp);
int tempWidth = display.getStringWidth(temp);
display.setFont(ArialMT_Plain_24);
String time1 = String(timeStamp2);
display.drawString(30 + x, 39 + y, time1);
int time1Width = display.getStringWidth(time1);
//deasemenea comanda trebuie sa mearga fara interfata web
int value = digitalRead(ledPin);
int value2 = LOW;
int value3 = LOW;
if (localTemp < 23) {
digitalWrite(ledPin2, HIGH);
value2 = HIGH;}
else{
digitalWrite(ledPin2, LOW);
value2 = LOW;
}
if (localHum > 40) {
digitalWrite(ledPin3, HIGH);
value3 = HIGH;}
else{
digitalWrite(ledPin3, LOW);
value3 = LOW;
}
}
/***************************************************
* Detectare miscare
****************************************************/
void senzorPIR()
{
// bucla senzorPIR
long state = digitalRead(pirSensor);
if(state == HIGH) {
digitalWrite (ledPin4, HIGH);
// Serial.println("Miscare Detectata!");
varpir=1;
delay(1000);
}else{
digitalWrite(ledPin4, LOW);
//Serial.println("Absenta miscare, totul este in regula");
varpir=0;
delay(1000);
}
while(!timeClient.update()) {
timeClient.forceUpdate();
}
}


