#include <DHT11.h>
#include "SoftwareSerial.h"
#include <OneWire.h>
#define POWER_MODE 0
OneWire sensDs (A0);
DHT11 dht11(15);
SoftwareSerial SIM800(2, 3); //программные RX, TX для связи с модулем SIM800L
unsigned long tpr1, tpr2, tpr4, tdi, ttemp, tsim, timeout, talt, talv, lastUpdate;// Перемен. для хранения точки отсчета для таймеров
int j = 0, k = 0, x2 = 20,wt = 1,wv = 1, t_1 = 0, humidity = 0,temperature = 0, p8 = 11;
//String _response = ""; // Переменная для хранения ответа модуля
String phones = "+79775645109, +79773874353"; //Список разрешенных номеров
//номера вписываются в международном формате начиная с +
String waitResponse() { // Функция ожидания ответа и возврата полученного результата
String _resp = ""; // Переменная для хранения результата
timeout = millis(); // Переменная для отслеживания тайм аута (10 секунд)
while (!SIM800.available() && millis() - timeout < 10000) {};// Ждем ответа 10 секунд, если пришел ответ или наступил тайм аут, то...
if (SIM800.available()) { // Если есть, что считывать
_resp = SIM800.readString(); //считываем и запоминаем
} else { // Если пришел тайм аут, то
Serial.println("Timeout..."); //оповещаем об этом и
} return _resp; //возвращаем результат. Пусто, если проблема
}
String sendATCommand(String cmd, bool waiting) {
String _resp = ""; // Переменная для хранения результата
Serial.println(cmd); // Дублируем команду в монитор порта
SIM800.println(cmd); // Отправляем команду модулю
if (waiting) { // Если необходимо дождаться ответа
_resp = waitResponse(); // ждем, когда будет передан ответ
// Если Echo Mode выключен (ATE0), то эти 3 строки можно за комментировать
if (_resp.startsWith(cmd)) { // Убираем из ответа дублирующую команду
_resp = _resp.substring(_resp.indexOf("\r", cmd.length()) + 2);
}
Serial.println(_resp); // Дублируем ответ в Serial
} return _resp; // Возвращаем результат. Пусто, если проблема
}
void parseSMS(String msg) { // Парсим SMS
String msgheader = "";
String msgbody = "";
String msgphone = "";
msg = msg.substring(msg.indexOf("+CMGR: "));
msgheader = msg.substring(0, msg.indexOf("\r")); // Выдергиваем телефон
msgbody = msg.substring(msgheader.length() + 2);
msgbody = msgbody.substring(0, msgbody.lastIndexOf("OK"));// Выдергиваем текст SMS
msgbody.trim();
int firstIndex = msgheader.indexOf("\",\"") + 3;
int secondIndex = msgheader.indexOf("\",\"", firstIndex);
msgphone = msgheader.substring(firstIndex, secondIndex);
Serial.println("Phone: " + msgphone); // Выводим номер телефона
Serial.println("Message: " + msgbody); // Выводим текст SMS
if (msgphone.length() > 6 && phones.indexOf(msgphone) > -1) { // Если телефон в белом списке, то
if (msgbody == "Pr0") {
j = 0;
digitalWrite(12, HIGH);//программа 0
}
if (msgbody == "Pr1") {
j = 1;
digitalWrite(12, HIGH);//программа 1
}
if (msgbody == "Pr2") {
j = 2;
digitalWrite(12, HIGH);//программа 2
}
if (msgbody == "Pr3") {
j = 3;//программа 3
}
if (msgbody == "Pr20") {
j = 20;
digitalWrite(12, HIGH);//программа 4
}
if (msgbody == "Ktr") {
k = 1;
} //запрос данных котла
if (msgbody == "Klx2+") {
x2 = x2 + 3; //повышение заданной температуры на 3 градуса
}
if (msgbody == "Klx2-") {
x2 = x2 - 3; //понижение заданной температуры на 3 градуса
}
if (msgbody == "Alt-of") {
wt = 0; //отключение оповещения аварии по температуре
}
if (msgbody == "Alt-on") {
wt = 1; //включение оповещения аварии по температуре
}
if (msgbody == "Alv-of") {
wv = 0; //отключение оповещения аварии по напряжению
}
if (msgbody == "Alv-on") {
wv = 1; //включение оповещения аварии по напряжению
}
} else {
Serial.println("Unknown phonenumber");
sendATCommand("AT+CMGDA=\"DEL ALL\"", true);
}
}
void setup() {
pinMode(12, OUTPUT);
pinMode(p8, OUTPUT);
digitalWrite(12, HIGH);
digitalWrite(p8, LOW);
pinMode(7, INPUT);
Serial.begin(9600); // Скорость обмена данными с компьютером
SIM800.begin(9600); // Скорость обмена данными с модемом
Serial.println("Start!");
// analogReference(INTERNAL);
sendATCommand("AT", true); // Отправили AT для настройки скорости обмена данными
sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все SMS, чтобы не забивать память
sendATCommand("AT+CMGF=1;&W", true); // Включаем текстовый режима SMS (Text mode) и сразу сохраняем значение (AT&W)!
lastUpdate = millis(); // Обнуляем таймер
}
bool hasmsg = false; // Флаг наличия сообщений к удалению
void loop() {
int sensorVal = digitalRead(7);
int rele=0, v = 0, msgphone = 0;
byte bufData[9]; // буфер данных
if (sensorVal == HIGH) {
v = 220; //проверка наличия питания
} else {
v = 0;
}
if (digitalRead(12) == LOW) {//проверка состояния реле
rele = 1;
} else {
rele = 0;
}
if (millis() - ttemp > 44000) {
ttemp = millis(); //обновление данных датчика температуры теплоносителя
sensDs.reset(); // сброс шины
sensDs.write(0xCC, POWER_MODE); // пропуск ROM
sensDs.write(0x44, POWER_MODE); // инициализация измерения
delay(6000); // пауза 0,9 сек
sensDs.reset(); // сброс шины
sensDs.write(0xCC, POWER_MODE); // пропуск ROM
sensDs.write(0xBE, POWER_MODE); // команда чтения памяти датчика
sensDs.read_bytes(bufData, 9); // чтение памяти датчика, 9 байтов
if ( OneWire::crc8(bufData, 8) == bufData[8] ) { // проверка CRC
// данные правильные
t_1= ((int)bufData[0] | (((int)bufData[1]) << 8)) * 0.0625 + 0.03125;
}
else {
// ошибка CRC, отображается ----
}
temperature = dht11.readTemperature();//обновление данных датчика температуры и влажности в помещении
humidity = dht11.readHumidity();
Serial.print("T1 = "); Serial.print(t_1); Serial.print("*C, ");
Serial.print("T2 = "); Serial.print(temperature); Serial.print("*C, ");
Serial.print(humidity); Serial.println("%");
}
// String _response = ""; // Переменная для хранения ответа модуля
if (millis()- lastUpdate > 60000 ) { // Пора проверить наличие новых сообщений
String _response = ""; // Переменная для хранения ответа модуля
do {
_response = sendATCommand("AT+CMGL=\"REC UNREAD\",1", true); // Отправляем запрос чтения непрочитанных сообщений
if (_response.indexOf("+CMGL: ") > -1) { // Если есть хоть одно, получаем его индекс
int msgIndex = _response.substring( _response.indexOf ("+CMGL: ") + 7, _response.indexOf("\"REC UNREAD\"", _response.indexOf("+CMGL: ")) - 1).toInt();
char i = 0; // Объявляем счетчик попыток
do {
i++; // Увеличиваем счетчик
_response = sendATCommand("AT+CMGR=" + (String)msgIndex + ",1", true); // Пробуем получить текст SMS по индексу
_response.trim(); // Убираем пробелы в начале/конце
if (_response.endsWith("OK")) { // Если ответ заканчивается на "ОК"
if (!hasmsg) hasmsg = true; // Ставим флаг наличия сообщений для удаления
sendATCommand("AT+CMGR=" + (String)msgIndex, true); // Делаем сообщение прочитанным
sendATCommand("\n", true); // Перестраховка - вывод новой строки
parseSMS(_response); // Отправляем текст сообщения на обработку
break; // Выход из do
} else { // Если сообщение не заканчивается на OK
Serial.println ("Error"); //ошибка
sendATCommand("\n", true); // Отправляем новую строку и повторяем попытку
}
}
while (i < 10); break;
} else {
lastUpdate = millis(); // Обнуляем таймер
if (hasmsg) {
sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все прочитанные сообщения
hasmsg = false;
} break;
}
} while (1);
}
if (SIM800.available()) { // Если модем, что-то отправил
String _response = ""; // Переменная для хранения ответа модуля
_response = waitResponse(); // Получаем ответ от модема для анализа
_response.trim(); // Убираем лишние пробелы в начале и конце
Serial.println(_response); // Если нужно выводим в монитор порта
if (_response.indexOf("+CMTI:") > -1) { // Пришло сообщение об отправке SMS
lastUpdate = millis(); // Теперь нет необходимости обрабатывать SMS здесь, достаточно просто сбросить счетчик авто проверки, и в следующем цикле все будет обработано
}
}
if (Serial.available()) { // Ожидаем команды по Serial
SIM800.write(Serial.read()); //и отправляем полученную команду модему
};
if (j == 0) { //Программа 0
digitalWrite(p8, HIGH);
} else {
digitalWrite(p8, LOW);
}
if (j == 1) { //Программа 1
if (millis() - tpr1 > 12600000) {
tpr1 = millis(); tpr2 = millis();
digitalWrite(12, LOW);
}
if (millis() - tpr2 > 1800000) {
digitalWrite(12, HIGH); //описание работы реле по программе 1
}
if (millis() - tdi > 3000) {
tdi = millis();
digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); //описание мерцания диода 1 раз
}
}
if (j == 2) { //Программа 2
if (millis() - tpr1 > 23400000) {
tpr1 = millis(); tpr2 = millis(); digitalWrite(12, LOW);
}
if (millis() - tpr2 > 1800000) {
digitalWrite(12,HIGH); //описание работы реле по программе 2
}
if (millis() - tdi > 3000) {
tdi = millis();
digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); delay(300);
digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); //описание мерцания диода 2 раза
}
}
if (j == 3) {
digitalWrite(12, LOW); //описание работы реле по программе 3
if (millis() - tdi > 3000) {
tdi = millis();
digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); delay(300);
digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); delay(300);
digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); //описание мерцания диода 3 раза
}
}
if (j == 20) {
if (temperature <= x2) {
digitalWrite(12, LOW);
}
if (temperature > x2) {
digitalWrite(12, HIGH); //описание работы реле по программе 4
}
if (millis() - tdi > 3000) {
tdi = millis();
digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); delay(300);
digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); delay(300);
digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); delay(300);
digitalWrite(p8, HIGH); delay(100); digitalWrite(p8, LOW); //описание мерцания диода 4 раза
}
}
if (millis() - tsim > 3600000) {
tsim = millis();
SIM800.println( "AT+CPOWD=1"); //програмная перезагрузка сим модуля на случай сбоя соединения
}
if (k == 1) {
SIM800.println( "AT+CMGS=\"+79775645109\""); //номер на который будет приходить SMS отчет
delay(3000); //номер вписывается в международном формате начиная с +
SIM800.print("T1="); //описание содержания смс с данными устройства
delay(300); SIM800.print(t_1);
delay(300); SIM800.print("*C, T2=");
delay(300); SIM800.print(temperature);
delay(300); SIM800.print("*C, T2-VL=");
delay(300); SIM800.print(humidity);
delay(300); SIM800.print("% Pr="); delay(300); SIM800.print(j);
delay(300); SIM800.print(" t=");
delay(300); SIM800.print(x2);
delay(300); SIM800.print(" Set=");
delay(300); SIM800.print(v);
delay(300); SIM800.print("volt");
delay(300); SIM800.print("; Al.t=");
delay(300); SIM800.print(wt);
delay(300); SIM800.print("; Al.v=");
delay(300); SIM800.print(wv);
delay(300); SIM800.print("; Rele=");
delay(300); SIM800.print(rele);
delay(300); SIM800.print((char)26);//команда для отправки SMS
delay(300); Serial.println("SMS send finish");
} k = 0;
if ((millis() - talt > 1800000)&&(t_1<=5)&&(wt == 1)) {//проверка необходимости отправить смс об аварии по температуре теплоносителя
talt = millis();
delay(300);
SIM800.println( "AT+CMGS=\"+79775645109\""); //номер на который будет приходить SMS отчет
delay(3000);SIM800.print("T1=");
delay(300); SIM800.print(t_1);
delay(300); SIM800.print("ALARM");
delay(300); SIM800.print((char)26);//команда для отправки SMS
delay(300); Serial.println("SMS send finish");
}
if ((millis() - talv > 1800000)&&(sensorVal == LOW)&&(wv == 1)) { //проверка необходимости отправить смс об аварии по температуре напряжения питания
talv = millis();
delay(300);
SIM800.println( "AT+CMGS=\"+79775645109\""); //номер на который будет приходить SMS отчет
delay(300); SIM800.print("Set=ALARM");
delay(300); SIM800.print((char)26);//команда для отправки SMS
delay(300); Serial.println("SMS send finish");
}
}