Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <SoftwareSerial.h> // Библиотека програмной реализации обмена по UART-протоколу
- SoftwareSerial SIM800(8, 9); // RX, TX
- // Назначаем переменные для управления мотором.
- const int stepPin = 5;
- const int dirPin = 4;
- const int enPin = 7;
- int count = 0;
- // Переменные для ручного управления
- const int m_forward = 13;
- const int m_backward = 12;
- // Переменные для датчиков-кнопок.
- const int ifSensorOpen = 11;
- const int ifSensorClosed = 10;
- // LOCK HUIOK.
- String _mainstatus = "unlock";
- //Датчик дождя
- const int rainsensor = 3;
- String sensorStop = ""; // Датчик сработал.
- String _status = "";
- String _phone = "";
- String _response = ""; // Переменная для хранения ответа модуля
- long lastUpdate = millis(); // Время последнего обновления
- long updatePeriod = 120000; // Проверять каждые 2 минуты
- String phones = "+37369777175, +37360450504, +37369277497"; // Белый список телефонов
- void setup() {
- // Датчики препятствия открытия
- pinMode(ifSensorOpen, INPUT_PULLUP);
- pinMode(ifSensorClosed, INPUT_PULLUP);
- //Датчик дождя
- pinMode(rainsensor, INPUT);
- // Ручное управление
- // Переменные для ручного управления
- pinMode(m_forward, INPUT_PULLUP); // Открываем крышу
- pinMode(m_backward, INPUT_PULLUP); // Закрываем крышу
- //Назначаем порты для двигателя
- pinMode(stepPin, OUTPUT);
- pinMode(dirPin, OUTPUT);
- pinMode(enPin, OUTPUT);
- digitalWrite(enPin, LOW);
- Serial.begin(9600); // Скорость обмена данными с компьютером
- SIM800.begin(9600); // Скорость обмена данными с модемом
- Serial.println("Start!");
- sendATCommand("AT", true); // Отправили AT для настройки скорости обмена данными
- sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все SMS, чтобы не забивать память
- // Команды настройки модема при каждом запуске
- _response = sendATCommand("AT+CLIP=1", true); // Включаем АОН
- //_response = sendATCommand("AT+DDET=1", true); // Включаем DTMF
- sendATCommand("AT+CMGF=1;&W", true); // Включаем текстовый режима SMS (Text mode) и сразу сохраняем значение (AT&W)!
- lastUpdate = millis(); // Обнуляем таймер
- }
- 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); // Дублируем ответ в монитор порта
- }
- return _resp; // Возвращаем результат. Пусто, если проблема
- }
- String waitResponse() { // Функция ожидания ответа и возврата полученного результата
- String _resp = ""; // Переменная для хранения результата
- long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд)
- while (!SIM800.available() && millis() < _timeout) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то...
- if (SIM800.available()) { // Если есть, что считывать...
- _resp = SIM800.readString(); // ... считываем и запоминаем
- }
- else { // Если пришел таймаут, то...
- // Serial.println("Timeout..."); // ... оповещаем об этом и...
- }
- return _resp; // ... возвращаем результат. Пусто, если проблема
- }
- bool hasmsg = false; // Флаг наличия сообщений к удалению
- // НАЧАЛО ЛУПА. НАЧАЛО ЛУПА. НАЧАЛО ЛУПА. НАЧАЛО ЛУПА. НАЧАЛО ЛУПА. НАЧАЛО ЛУПА. НАЧАЛО ЛУПА. НАЧАЛО ЛУПА.
- void loop() {
- if (!digitalRead(ifSensorOpen) == 0 && _mainstatus != "lock") {
- if (!digitalRead(m_forward) == 1) {
- digitalWrite(dirPin, LOW); // Enables the motor to move in a particular direction
- Serial.println("Manual Forward");
- for (int x = 0; x < 70; x++) {
- digitalWrite(stepPin, HIGH);
- delayMicroseconds(210);
- digitalWrite(stepPin, LOW);
- delayMicroseconds(210);
- if (!digitalRead(ifSensorOpen) == 1) {
- sendSMS("+37369777175","Roof is opened by Button!");
- sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все SMS, чтобы не забивать память
- break;
- }
- }
- }
- }
- if (!digitalRead(ifSensorClosed) == 0 && _mainstatus != "lock") {
- if (!digitalRead(m_backward) == 1) {
- // Serial.println("Manual Backward");
- digitalWrite(dirPin, HIGH); // Enables the motor to move in a particular direction
- for (int x = 0; x < 70; x++) {
- digitalWrite(stepPin, HIGH);
- delayMicroseconds(210);
- digitalWrite(stepPin, LOW);
- delayMicroseconds(210);
- }
- }
- }
- if ((_status == "openroof" || _status == "closeroof") && _mainstatus != "lock") {
- if (sensorStop == "true") {
- sensorStop = "false";
- // if (_status == "closeroof") digitalWrite(dirPin, LOW);
- // else digitalWrite(dirPin, HIGH); // Enables the motor to move in a particular direction
- // Makes 200 pulses for making one full cycle rotation
- _status = "";
- _phone = "";
- } else {
- setLedState(_status, _phone);
- }
- } else if (lastUpdate + updatePeriod < millis() && (!digitalRead(m_forward) == 0 || !digitalRead(m_backward) == 0 )) { // Пора проверить наличие новых сообщений
- do {
- if (!digitalRead(rainsensor) == 1) {
- sendSMS("+37369777175"," RAIN! Check the CAMERA or CLOSE the roof!");
- }
- _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();
- int i = 0; // Объявляем счетчик попыток
- do {
- i++; // Увеличиваем счетчик
- _response = sendATCommand("AT+CMGR=" + (String)msgIndex + ",1", true); // Пробуем получить текст SMS по индексу
- Serial.println("readsms");
- _response.trim(); // Убираем пробелы в начале/конце
- if (_response.endsWith("OK")) { // Если ответ заканчивается на "ОК"
- if (!hasmsg) hasmsg = true; // Ставим флаг наличия сообщений для удаления
- sendATCommand("AT+CMGR=" + (String)msgIndex, true); // Делаем сообщение прочитанным
- sendATCommand("\n", true); // Перестраховка - вывод новой строки
- parseSMS(_response); // Отправляем текст сообщения на обработку
- // Serial.println(_response);
- break; // Выход из do{}
- }
- else { // Если сообщение не заканчивается на OK
- // Serial.println ("Error answer"); // Какая-то ошибка
- 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()) { // Если модем, что-то отправил...
- _response = waitResponse(); // Получаем ответ от модема для анализа
- _response.trim(); // Убираем лишние пробелы в начале и конце
- Serial.println(_response); // Если нужно выводим в монитор порта
- if (_response.indexOf("+CMTI:") > -1) { // Пришло сообщение об отправке SMS
- lastUpdate = millis() - updatePeriod; // Теперь нет необходимости обрабатываеть SMS здесь, достаточно просто
- // сбросить счетчик автопроверки и в следующем цикле все будет обработано
- }
- }
- if (Serial.available()) { // Ожидаем команды по Serial...
- SIM800.write(Serial.read()); // ...и отправляем полученную команду модему
- };
- }
- 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) { // Если телефон в белом списке, то...
- _status = msgbody;
- _phone = msgphone;
- setLedState(msgbody, msgphone); // ...выполняем команду
- }
- else {
- Serial.println("Unknown phonenumber");
- }
- }
- void setLedState (String result, String phone) {
- bool correct = false; // Для оптимизации кода, переменная корректности команды
- String msgToSend = "";
- if (result == "openroof") {
- if ( _mainstatus == "lock") {
- sendSMS("+37369777175","Roof is LOCKED! Send \"unlock\" to unlock");
- } else {
- Serial.println("roof is opening");
- digitalWrite(dirPin, HIGH); // Enables the motor to move in a particular direction
- if (count >= 13){
- sensorStop = "true";
- count = 0;
- sendSMS("+37369777175","Roof is opened by COUNTER!");
- sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все SMS, чтобы не забивать память
- } else {
- // Makes 200 pulses for making one full cycle rotation
- for (int x = 0; x < 25400; x++) {
- digitalWrite(stepPin, HIGH);
- delayMicroseconds(225);
- digitalWrite(stepPin, LOW);
- delayMicroseconds(225);
- if (!digitalRead(ifSensorClosed) == 1) {
- sensorStop = "true";
- Serial.println("Break Done");
- sendSMS("+37369777175","Roof is opened by BUTTON!");
- sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все SMS, чтобы не забивать память
- count = 0;
- break;
- }
- }
- int x = 0;
- count++;
- Serial.print("counter: ");
- Serial.println(count);
- }
- correct = true;
- }
- } else if (result == "closeroof") {
- if ( _mainstatus == "lock") {
- sendSMS("+37369777175","Roof is LOCKED! Send \"unlock\" to unlock");
- } else {
- digitalWrite(dirPin, LOW); // Enables the motor to move in a particular direction
- if (count >= 13){
- sensorStop = "true";
- count = 0;
- sendSMS("+37369777175","Roof is closed by COUNTER!");
- sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все SMS, чтобы не забивать память
- } else {
- // Makes 200 pulses for making one full cycle rotation
- for (int x = 0; x < 25400; x++) {
- digitalWrite(stepPin, HIGH);
- delayMicroseconds(225);
- digitalWrite(stepPin, LOW);
- delayMicroseconds(225);
- if (!digitalRead(ifSensorOpen) == 1) {
- sensorStop = "true";
- Serial.println("Break Done");
- sendSMS("+37369777175","Roof is closed by BUTTON!");
- sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все SMS, чтобы не забивать память
- count = 0;
- break;
- }
- }
- int x = 0;
- count++;
- Serial.print("counter: ");
- Serial.println(count);
- }
- correct = true; // Флаг корректности команды
- }
- }
- else if (result == "unlock") {
- _mainstatus = "unlock";
- sendSMS("+37369777175","Roof is UNLOCKED");
- sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все SMS, чтобы не забивать память
- }
- if (!correct) {
- msgToSend = "Incorrect command: " + result; // Статус исполнения
- }
- Serial.println(msgToSend); // Выводим результат в терминал
- }
- void sendSMS(String phone, String message)
- {
- sendATCommand("AT+CMGS=\"" + phone + "\"", true); // Переходим в режим ввода текстового сообщения
- sendATCommand(message + "\r\n" + (String)((char)26), true); // После текста отправляем перенос строки и Ctrl+Z
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement