Странное поведения скетча

Тема в разделе "Arduino & Shields", создана пользователем hrustbb, 30 авг 2016.

  1. hrustbb

    hrustbb Нуб

    Я ардуинкой занимаюсь второй день, так-что, возможно, где-то ошибаюсь.
    Вообщем собрал некоторое подобие gsm сигнализации, залил скетч

    Код (C++):
    #include <SoftwareSerial.h>

    SoftwareSerial mySerial(2, 3);

    int nlg = 0; //вход с вибродатчика
    char at_ring[] = "ATD+7908*******;"; //звоним на телефон
    int off = 0;
    byte response_byte = 0;
    char response[50];
    String resp_str = "";

    void setup() {
      pinMode(13, OUTPUT);
      digitalWrite(13, LOW);

      Serial.begin(9600);
      mySerial.begin(115200);
      mySerial.println("AT");
    }

    void loop() {
      nlg = analogRead(5);

      if (off == 0) {
        if (nlg > 5) {
          //сработал вибродатчик
          digitalWrite(13, HIGH);
          mySerial.println(at_ring);//звоним на телефон
          mySerial.flush();
          //собираем строку из пришедших данных
          while (resp_str.length() < 2) {
            if (mySerial.available() > 0) {
              response_byte = mySerial.read();
              if (response_byte > 64 && response_byte < 91){
                resp_str += String(char(response_byte));
              }
            }
          }
     
          if (resp_str.compareTo("OK") == 0) {
            //команда принята
            off = 1;
            //Serial.println(resp_str);
            resp_str = "";
          }
        }
      }

      if (off == 1) {
        while (resp_str.length() < 2){
          if (mySerial.available() > 0) {
            response_byte = mySerial.read();
            if (response_byte > 64 && response_byte < 91){
              resp_str += String(char(response_byte));
            }
          }
        }
     
        if (resp_str.compareTo("OK") == 0) {
          off = 2;
          //Serial.println(resp_str);
          resp_str = "";
        }
      }

      if (off == 2) {
        while (resp_str.length() < 3){
          if (mySerial.available() > 0) {
            response_byte = mySerial.read();
            if (response_byte > 64 && response_byte < 91){
              resp_str += String(char(response_byte));
            }
          }
        }
        digitalWrite(13, LOW);
        //GSM модуль отвечает всегда по разному (NO CARSIER, NO CARRIES и т.п.)
        if (resp_str.compareTo("NOC") == 0) {
          //положил трубку
          off = 0;
          //Serial.println(resp_str);
          resp_str = "";
          //диод не гаснет
          digitalWrite(13, LOW);
        }
      }
    }
    Все вроде работает, но по замыслу, после того, как я положу трубку, должен погаснуть диод на 13 пине, а это происходит только после первого срабатывания, потом диод не гаснет, в остальном же - все как надо, звонок на сотовый отправляется и на второе, и на третье, и на последующие срабатывания вибродатчика.
    Не могу понять ЧЯДНТ?
     
    Последнее редактирование: 31 авг 2016
  2. hrustbb

    hrustbb Нуб

    Говорят что-то связано с spi и что якобы ноги 10 11 12 13 им заняты, но я то spi не использую пока
     
  3. hrustbb

    hrustbb Нуб

    Короче, помогло только это:

    Код (C++):
    void(* resetFunc) (void) = 0; // Reset MC function

    resetFunc(); //вызов
    Это наверно какие-то непонятные ардуиноглюки. Вообщем для меня ардуинка - старт в мир микроконтроллеров
     
  4. hrustbb

    hrustbb Нуб

    Ардуинки отамперки такие же глючные?
     
  5. DIYMan

    DIYMan Guest

    Даже китайские ардуинки - прямее некуда, глючить там может, как правило, только кривой код вкупе с кривой схемотехникой.
     
    ostrov нравится это.
  6. hrustbb

    hrustbb Нуб

    что кривого в моем коде? вроде вполне себе код (i' need help!). А насчет схемотехники, я даже не знаю, она у меня проще автомата калашникова.
     
  7. AlexU

    AlexU Гуру

    Код (C++):
    void(* resetFunc) (void) = 0; // Reset MC function

    resetFunc(); //вызов
    Это не решение проблемы, это, как говориться, "грязный хак".
    В данном случае Вы программно перегружаете контроллер. Иными словами в логике скетча есть ошибка, из-за которой устройство правильно работает до первого звонка. И вместо того, что бы найти и устранить ошибку, Вы просто перегружаете контроллер.

    А что именно за ошибка -- надо смотреть почему не срабатывает условие 'if (off == 2)' -- попробуйте добавить вывод отладочной информации в последовательный порт и смотрите через монитор порта на компьютере что происходит.
     
  8. DIYMan

    DIYMan Guest

    Вам честно или чтобы не обижать ваше самолюбие? Если честно - всё. Я не с целью напасть и принизить, просто код, написанный подобным образом - трудносопровождаем, хотя, на первый взгляд, вроде и прост. Вы сами нагородили то, с чем уже сейчас разобраться не можете - что же будет дальше?

    Ну и - не обижайтесь, но комментарии в коде подобного рода "модуль отвечает всегда по разному (NO CARSIER, NO CARRIES и т.п.)" говорят о том, что у вас не в порядке и со схемой. Я уверен на 200%, что модем НЕ МОЖЕТ отвечать разными ответами на одну команду, а то, что вы привели - это битые символы (отличие в один бит), что косвенно свидетельствует о том, что система, собранная из соплей и палок - глючная по определению.
     
  9. hrustbb

    hrustbb Нуб

    я знаю что это не решение. Условия то как раз отрабатывают по схеме: срабатывает вибродатчик, звонок на телефон и включение диода на 13ой ноге, я кладу трубку, диод гаснет и система снова ждет срабатывания вибродатчика. Причем отрабатывает стабильно и на 10й раз, но светодиод гаснет только при отработке по первому кругу, далее дальше продолжает гореть. Насчет вывода отладочной информации, она также перестает выводиться на втором круге.
     
  10. DIYMan

    DIYMan Guest

    Смущает вот это, как минимум:

    Код (C++):
    if (resp_str.compareTo("NOC") == 0)
    при том, что прямо выше написано:
    Код (C++):
    //GSM модуль отвечает всегда по разному (NO CARSIER, NO CARRIES и т.п.)
    Не находите разницы? Пробел где? Игнорируете? Вижу условие, конечно (response_byte > 64 && response_byte < 91), но вот такие плюшки порой выходят боком в самых неожиданных местах.

    Возможно, дело и не в этом, но вот смотрю я в код - и не вижу особого криминала, кроме излишней запутанности. Посмотрю ещё, может, найду чего.

    Правка: вы можете выводить в Serial всё, что получаете из mySerial? Такое ощущение, что при первом прогоне возвращается двойной ответ OK\r\nOK\r\n - других вариантов пока не вижу.
     
    Последнее редактирование модератором: 31 авг 2016
  11. hrustbb

    hrustbb Нуб

    Давайте честно, но по делу, за самолюбие не переживайте. Код-говнокод, согласен, в последствии, когда разберусь, переделаю. Насчет плохих контактов - ну на макетке там, проводки-штыречки. Всетаки я не пойму- почему все работает, а светодиод не гаснет?
     
  12. DIYMan

    DIYMan Guest

    Выше написал предположение, отредактировав сообщение. Надо сделать вывод в Serial всего, что отдаёт mySerial - пока наскидку вижу, что единственный вариант, почему не работает на последующих прогонах - если на первом прогоне приходит два ответа OK вместо одного.
     
  13. hrustbb

    hrustbb Нуб

    да, пробел и непечатаемые символы, типа переноса строки игнорятся, берутся первые 3 символа потому, что не известно точно, что там дальше, я согласен что это слишком уж корявенько, но это все временные решения
     
  14. hrustbb

    hrustbb Нуб

    спасибо за участие. А в ответ на команду AT в процедуре setup() gsm-модуль чем-то отвечает? хотя там и на втором круге два ок приходят. Кстати модуль neoway m590
     
    Последнее редактирование: 31 авг 2016
  15. Developer-RU

    Developer-RU Гик

    nlg всегда больше 5 подозреваю. а так же задержки между условиями помоему должны быть - сериал порт не так быстро работает.

    а светодиод не гаснет из за того что nlg более 5 постоянно... (аналоговый до 1024, а 5 это практически 0, вот он и гоняет постоянно в цикле и не успевая выключить светодиод включает по новой, и сплется по несколько раз ок, а что за NOC - непонятно вообще)

    поставь в конце loop задержку секунд на 10 и задержки между условиями небольшие(off 1,2...)
     
  16. DIYMan

    DIYMan Guest

    Точно, слона-то я и не приметил. Смотрите - вы в setup посылаете AT. В буфер попадает ответ OK. При первом проходе loop при срабатывании вибродатчика вы посылаете ещё одну команду, в буфере будут два ответа OK. Вы их вычитываете, и off принимает значение 2, светодиод после первого отсыла гаснет. Далее, при последующих срабатываниях датчика - off никогда не станет равно 2, поскольку в буфере будет лежать только один OK. Выход - убрать проверку на 2, гасить светодиод на off = 1, вторую вычитку ответа от модема блок if(off == 1) - перенести в setup после отсыла команды AT.

    И всё взлетит.
     
  17. hrustbb

    hrustbb Нуб

    показания с датчика nlg во внимание принимаем только когда off == 1, читать из порта не перестаем, пока не получим нужное нам количество читаемых символов игнорируя пробелы, NOC это от NO CARRIER, н т.к. схема на макетке, херовые контакты, биты теряются, то приходит NO CARRIES, NO CASIER и т.п
     
  18. hrustbb

    hrustbb Нуб

    Теперь у меня отпал последний usb порт на ноуте, так-что вернусь позже. Кстати насколько вредно запитывать ардуинку чисто от usb?
     
  19. DIYMan

    DIYMan Guest

    Саму ардуинку - безвредно. Вредно питать от USB сразу всё, порт может не сдюжить - емнип там максимум 500 mA.
     
  20. hrustbb

    hrustbb Нуб

    У меня ардуинка от усб, gsm модуль от внешнего источника, земли объеденены, хотя может и не из-за этого, они как-то поочереди у меня передохли за год примерно