Датчик, смс и реле

Тема в разделе "Arduino & Shields", создана пользователем re_mast, 5 янв 2020.

Метки:
  1. re_mast

    re_mast Нуб

    Здравствуйте, есть датчик mq-2 для дыма и газа. Если превышает заданное значение то отправляет смс типа "газ" и потом включается реле, допустим на 15 сек. Как сделать так чтобы смс не отправлялись каждый цикл в loop() при учёте того что газ регистрируется? delay - на 15 секунд тема, но останова идёт всего микроконтроллера да и смс получать каждые 15 секунд не то...
     
  2. Daniil

    Daniil Гуру

    Засекать время. См. millis или rtc
     
  3. DIYMan

    DIYMan Guest

    Посылать смс однократно по превышению порога. Т.е., как только превысился порог - смотрим, не отправляли смс? Нет? Отправляем, выставляем флаг, что отправили. Как порог снизился до безопасного - сбрасываем флаг. Примерно так, псевдокод:

    Код (C++):
    bool flag = false;
    int border = 500;

    void loop()
    {
        int value = analogRead(SENSOR_PIN);

        if(value <= border)
        {
            flag = false;
        }
        else
        {
            if(!flag)
            {
                flag = true;
                sendSMS("АХТУНГ, ПАРТИЗАНЕН!");
            }
        }
     
    }
    Но! Надо, по хорошему, ещё обрабатывать нюанс, когда значение пляшет на границе. Это тоже просто, в качестве домашнего задания, так сказать ;)
     
    Airbus нравится это.
  4. re_mast

    re_mast Нуб

    millis я смотрел для меня это довольно сложно. Чесно.
    Я тоже думал про флаги. Допустим я в отъезде, а смс отправится только раз при срабатывании. Включится реле на 15 сек(delay на 15000мсек) и приостановит весь код и потом по кругу будет луп() идти без обнаружения. Случился пожар или протечка газа - спасайся кто может :)
    Можно какнибудь включить реле допустим на 15 сек, отправить смс а потом не отправлять смс в течении часа? Или только переменными и вычислением времени?
     
  5. DIYMan

    DIYMan Guest

    без delay - да, только так.
     
  6. parovoZZ

    parovoZZ Гуру

    В смысле сложно? Вычесть одно из другого, результат запомнить в переменной? Это ж алгебра из пятого класса.
     
  7. re_mast

    re_mast Нуб

    В теории если датчик газа сработал ты либо приезжаешь и выясняешь что не так, либо вызываешь газовиков и пожарных все дела и всё.
    Как думаете такой подход норм (если не заморачиваться)? Типа сработал раз датчик и сам думай что делать?
     
  8. re_mast

    re_mast Нуб

    Крутится в голове а сам допереть не могу. Допустим time=0. Если time<millis тогда time=time+millis+час; иначе не выполняем код(не отправляем смс). Я читал что millis сбрасываются по переполнению что около 50 дней. И получается +обработчик сбрасывания millis
     
  9. DIYMan

    DIYMan Guest

    Боже, опять про переполнение millis :( Интервалы для беззнаковых чисел - надо рассчитывать правильно, и нет проблем с переполнением. Вот - как правильно:

    Код (C++):
    unsigned long lastMillis = millis();

    ...

    if(millis() - lastMillis >= interval)
    {
    // интервал прошёл.
    }
    Всё остальное - неправильно.
     
    DetSimen нравится это.
  10. re_mast

    re_mast Нуб

    Воо благодарю. Попробую. Нублю, что поделать. Прост писали везде переполнение, обнуление и т.п. ...
     
  11. DIYMan

    DIYMan Guest

    Кто писал? Гайвер ненаглядный, что ли? Не читайте советских газет, как говорится.
     
    vvr нравится это.
  12. re_mast

    re_mast Нуб

    http://arduino.ru/Reference/Millis
     
  13. DetSimen

    DetSimen Guest

    дак у тебя часы тоже сбрасываются на ноль раз в сутки, ты тоже не сможешь узнать, скока времени прошло между 23-00 и часом ночи?
     
    DIYMan нравится это.
  14. DetSimen

    DetSimen Guest

    А минуты переполняются и того чаще. :)
     
  15. SergeiL

    SergeiL Оракул Модератор

    Со временем даже посложнее, чем с миллис :)
     
    DIYMan нравится это.
  16. Vovka

    Vovka Гик

    Вот любители millis()... прерывания по таймеру не проще использовать? ;)
     
  17. DIYMan

    DIYMan Guest

    Понимаете, какая штука: по совершенно непротиворечивым и правильным вводным - люди порой умудряются делать неправильные выводы. Я вам больше скажу - переполняются все типы данных. Но это не значит, что в этом какая-то проблема, просто надо понимать, как это дело устроено, и каким образом с этим жить и работать. Вот смотрите (там есть кнопка "выполнить", гляньте на результат: http://cpp.sh/9frsq
    Код (C++):
    // Example program
    #include <iostream>
    #include <string>
    using namespace std;

    int main()
    {
      uint8_t byte1 = 255;
      printf("byte1 = %hhu\n",byte1);

      byte1 += 2;
      printf("byte1+2 = %hhu\n",byte1);

      uint8_t byte2 = 255;
      printf("byte2 = %hhu\n",byte2);
      printf("%hhu - %hhu = %hhu\n",byte1, byte2, (uint8_t)byte1 - byte2);
    }
     
    Как видите, в случае беззнакового целого размерностью 1 байт (максимальное значение 0xFF, или 255 в десятичной - если к 255 прибавить единичку - получится нолик, переполнение. А если от единички отнять 255 (то есть от меньшего большее) - получится двоечка, переполнение не страшно, т.к. беззнаковая арифметика. Представьте себе все возможные значения такого типа переменных - как замкнутое кольцо, а интервал между ними - просто расстояние между любыми двумя числами в этом кольце. Но - только разница, если будете к одному числу прибавлять, чтобы пытаться проверить на достижение интервала, то - будет проблема. Потому что можете перешагнуть через переполнение, в результате чего значение после прибавления станет меньше, чем до него. В этом ничего страшного, само по себе - нету, проблема не в этом, главное - понимать, что проверять на интервал между двумя беззнаковыми числами надо только вычитанием одного из другого.
     
    DetSimen нравится это.