Ожидание выключения реле после смс запроса

Тема в разделе "Arduino & Shields", создана пользователем overdast, 11 янв 2023.

Метки:
  1. overdast

    overdast Нуб

    Код (C++):
    #include "TM1637.h"
    #include "DHT.h"
    #include <Wire.h>
    #include <SoftwareSerial.h>

    #define Rele 10  // Пин на реле
    #define Rele2 11
    #define CLK 12
    #define DIO 13
    #define pinPower A0   // Пин датчика напряжения
    #define DHTPin A1     // Пин датчика DHT22
    #define pinSensor A5  // Пин датчика влажности почвы HM-390

    #define pinSensor_MIN 230
    #define pinSensor_MAX 600
    #define INTERVAL (10000 * 3)
    #define INTERVAL2 (70000 * 8)
    #define DHTTYPE DHT22

    String phoneNumber = ("+7хххххххххххх");

    int analogInput = A0;
    float vout = 0.0;
    float vin = 0.0;
    float R1 = 30000.0;
    float R2 = 7500.0;
    int value = 0;

    unsigned int humidity = 0;

    float waitTime = 0;  // отсчёт времени
    float waitTime2 = 0;
    float lcdTime = 0;  // отсчёт времени
    static bool PolifConch = true;

    char incomingByte;
    String inputString;

    float t;  // Температура
    float h;  // Влажность воздуха
    float p;  // Влажность почвы
    float v;

    int Temperature = 0;
    int Humidity = 0;
    int valueSensor = 0;
    int powSensor = 0;

    bool tempVlaj = false;   // флаг вывода на экран т/в
    bool poliv = false;      // флаг полива
    bool smsOtchet = false;  // флаг для отправки смс по окончанию ролива

    SoftwareSerial mySerial(7, 8);  // пины RX:TX
    TM1637 tm1637(CLK, DIO);        // Дисплей HW-069
    DHT dht(DHTPin, DHTTYPE);

    void setup() {
      pinMode(Rele2, OUTPUT);
      digitalWrite(Rele2, HIGH);
      pinMode(Rele, OUTPUT);
      digitalWrite(Rele, HIGH);
      delay(100);
      pinMode(pinPower, INPUT);
      delay(500);
      pinMode(9, OUTPUT);  // Атозапуск SIM900 при первом всключении
      digitalWrite(9, LOW);
      delay(1000);
      digitalWrite(9, HIGH);
      delay(2000);
      digitalWrite(9, LOW);
      delay(3000);

      Serial.begin(9600);
      //delay(1000);
      mySerial.begin(9600);

      while (!mySerial.available()) {     // Зацикливаем и ждем инициализацию SIM900
        mySerial.println("AT");           // Отправка команды AT
        delay(500);                       // Пауза
        Serial.println("Connecting...");  // Печатаем текст
      }
      Serial.println("Connected!");           // Печатаем текст
      mySerial.println("AT+CMGF=1");          // Отправка команды AT+CMGF=1
      delay(500);                             // Пауза
      mySerial.println("AT+CNMI=1,2,0,0,0");  // Отправка команды AT+CNMI=1,2,0,0,0
      delay(500);                             // Пауза
      mySerial.println("AT+CMGL=\"REC UNREAD\"");

      delay(1000);

      tm1637.init();

      dht.begin();  // запускаем датчик DHT22
      tm1637.set(BRIGHTEST);
    }

    void loop() {
      int Temperature = dht.readTemperature();
      int Humidity = dht.readHumidity();
      int valueSensor = analogRead(pinSensor);
      int powSensor = analogRead(pinPower);


      if (isnan(Humidity) || isnan(Temperature)) {
        Serial.println(F("Oshibka DHT22"));
        // return;  //весь остальной код не будет исполняться после этого. либо в конец функции эту проверку, либо не использовать
      }

      if (mySerial.available()) {          // Проверяем, если есть доступные данные
        while (mySerial.available()) {     // Проверяем, есть ли еще данные.
          incomingByte = mySerial.read();  // Считываем байт и записываем в переменную incomingByte
          inputString += incomingByte;     // Записываем считанный байт в массив inputString
          delay(5);                        // Пауза, защита от пропусков
        }

        //delay(10);                    // Пауза тут вообще не нужна
        Serial.println(inputString);  // Отправка в "Мониторинг порта" считанные данные
        inputString.toUpperCase();    // Меняем все буквы на заглавные

        if (inputString.indexOf("DATA") > -1) {
          p = analogRead(pinSensor);
          t = dht.readTemperature();
          h = dht.readHumidity();
          value = analogRead(pinPower);
          vout = (value * 5.0) / 1024.0;
          vin = vout / (R2 / (R1 + R2));
          v = (vin);

          sms(String("Temper: " + String(t) + " C " + " Humid: " + String(h) + " Pochva: " + String(p) + " Volt: " + String(v)), phoneNumber);
        }

        delay(10);

        if (inputString.indexOf("POLIVON") > -1) {
          digitalWrite(Rele2, LOW);
          delay(1000);
          sms(String("Rele2 - PolifON"), phoneNumber);
        }

        delay(10);

        if (inputString.indexOf("POLIVOFF") > -1) {

          digitalWrite(Rele2, HIGH);
          delay(1000);
          sms(String("Rele2 - PolifOff"), phoneNumber);
        }

        delay(10);

        if (inputString.indexOf("GOLYON") > -1) {

          digitalWrite(Rele, LOW);
          delay(1000);
          sms(String("Rele1 - PolifOn1"), phoneNumber);
        }

        delay(10);

        if (inputString.indexOf("GOLYOFF") > -1) {

          digitalWrite(Rele, HIGH);
          delay(1000);
          sms(String("Rele1 - PolifOff2"), phoneNumber);
        }

        delay(50);

        if (inputString.indexOf("OK") == -1) {
          mySerial.println("AT+CMGDA=\"DEL ALL\"");
          delay(1000);
        }

        inputString = "";
      }

      Serial.println(valueSensor);
      value = analogRead(pinPower);
      vout = (value * 5.0) / 1024.0;
      vin = vout / (R2 / (R1 + R2));
      if (isnan(Humidity) || isnan(Temperature)) {
        Serial.println(F("Oshibka"));
        return;
      }

      int digitoneT = Temperature / 10;
      int digittwoT = Temperature % 10;

      int digitoneH = Humidity / 10;
      int digittwoH = Humidity % 10;

      tm1637.display(1, digitoneT);
      tm1637.display(2, digittwoT);
      tm1637.display(3, 12);

      delay(5000);

      tm1637.display(1, digitoneH);
      tm1637.display(2, digittwoH);
      tm1637.display(3, 15);

      delay(5000);

      Serial.print(F("INPUT V = "));
      Serial.println(vin, 2);
      Serial.print(F("Vlaga: "));
      Serial.print(Humidity);
      Serial.print(F(" %\t"));
      Serial.print(F("Tempera: "));
      Serial.print(Temperature);
      Serial.println(F(" °C "));

      delay(500);

      int humidityNow = analogRead(pinSensor);

      if (humidityNow != humidity) {
        humidity = humidityNow;
      }
      if ((waitTime == 0 || millis() - waitTime > INTERVAL) && humidity < pinSensor_MIN) {
        digitalWrite(Rele, LOW);
        delay(5000 * 2);
        digitalWrite(Rele, HIGH);
        waitTime = millis();
      }
    }

    void switch_Rele2() {
      inputString.toUpperCase();
      if (inputString.indexOf("POLIV1") > -1) {
        digitalWrite(Rele2, LOW);
        PolifConch = false;
        waitTime2 = millis();
      } else if (millis() - waitTime2 > INTERVAL2 && !PolifConch) {
        digitalWrite(Rele2, HIGH);
        delay(100);
        sms(String("Rele2 - PolifConch"), phoneNumber);
        PolifConch = true;
      }
    delay(100);
    }

    void sms(String text, String phone)  // Процедура Отправка SMS
    {
      Serial.println("SMS send started");
      mySerial.println("AT+CMGS=\"" + phone + "\"");
      delay(500);
      mySerial.print(text);
      delay(500);
      mySerial.print((char)26);
      delay(500);
      Serial.println("SMS send complete");
      delay(2000);
    }
    Вывел теперь вообще не реагирует на POLIV1.
     
  2. User248

    User248 Гик

    Я же не говорил вывести в отдельную функцию. Просто вывести за закрывающую скобку условия if(mySerial.available()).
    В точности, как здесь:
     
  3. overdast

    overdast Нуб

    Код (C++):
     if (inputString.indexOf("OK") == -1) {
          mySerial.println("AT+CMGDA=\"DEL ALL\"");
          delay(1000);
        }

        inputString = "";
      }

      if (inputString.indexOf("POLIV1") > -1) {
        digitalWrite(Rele2, LOW);
        PolifConch = false;
        waitTime2 = millis();
      } else if (millis() - waitTime2 > INTERVAL2 && !PolifConch) {
        digitalWrite(Rele2, HIGH);
        delay(100);
        sms(String("Rele2 - PolifConch"), phoneNumber);
        PolifConch = true;
        }


        Serial.println(valueSensor);
        value = analogRead(pinPower);
        vout = (value * 5.0) / 1024.0;
        vin = vout / (R2 / (R1 + R2));
        if (isnan(Humidity) || isnan(Temperature)) {
          Serial.println(F("Oshibka"));
          return;
        }
     
    Вывел и аналогично тишина.
     
  4. User248

    User248 Гик

    Да, действительно не заработает. Потому что строку inputString ="" нужно перенести вверх, сразу после открытия условия if (mySerial.available()). Иначе она сбрасывается раньше, чем нужно.
    Код (C++):

    if(mySerial.available()){         // Проверяем, если есть доступные данные
       inputString ="";
       while(mySerial.available()){   // Проверяем, есть ли еще данные.
          incomingByte = mySerial.read();// Считываем байт и записываем в переменную incomingByte
          inputString += incomingByte;   // Записываем считанный байт в массив inputString
          delay(5);                       // Пауза, защита от пропусков
       }
     
     
  5. overdast

    overdast Нуб

    Не все равно реле не выключает и не включает.
    СМС теперь в ответ не шлет.
     
  6. User248

    User248 Гик

    А на команды POLIVON и POLIVOFF реагирует?
     
  7. Рокки1945

    Рокки1945 Гуру

    с таким количеством делаев - вообще удивительно что работает
     
    parovoZZ нравится это.
  8. overdast

    overdast Нуб

    Работает но не отвечает в смс о включении-выключении.
     
  9. User248

    User248 Гик

    А раньше отвечал? Может из-за delay(5) начал барахлить.
    Код (C++):

    if(mySerial.available()){         // Проверяем, если есть доступные данные
       inputString ="";
       while(mySerial.available()){   // Проверяем, есть ли еще данные.
          incomingByte = mySerial.read();// Считываем байт и записываем в переменную incomingByte
          inputString += incomingByte;   // Записываем считанный байт в массив inputString
          delay(5);                       // Пауза, защита от пропусков
       }
     
     
  10. User248

    User248 Гик

    Должно работать. Может напутали чего. Попробуйте так, и номер телефона не забудьте свой поставить.
    Код (C++):

    #include "TM1637.h"
    #include "DHT.h"
    #include <Wire.h>
    #include <SoftwareSerial.h>

    #define Rele 10  // Пин на реле
    #define Rele2 11
    #define CLK 12
    #define DIO 13
    #define pinPower A0   // Пин датчика напряжения
    #define DHTPin A1     // Пин датчика DHT22
    #define pinSensor A5  // Пин датчика влажности почвы HM-390

    #define pinSensor_MIN 230
    #define pinSensor_MAX 600
    #define INTERVAL (10000 * 3)
    #define INTERVAL2 (70000 * 8)
    #define DHTTYPE DHT22

    String phoneNumber = ("+7ххххххххххх");

    int analogInput = A0;
    float vout = 0.0;
    float vin = 0.0;
    float R1 = 30000.0;
    float R2 = 7500.0;
    int value = 0;

    unsigned int humidity = 0;

    float waitTime = 0;  // отсчёт времени
    float waitTime2 = 0;
    float lcdTime = 0;  // отсчёт времени
    static bool PolifConch = true;

    char incomingByte;
    String inputString;

    float t;  // Температура
    float h;  // Влажность воздуха
    float p;  // Влажность почвы
    float v;

    int Temperature = 0;
    int Humidity = 0;
    int valueSensor = 0;
    int powSensor = 0;

    bool tempVlaj = false;   // флаг вывода на экран т/в
    bool poliv = false;      // флаг полива
    bool smsOtchet = false;  // флаг для отправки смс по окончанию ролива

    SoftwareSerial mySerial(7, 8);  // пины RX:TX
    TM1637 tm1637(CLK, DIO);        // Дисплей HW-069
    DHT dht(DHTPin, DHTTYPE);

    void setup() {
      pinMode(Rele2, OUTPUT);
      digitalWrite(Rele2, HIGH);
      pinMode(Rele, OUTPUT);
      digitalWrite(Rele, HIGH);
      delay(100);
      pinMode(pinPower, INPUT);
      delay(500);
      pinMode(9, OUTPUT);  // Атозапуск SIM900 при первом всключении
      digitalWrite(9, LOW);
      delay(1000);
      digitalWrite(9, HIGH);
      delay(2000);
      digitalWrite(9, LOW);
      delay(3000);

      Serial.begin(9600);
      //delay(1000);
      mySerial.begin(9600);

      while (!mySerial.available()) {     // Зацикливаем и ждем инициализацию SIM900
        mySerial.println("AT");           // Отправка команды AT
        delay(500);                       // Пауза
        Serial.println("Connecting...");  // Печатаем текст
      }
      Serial.println("Connected!");           // Печатаем текст
      mySerial.println("AT+CMGF=1");          // Отправка команды AT+CMGF=1
      delay(500);                             // Пауза
      mySerial.println("AT+CNMI=1,2,0,0,0");  // Отправка команды AT+CNMI=1,2,0,0,0
      delay(500);                             // Пауза
      mySerial.println("AT+CMGL=\"REC UNREAD\"");

      delay(1000);

      tm1637.init();

      dht.begin();  // запускаем датчик DHT22
      tm1637.set(BRIGHTEST);
    }

    void loop() {
      int Temperature = dht.readTemperature();
      int Humidity = dht.readHumidity();
      int valueSensor = analogRead(pinSensor);
      int powSensor = analogRead(pinPower);


      if (isnan(Humidity) || isnan(Temperature)) {
        Serial.println(F("Oshibka DHT22"));
        // return;  //весь остальной код не будет исполняться после этого. либо в конец функции эту проверку, либо не использовать
      }

      if (mySerial.available()) {  // Проверяем, если есть доступные данные
        inputString = "";
        while (mySerial.available()) {     // Проверяем, есть ли еще данные.
          incomingByte = mySerial.read();  // Считываем байт и записываем в переменную incomingByte
          inputString += incomingByte;     // Записываем считанный байт в массив inputString
          delay(5);                // Пауза, защита от пропусков
        }

        //delay(10);                    // Пауза тут вообще не нужна
        Serial.println(inputString);  // Отправка в "Мониторинг порта" считанные данные
        inputString.toUpperCase();    // Меняем все буквы на заглавные

        if (inputString.indexOf("DATA") > -1) {
          p = analogRead(pinSensor);
          t = dht.readTemperature();
          h = dht.readHumidity();
          value = analogRead(pinPower);
          vout = (value * 5.0) / 1024.0;
          vin = vout / (R2 / (R1 + R2));
          v = (vin);

          sms(String("Temper: " + String(t) + " C " + " Humid: " + String(h) + " Pochva: " + String(p) + " Volt: " + String(v)), phoneNumber);
        }

        delay(10);

        if (inputString.indexOf("POLIVON") > -1) {
          digitalWrite(Rele2, LOW);
          delay(1000);
          sms(String("Rele2 - PolifON"), phoneNumber);
        }

        delay(10);

        if (inputString.indexOf("POLIVOFF") > -1) {

          digitalWrite(Rele2, HIGH);
          delay(1000);
          sms(String("Rele2 - PolifOff"), phoneNumber);
        }

        delay(10);

        if (inputString.indexOf("GOLYON") > -1) {

          digitalWrite(Rele, LOW);
          delay(1000);
          sms(String("Rele1 - PolifOn1"), phoneNumber);
        }

        delay(10);

        if (inputString.indexOf("GOLYOFF") > -1) {

          digitalWrite(Rele, HIGH);
          delay(1000);
          sms(String("Rele1 - PolifOff2"), phoneNumber);
        }

        delay(50);

        if (inputString.indexOf("OK") == -1) {
          mySerial.println("AT+CMGDA=\"DEL ALL\"");
          delay(1000);
        }
      }

      if (inputString.indexOf("POLIV1") > -1) {
        digitalWrite(Rele2, LOW);
        PolifConch = false;
        waitTime2 = millis();
      }
      else if (millis() - waitTime2 > INTERVAL2 && !PolifConch) {
        digitalWrite(Rele2, HIGH);
        delay(1000);
        sms(String("Rele2 - PolifConch"), phoneNumber);
        PolifConch = true;
      }

      Serial.println(valueSensor);
      value = analogRead(pinPower);
      vout = (value * 5.0) / 1024.0;
      vin = vout / (R2 / (R1 + R2));
      if (isnan(Humidity) || isnan(Temperature)) {
        Serial.println(F("Oshibka"));
        return;
      }

      int digitoneT = Temperature / 10;
      int digittwoT = Temperature % 10;

      int digitoneH = Humidity / 10;
      int digittwoH = Humidity % 10;

      tm1637.display(1, digitoneT);
      tm1637.display(2, digittwoT);
      tm1637.display(3, 12);

      delay(5000);

      tm1637.display(1, digitoneH);
      tm1637.display(2, digittwoH);
      tm1637.display(3, 15);

      delay(5000);

      Serial.print(F("INPUT V = "));
      Serial.println(vin, 2);
      Serial.print(F("Vlaga: "));
      Serial.print(Humidity);
      Serial.print(F(" %\t"));
      Serial.print(F("Tempera: "));
      Serial.print(Temperature);
      Serial.println(F(" °C "));

      delay(500);

      int humidityNow = analogRead(pinSensor);

      if (humidityNow != humidity) {
        humidity = humidityNow;
      }
      if ((waitTime == 0 || millis() - waitTime > INTERVAL) && humidity < pinSensor_MIN) {
        digitalWrite(Rele, LOW);
        delay(5000 * 2);
        digitalWrite(Rele, HIGH);
        waitTime = millis();
      }
    }

    void sms(String text, String phone)  // Процедура Отправка SMS
    {
      Serial.println("SMS send started");
      mySerial.println("AT+CMGS=\"" + phone + "\"");
      delay(500);
      mySerial.print(text);
      delay(500);
      mySerial.print((char)26);
      delay(500);
      Serial.println("SMS send complete");
      delay(2000);
    }
     
     
  11. Рокки1945

    Рокки1945 Гуру

    ТС - твоя ошибка в том, что ты не подумал над тем как оно должно будет взаимодействовать (модуль сим) в паре с микроконтроллером (ардуино), а не зная микроконтроллер - ты так и будешь всегда попадать на грабли. В своё время этот путь прошёл и сделал девайс который работает 3 года без сбоя. Отлаживался в протеусе при помощи компонента КОМПИМ.
     
    parovoZZ нравится это.
  12. parovoZZ

    parovoZZ Гуру

    Тут в пору освоить конечные автоматы.
    Кучу делеев заменить на таймеры.
    Линейное программирование здесь никак не подходит.
     
  13. parovoZZ

    parovoZZ Гуру

    Ну и самый первый шаг - взять листок бумаги и нарисовать на нем алгоритм работы.
     
  14. overdast

    overdast Нуб

    Таки заработало. Проблема оказалась в том что из-за количества делеев время заданное мною не совпадает с итоговым временем.
    Я просто не дожидался ответа от ардуины и начинал копаться по новой.
    Спасибо за помощь дальше постараюсь допиливать код своими силами и избавляться от делеев.
     
  15. User248

    User248 Гик

    "Если всё работает, то ничего не трогайте." (с)
     
  16. overdast

    overdast Нуб

    это значит что можно сделать 20 минут интервала + удаление всех делеев.
     
  17. overdast

    overdast Нуб

    Совершенству нету предела.
     
  18. parovoZZ

    parovoZZ Гуру

     
    Ariadna-on-Line нравится это.