Код:
#include <WiFi.h>
#include <Wire.h>
#include <ArduinoJson.h>
#include "time.h"
#include "Adafruit_BME280.h"
#include <HTTPClient.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
//#define I2C_SDA 4
//#define I2C_SCL 5
#define LED_PIN 2
#define BME280_ADDRESS 0x76
char buffer [256];
char server[] = "smtpcorp.com"; // smtp сервер сайта smtp2go для отправки через него емэйла
int port = 2525;
char login[] = "*****@gmail.com"; // Ваш логин с сайта smtp2go
char password[] = "******"; // Ваш пароль с сайта smtp2go
char email_sendto[] = "*******@gmail.com"; // Адрес получателя письма
char email_sendfrom[] = "******@gmail.com"; // Адрес отправителя письма
char name_sendto[] = "*****"; // Имя получателя письма
char name_sendfrom[] = "*****"; // Имя отправителя письма
char subject[] = "ESP32 was rebooted!"; // Тема письма
const long gmtOffset_sec = 7200;
const int daylightOffset_sec = 3600;
const char* ntpServer = "pool.ntp.org";
Adafruit_BME280 bme;
const char* ssid = "*****";
const char* passwordwifi = "******";
const char * hostDomain = "api.openweathermap.org";
const int hostPort = 80;
const char * narmon = "narodmon.ru";
const int narmonPort = 8283;
String line;
WiFiClient client;
unsigned long WeatherPreviousMillis = 0;
unsigned long NTPPreviousMillis = 0;
unsigned long NarmonPreviousMillis = 0;
String name1;
float temp;
float pressure;
float humidity;
float wind;
float bpi_USD_rate;
float USD_rate;
void Bitcoin() {
HTTPClient http;
http.begin("http://api.coindesk.com/v1/bpi/currentprice.json");
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
StaticJsonBuffer<1536> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(payload);
if (root.success()) {
{
String time_updated = root["time"]["updated"];
//const char* time_updated = time["updated"];
//JsonObject& bpi = root["bpi"];
//JsonObject& bpi_USD = bpi["USD"];
bpi_USD_rate = root["bpi"]["USD"]["rate_float"];
Serial.print("Curs of bitcoin: ");
Serial.println(bpi_USD_rate);
Serial.print("Update time: ");
Serial.println(time_updated);
}
} else {
Serial.println("parseObject() failed");
Serial.println(payload);
}
} else {
Serial.println("HTTP error");
Serial.println(httpCode);
}
http.end();
}
void USD() {
HTTPClient http;
http.begin("http://www.nbrb.by/API/ExRates/Rates/145");
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
StaticJsonBuffer<1536> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(payload);
if (root.success()) {
{
USD_rate = root["Cur_OfficialRate"];
Serial.print("Curs of USD: ");
Serial.println(USD_rate);
}
} else {
Serial.println("parseObject() failed");
Serial.println(payload);
}
} else {
Serial.println("HTTP error");
Serial.println(httpCode);
}
http.end();
}
void SendMon()
{
String cmd;
cmd = "#**-**-**-**-**-**";
cmd += "\n";
cmd += "#T1#";
cmd += bme.readTemperature();
cmd += "\n";
cmd += "#P1#";
cmd += (bme.seaLevelForAltitude(138, bme.readPressure() / 100.0F ) / 1.333);
cmd += "\n";
cmd += "#H1#";
cmd += bme.readHumidity();
cmd += "\n";
cmd += "#B1#";
cmd += bpi_USD_rate;
cmd += "\n";
cmd += "##";
Serial.println("Connecting to narodmon.ru:");
if (!client.connect(narmon, narmonPort))
{
Serial.println("connection failed");
return;
}
Serial.println("Connected!");
client.println(cmd);
unsigned long timeout = millis();
while (client.available() == 0)
{
if (millis() - timeout > 2000)
{
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}
Serial.println("closing connection");
client.stop();
Serial.println("Weather is loaded to narmon.ru");
}
void requestURL(const char * host, uint8_t port)
{
Serial.println("Connecting to domain: " + String(host));
if (!client.connect(host, port))
{
Serial.println("connection failed");
return;
}
Serial.println("Connected!");
client.println("GET /data/2.5/weather?q=Homyel&mode=json&units=metric&APPID=8bb1caef3ad28de754c259361baffd58 HTTP/1.1");
client.print("Host: api.openweathermap.org\r\n");
client.print("Connection: close\r\n\r\n");
unsigned long timeout = millis();
while (client.available() == 0)
{
if (millis() - timeout > 2000)
{
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}
// Read all the lines of the reply from server and print them to Serial
while (client.available())
{
line = client.readStringUntil('\r');
}
Serial.println("closing connection");
client.stop();
}
void printLocalTime()
{
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%d.%m.%Y %H:%M:%S");
int intVar; //Преобразуем значение времени в целове число, так как функция возвращает нам строку, непригодную для сравнения
String time_int;
char output[10];
strftime(output, 10, "%H", &timeinfo);
time_int = String(output);
intVar = time_int.toInt();
Serial.println(intVar);
if (intVar > 22 || intVar < 6 )
{
Serial.println("SVET OFF");
lcd.noBacklight();
}
else
{
Serial.println("SVET ON");
lcd.backlight();
}
}
void printLocalTimeDateLcd()
{
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
lcd.setCursor(10, 0); //Переходим на 10 ячейку дисплея 1-ой строки
lcd.println(&timeinfo, "%d.%m.%Y");
lcd.setCursor(15, 1); //Переходим на 15 ячейку дисплея 2-ой строки
lcd.print(&timeinfo, "%H:%M:%S");
}
//void printLocalTimeTimeLcd()
//{
//struct tm timeinfo;
// if (!getLocalTime(&timeinfo)) {
// Serial.println("Failed to obtain time");
// return;
// }
// lcd.setCursor(15, 1); //Переходим на 15 ячейку дисплея 2-ой строки
// lcd.print(&timeinfo, "%H:%M:%S");
//}
void parseJSON(String weather)
{
StaticJsonBuffer<3000> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(weather);
if (!root.success())
{
Serial.print("ParseObject() failed");
}
String name = root["name"];
name1 = name;
// Serial.print("City: ");
// Serial.println(name1);
temp = root["main"]["temp"];
// Serial.print("Temp: ");
// Serial.print(temp);
// Serial.println(" C");
pressure = root["main"]["pressure"];
// Serial.print("Pressure: ");
// Serial.print(pressure / 1.333);
// Serial.println(" mmHg");
humidity = root["main"]["humidity"];
// Serial.print("humidity: ");
// Serial.print(humidity);
// Serial.println(" %");
wind = root["wind"]["speed"];
}
void setup()
{
bme.begin(0x76);
lcd.begin(21,22);
// lcd.init(); // initialize the lcd
lcd.backlight();
Serial.begin(9600);
delay(100);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, passwordwifi);
int var = 0;
while (WiFi.status() != WL_CONNECTED && var < 20) {
delay(500);
Serial.print(".");
Serial.print(var);
if (var == 19) {
ESP.restart();
}
var++;
}
Serial.println("");
Serial.println("WiFi connected");
lcd.setCursor(0, 0);
lcd.print("Connected to ");
lcd.setCursor(0, 1);
lcd.print(ssid);
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
lcd.setCursor(0, 3);
lcd.print(WiFi.localIP());
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("MAC");
lcd.setCursor(0, 1);
lcd.print("30AEA437F33C");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Login on Narmon");
lcd.setCursor(0, 1);
lcd.print("leruetkins");
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Serial.println("Time is updated on NTP");
requestURL(hostDomain, hostPort);
parseJSON(line);
// Serial.println("Weather is updated on openweather.com");
Bitcoin();
//Serial.println("Bitcoin curs is updated");
USD();
if (bme.readTemperature() <= 0 ) {
sendEmail();
Serial.println(" ESP RESTART");
delay(2000);
ESP.restart();
}
SendMon();
// Serial.println("Weather is loaded to narmon.ru");
}
void efail()
{
byte thisByte = 0;
int loopCount = 0;
client.println(F("QUIT"));
while (!client.available()) {
delay(1);
loopCount++;
// if nothing received for 10 seconds, timeout
if (loopCount > 10000) {
client.stop();
Serial.println(F("\r\nTimeout"));
return;
}
}
while (client.available())
{
thisByte = client.read();
Serial.write(thisByte);
}
client.stop();
Serial.println(F("disconnected"));
}
byte eRcv()
{
byte respCode;
byte thisByte;
int loopCount = 0;
while (!client.available()) {
delay(1);
loopCount++;
// if nothing received for 10 seconds, timeout
if (loopCount > 10000) {
client.stop();
Serial.println(F("\r\nTimeout"));
return 0;
}
}
respCode = client.peek();
while (client.available())
{
thisByte = client.read();
Serial.write(thisByte);
}
if (respCode >= '4')
{
efail();
return 0;
}
return 1;
}
byte sendEmail() //Функция отправки письма
{
byte thisByte = 0;
byte respCode;
if (client.connect(server, port) == 1) {
Serial.println(F("connected"));
}
else {
Serial.println(F("connection failed"));
return 0;
}
if (!eRcv()) return 0;
Serial.println(F("Sending hello"));
// replace 1.2.3.4 with your Arduino's ip
client.println("EHLO 1.2.3.4");
if (!eRcv()) return 0;
Serial.println(F("Sending auth login"));
client.println("auth login");
if (!eRcv()) return 0;
Serial.println(F("Sending User"));
// Change to your base64 encoded user
client.println("bGVydWV0a2luc0BnbWFpbC5jb20=");
if (!eRcv()) return 0;
Serial.println(F("Sending Password"));
// change to your base64 encoded password
client.println("c210cDEyM2E0NTY=");
if (!eRcv()) return 0;
// change to your email address (sender)
Serial.println(F("Sending From"));
// client.println("MAIL From: <leruetkins@gmail.com>");
client.print("MAIL From: <");
client.print(email_sendfrom);
client.println(">");
if (!eRcv()) return 0;
// change to recipient address
Serial.println(F("Sending To"));
//client.println("RCPT To: <leruetkins@gmail.com>");
client.print("RCPT To: <");
client.print(email_sendto);
client.println(">");
if (!eRcv()) return 0;
Serial.println(F("Sending DATA"));
client.println("DATA");
if (!eRcv()) return 0;
Serial.println(F("Sending email"));
// change to recipient address
//client.println("To: You <her@gmail.com>");
client.print("To: ");
client.print(name_sendto);
client.print(" <");
client.print(email_sendto);
client.println(">");
// change to your address
//client.println("From: Me <her@gmail.com>");
client.print("From: ");
client.print(name_sendfrom);
client.print(" <");
client.print(email_sendfrom);
client.println(">");
//client.println("Subject: 111\r\n");
client.print("Subject: ");
client.print(subject);
client.println("\r\n");
client.print("ESP32 was rebooted at: ");
struct tm timeinfo;
getLocalTime(&timeinfo);
client.println(&timeinfo, "%H:%M:%S %d.%m.%Y");
client.println("Have a nice day!");
client.println(".");
if (!eRcv()) return 0;
Serial.println(F("Sending QUIT"));
client.println("QUIT");
if (!eRcv()) return 0;
client.stop();
Serial.println(F("disconnected"));
return 1;
}
void loop()
{
if (WiFi.status() != WL_CONNECTED){ //Проверям, есть ли подключение к wifi и если нету перезагружаемся
ESP.restart();}
if (bme.readTemperature() <= 0 ) { //Проверяем, подключён или не завис ли bme280 и в случае чего перезагружаемся
sendEmail();
Serial.println(" ESP RESTSRT");
delay(2000);
ESP.restart();
}
unsigned long CurrentMillis = millis();
Serial.println(CurrentMillis);
//Получение времени с NTP сервера
int tntp = 3600000; // Интервал получения времени с NTP сервера
Serial.println(CurrentMillis - NTPPreviousMillis);
Serial.print(round((tntp - (CurrentMillis - NTPPreviousMillis)) / 60000)); // Количество оставшихся минут до получения времени с с NTP сервера
Serial.println(" m. - estimated time to get time from NTP");
if (CurrentMillis - NTPPreviousMillis > tntp) {
NTPPreviousMillis = CurrentMillis;
Serial.println(NTPPreviousMillis);
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Serial.println("Time is updated on NTP");
}
//Получение погоды с сайта openweather.com
int tw = 1800000; // Интервал получения данных с сайта openweather.com в миллисекундах
Serial.println(CurrentMillis - WeatherPreviousMillis);
Serial.print((tw - (CurrentMillis - WeatherPreviousMillis)) / 60000); // Количество оставшихся минут до получения погоды с сайта openweather.com
Serial.println(" m. - estimated time to get data from openweather.com");
if (CurrentMillis - WeatherPreviousMillis > tw) {
WeatherPreviousMillis = CurrentMillis;
Serial.println(WeatherPreviousMillis);
requestURL(hostDomain, hostPort);
parseJSON(line);
Serial.println("Weather is updated on openweather.com");
}
//Отправка данных на народный мониторинг и получение данных о курсе биткоина
int tn = 600000;
Serial.println(CurrentMillis - NarmonPreviousMillis);
Serial.print((tn - (CurrentMillis - NarmonPreviousMillis)) / 60000);
Serial.println(" m. - estimated time to send data on narodmon.ru");
if (CurrentMillis - NarmonPreviousMillis > tn) {
NarmonPreviousMillis = CurrentMillis;
Serial.println(NarmonPreviousMillis);
Bitcoin();
delay(500);
SendMon();
delay(500);
Serial.println("Weather is loaded to narmon.ru");
Serial.println("Curs of Bitcoin is updated");
}
Serial.println();
Serial.println("-------------");
Serial.print("Time: ");
printLocalTime();
delay(500);
Serial.println();
Serial.print("City: ");
Serial.println(name1);
Serial.print("Temp outdoor: ");
Serial.print(temp);
Serial.println(" C");
Serial.print("Humidity outdoor: ");
Serial.print(humidity);
Serial.println(" %");
Serial.print("Pressure outdoor: ");
Serial.print(pressure / 1.333);
Serial.println(" mmHg");
Serial.print("Wind outdoor: ");
Serial.print(wind);
Serial.println(" Km/h");
//parseJSON(line);
// Serial.print(line);
Serial.println();
Serial.print("Temp in home: ");
Serial.print(bme.readTemperature());
Serial.println(" C");
delay(500);
Serial.print("Humidity in home: ");
Serial.print(bme.readHumidity());
Serial.println(" %");
delay(500);
Serial.print("Pressure in home: ");
Serial.print(bme.seaLevelForAltitude(138, bme.readPressure() / 100.0F ) / 1.333);
Serial.println(" mmHg");
delay(500);
Serial.print("Bitcoin curs: ");
Serial.print(bpi_USD_rate);
Serial.println(" USD");
delay(500);
Serial.print("Curs of USD: ");
Serial.print(USD_rate * 10000);
Serial.println(" BEL RUB");
int T = round (bme.readTemperature());
delay(500);
int P = round (bme.seaLevelForAltitude(138, bme.readPressure() / 100.0F ) / 1.333);
delay(500);
int H = round (bme.readHumidity());
delay(500);
lcd.clear();
printLocalTimeDateLcd();
printLocalTimeTimeLcd();
lcd.setCursor(0, 0);
lcd.print("T=");
lcd.print(T); // Вывод округлённого значения температуры с датчика
lcd.setCursor(4, 0);
lcd.print("(");
lcd.print(round (temp));
lcd.print(")");
//Вывод давления с датчика BMP180 на дисплей
lcd.setCursor(0, 1);
lcd.print("P=");
//Датчик выводит температуру в дробных числах в гидропаскалях, поэтому преобразуем их в целые значения миллиметров ртутного столба
// word pbmp = Pressurebmp / 133.3;
lcd.print(P);
lcd.setCursor(5, 1);
lcd.print("(");
lcd.print(round (pressure / 1.333));
lcd.print(")");
//Вывод влажности с датчика DHT11 на дисплей
lcd.setCursor(0, 2);
lcd.print("H=");
lcd.print(H);
lcd.setCursor(4, 2);
lcd.print("(");
lcd.print(round (humidity));
lcd.print(")");
lcd.setCursor(0, 3);
lcd.print("W=");
lcd.print(round (wind));
lcd.print("Km/h");
lcd.setCursor(10, 2);
lcd.print("USD=");
lcd.print(round (USD_rate * 10000));
lcd.setCursor(10, 3);
lcd.print("BTC=");
lcd.print((int)bpi_USD_rate);
delay(60000);
}