Изменение значения в цикле loop

Тема в разделе "Arduino & Shields", создана пользователем Cynep, 16 июн 2017.

  1. Cynep

    Cynep Нерд

    Зачем его комментировать? В конце идет обработка else! Если метка не приложена флаг обнуляется. Понимаете? Мы приложили метку и флаг = 1. Если сделать, как вы говорите и убрать метку с датчике флаг останется = 1...
     
  2. Airbus

    Airbus Радиохулиган Модератор

    Накуя?Не понимаю.Нет метки и не та метка это одно и то же.Зачем огород городить?Вы в коде разберитесь коменты проставьте лишнее уберите.
     
  3. Limoney

    Limoney Гик

    Нафиг ненужная переменная.
    Реле щелкает здесь
    Код (C++):
    void indication(int led)
    {
      digitalWrite(led, HIGH);
      delay(1000);
      digitalWrite(led, LOW);
    }
     
  4. Cynep

    Cynep Нерд

    В моей версии скетча эта функция не используется. Походу, по сети этот скетч гуляет в разных вариантах.
    Но проблема не в коде. По какой-то причине переменная не может значение в себя сохранить, понимаете?
     
  5. Cynep

    Cynep Нерд

    Эм... Я вас не понимаю. Зачем комментировать сброс флага? Все очень просто: если условие не выполняется надо сбросить флаг. Если карта приложена к датчику, выполняется один блок кода, если нет, то другой.
     
  6. Cynep

    Cynep Нерд

    Всем большое спасибо за попытки помочь, но Вы явно меня не поняли. У меня переменная не сохраняет новое значение! Такое иногда бывает, по запарке, при использовании ссылок на переменную.
    Вопрос: почему? Тут, судя по-всему, с этой проблемой никто не сталкивался. Я уже и сам склоняюсь к тому, что проблема где-то в железе. Может во время работы микросхема не может переписывать данные в памяти или еще что-то... В любом случае, ардуинка осталась на работе и доступ к ней будет только в понедельник. Проверю код еще раз и обязательно скину видеоролик. До понедельника.:)Всех благ.
     
  7. rkit

    rkit Гуру

    Проблема в том, что вы пытаетесь программировать, не прочитав учебник. Код делает ровно то, что вы написали.
     
  8. Cynep

    Cynep Нерд

    Расскажите подробнее.
     
  9. rkit

    rkit Гуру

    Вам три человека уже написали подробно и как надо. Это уже не смешно.
     
  10. AlexU

    AlexU Гуру

    Добавьте ёще отладочной информации типа:
    Код (C++):
    /* MOSI: Pin 11 / ICSP-4
    * MISO: Pin 12 / ICSP-1
    * SCK: Pin 13 / ISCP-3
    * SS: Pin 10
    * RST: Pin 9
    */


    #include <SPI.h>
    #include <RFID.h>

    #define SS_PIN 10
    #define RST_PIN 9
    #define BLUE_LED 6
    #define YELLOW_LED 7


    RFID rfid(SS_PIN, RST_PIN);

    unsigned char reading_card[5]; //for reading card
    unsigned char master[5] = {160,112,85,128,5}; // allowed card
    unsigned char i;
    int isAllow;

    void indication(int led);
    void allow();
    void denied();

    void setup()
    {
      Serial.begin(9600);
      SPI.begin();
      rfid.init();
      pinMode(BLUE_LED, OUTPUT);
      pinMode(YELLOW_LED, OUTPUT);
      digitalWrite(BLUE_LED, HIGH);
      digitalWrite(YELLOW_LED, HIGH);
      isAllow = 0;

      //DEBUG
      Serial.print("setup(): isAllow = ");
      Serial.println(isAllow);
      //DEBUG END
    }

    void loop()
    {
       if (rfid.isCard())
       {
         Serial.println(analogRead(YELLOW_LED));
         if (rfid.readCardSerial())
         {
            /* Reading card */
            Serial.println(" ");
            Serial.println("Card found");
            Serial.println("Cardnumber:");
            for (i = 0; i < 5; i++)
            {
               Serial.print(rfid.serNum[i]);
               Serial.print(" ");
               reading_card[i] = rfid.serNum[i];
            }
            Serial.println();
            //verification
            for (i = 0; i < 5; i++)
            {
               if (reading_card[i]!=master[i])
               {
                  break;
               }
            }
            if (i == 5)
            {
               if(isAllow == 0)
               {
                  allow();
               }
            }
            else
            {
               denied();
            }
         }
      }
      else
      {
        digitalWrite(YELLOW_LED, HIGH);
        isAllow = 0;
        // rfid.halt();

       //DEBUG
       Serial.print("loop(): isAllow = ");
       Serial.println(isAllow);
       //DEBUG END
      }
    }

    void allow()
    {
      Serial.println("Access accept!"); //доступ получен
      digitalWrite(YELLOW_LED, LOW);
      //delay(1000);
      isAllow = 1;
     
      //DEBUG
      Serial.print("allow(): isAllow = ");
      Serial.println(isAllow);
      //DEBUG END
    }
    void denied()
    {
      Serial.println("Access denied!"); //доступ закрыт
      digitalWrite(YELLOW_LED, HIGH);
      delay(1000);
      isAllow = 0;

      //DEBUG
      Serial.print("debied(): isAllow = ");
      Serial.println(isAllow);
      //DEBUG END
    }
    Когда разберётесь в чём дело, отладку удалите.
     
    Cynep нравится это.
  11. Airbus

    Airbus Радиохулиган Модератор

    Я же уже сказал Вам почему
    Код (C++):

    digitalWrite(YELLOW_LED, HIGH);
        isAllow = 0;
        // rfid.halt();
    Эта часть кода выполняется постоянно и вы постоянно присваиваете isAllow - 0 Если не понятно почему то разберитесь как работает конструкция if-else. У Вас нагорожен огород из нескольких if и else работает не с тем if с которым Вы планировали. или убирайте нах первый if (а для чего он вообще там?) или правильно прицепите else. Но всё равно я не понимаю логики работы Вашего кода.
    Вот здесь помогал одному человеку делать ГСМ сигнализацию. Для однократного дозвона и посыла СМС использовал флаги state и flag. Обратите внимание как они работают.
    Код (C++):
    #include <LiquidCrystal.h>
        LiquidCrystal lcd(2, 3, 4, 5, 11, 12);
        int analogInput = 0;            // переменная для удобства инициализации и работы с аналог. портом 0
        float vout = 0.0;               // переменная с значением выходного напряжения
        float vin = 0.0;                // переменная с результатом измерений
        int R1 = 100000;                // сопротивление R1
        int R2 = 10000;                 // сопротивление R2
        int value = 0;                  // переменная хранения данных
        int btnPin = 10;                // переменная прерывателя
        int state = 1 ;                 // статус СМС
        int flag = 1 ;                  // флаг дозвона
        void setup()
      {
        Serial.begin(9600);      
        pinMode(btnPin, INPUT);
        //Включаем GPRS Shield, эмулируя нажатие кнопки POWER
        pinMode(9, OUTPUT);
        digitalWrite(9, HIGH);    // Подаем High на пин 9
        delay(1000);              // на 3 секунды
        digitalWrite(9, LOW);     // и отпускаем в Low.
        delay(3000);              // Ждём 5 секунд для старта шилда
        lcd.begin(16, 2);
        lcd.print("DC VOLTMETER");
             }
        void loop()                                                                                                                                                                                                                                                                                        
         {
         //Serial.println("start");  // чисто для отладки
         if (digitalRead(btnPin) == HIGH) // если сработал контакт
           {
             if (flag == 1)                 //и флаг поставлен
             {
            //сразу после нажатия кнопки начинаем звонить по заданному номеру
            Serial.println("ATD +380686617468;");
            delay(100);
            flag = 0;    //блокируем повторные дозвоны  
              }
                       }
         // измеряем напряжение
         value = analogRead(analogInput);// читаем аналоговый сигнал, с аналог. порта - 0
         vout = (value * 4.95) / 1024.0;  // не забываем про внесение поправки (5.0 - это идеальный вариант,хотя все возможно)
         vin = vout / (R2/(R1+R2));      // в переменной будет значение входного напряжения
         //Serial.println(vout);
         if(vin < 12)      // если меньше 12 вольт
       {
         if (state == 1)           // и флаг поставлен
           {
                 
        Serial.println("AT+CMGF=1\r"); // Устанавливает текстовый режим для SMS-сообщений
        delay(100);                // даём время на усваивание команды
                                   // Устанавливаем адресата: телефонный номер в международном формате
        Serial.println("AT + CMGS = \"+380686617468\"");
        delay(100);
        // Пишем текст сообщения
        Serial.println("Alarm Low Bat Voltage!!!");
        delay(100);
        Serial.println(vin);
        delay(300);
                                   // Отправляем Ctrl+Z, обозначая, что сообщение готово
        Serial.println((char)26);
        state = 0;                 //блокируем повторные отправки
               }
             }
        lcd.setCursor(0, 1);       //выводим на LCD
        lcd.print("INPUT V= ");
        lcd.print(vin);           // значение напряжения
        //Serial.println(vin);      // чисто для отладки
        delay(500);
      }
    А они реально работают.Удачи!
     
    Последнее редактирование: 17 июн 2017
  12. Airbus

    Airbus Радиохулиган Модератор

    Это понятно. Это и в моём скетче тоже.Тогда зачем вам флаг isAllow? Метка приложена замок открылся и зачем Вы ставите флаг isAllow = 1;? Он же уже сработал и без него? А потом в конце кода ставите опять isAllow = 0; Что в Вашем коде делает isAllow? вы уж определитесь. А про коменты это чтоб самому понимать что и где происходит. Чтоб код оперативно поправить под свои цели. Очень удобно!
     
  13. Cynep

    Cynep Нерд

    Спасибо за дельный совет, но, к сожалению, логирование уже делал. Не так досконально, как вы, но вывод в терминал показал, что переменная isAllow НЕ изменяется. Более того, сначала вместо флага делал вариант с чтением пина digitalRead, который должен вернуть LOW или HIGH.
    Код (C++):

    if(digitalRead(LED) == HIGH)
    {
      digitalWrite(LED, LOW)
    }
     
    Это не сработало и поскольку это был мой первый опыт с ардуино, подумал, что сделал ошибку или неправильно использовал функцию - отказался от данного кода. Решил использовать флаг - старый проверенный метод. Опять не работает. Сделал логирование - переменная всегда выдает 0. Что за ерунду, подумал я?
    Проверю еще раз в понедельник, может у меня крыша поехала или где-то ошибся. Конец недели, все-таки...

    Нет, эта часть кода срабатывает, когда rc метка не приложена к датчику.
    Код (C++):

    if (rfid.isCard())
    {
    //Если приложенная карта определена
    }
    else
    {
    //а это место, про которое вы мне говорите - оно срабатывает НЕ ВСЕГДА, а когда НЕТ КАРТЫ!!!!
    }
     
    Спасибо за пример с флагами. Обратил внимание, что код у вас срабатывает ровно ОДИН раз. Например, у вас сработал контакт и начинается дозвон по заданному номеру, но если контакт сработает еще раз? Например, в следующем проходе цикла? Дозвона не будет, так как флаг не обнулен. Ваш флаг остается = 0. Получается одноразовая сигнализация. Владельцу придется приезжать и делать перезагрузку ардуино, после чего все переменные обнулятся и флаг будет = 1. Тоже самое с state. Остальной код будет срабатывать каждый раз, когда сработает контакт, но без телефона. К примеру, если поставить ваш код на лампочку и датчик освещения в подъезде, то свет загорится только один раз и больше загораться не будет и люди будут ходить в темноте...
    В моем случае, если я подношу карту, то лампочка зажигается, если убираю карту, то лампочка гаснет, если опять подношу карту лампочка зажигается и так далее... Ниже, для пользователя Airbus, есть пример работы с обнулением флага.
    Если вы запустите СВОЙ скетч, то увидите, что если приложить карточку и не убирать ее, то реле будет включаться каждую секунду. Если карточку НЕ убирать, то цикл loop будет включать реле каждую секунду.
    Тут важно понять, что это НЕ разовое нажатие кнопки, а УДЕРЖИВАНИЕ. Пока держишь кнопку условие выполняется. Если отпускаешь - условие не выполняется.

    Теперь к моим баранам. Я хочу, чтобы при прикладывании карты реле включилось только ОДИН раз, следовательно программа должна как-то узнать включено ли реле УЖЕ или не включено. Есть два способа: узнать состояние пина или ввести дополнительный флаг. Если мы используем флаг, то его надо СБРАСЫВАТЬ на исходное состояние, иначе он не сработает в дальнейшем.
    Напишу для вас простой пример кода с флагом ниже:
    Код (C++):

    flag = 0;
    void loop()
    {
      if(Удерживаем кнопку)
      {
        //Если еще не включено, то флаг будет = 0
        if(flag == 0)
        {
          turnOn(); //включаем
          flag = 1; //делаем пометку, что включено - если будем держать кнопку и дальше этот код не выполнится
        }
      }
      else //НЕ удерживаем кнопку
      {
        //если до этого момента удерживали кнопку, то flag будет =1, но кнопку то уже отпустили!!!
        flag = 0; //делаем пометку, что выключили
        turnOff(); //выключаем - тут, по-хорошему, надо тоже сделать проверку, иначе код будет всегда выключать то, что уже выключено.
      }
    }
     
     
    Последнее редактирование: 17 июн 2017
  14. Cynep

    Cynep Нерд

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

    ostrov Гуру

    После второго ответа я потерял мысль. Но если отвечать на первый вопрос, то условие срабатывает 1 раз. С чего вы взяли что переменная не меняется? Вот это:
    Код (C++):
    int var = 0;
    где обьявлено?
     
  16. Cynep

    Cynep Нерд

    Это упрощенный вариант. Реальный код есть на первой странице, внизу.
     
  17. Airbus

    Airbus Радиохулиган Модератор

    Начинаю немного понимать-хотите управлять замком флагами?Или триггерным режимом приложил - вкл второй раз приложил - выкл так?Но вот у меня реле не щёлкает каждую минуту оно всегда включено пока карта прижата возможно даже потому что скетч крутиться очень быстро. Есть даже конечное устройство на Меге 8. Но всё равно ошибка в коде и надо смотреть где. По поводу сигнализации - это был промежуточный вариант показал человеку как работать с флагами. В конечном варианте флаг СМС сбрасывался через 3 минуты функцией миллис. Но код у меня не сохранился. Я поковыряю ваш код если вы не против? Если добьюсь чего то то выложу.
     
  18. Cynep

    Cynep Нерд

    Я ещё и сам не знаю, что хочу сделать. Сам факт того, что оно щелкает меня бесит.
    А какой у вас скетч?
    Намного лучше.
    Ковыряйте сколько угодно. Этот скетч скачал откуда то. Посмотрел видео и загорелся попробовать. Я лишь добавил флаг. Спасибо за помощь.
     
  19. fogary

    fogary Гик

    Поясните Вашу высказывание, т. е. каждую секунду реле сначала выключается, а потом включается? Или Вы имеете ввиду, что команда на включение реле подается каждую секунду?

    По поводу флага. Пробовали проверять значение i перед строкой:
    Код (C++):
    if (i == 5)
     
  20. Cynep

    Cynep Нерд

    Да, скетч постоянно включает включенное.

    i не проверял. Конструкция странная