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

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

  1. Cynep

    Cynep Нерд

    Здравствуйте, сегодня получил первый опыт работы с ардуино и столкнулся с проблемой невозможности изменить значение переменной в цикле loop.
    В упрощённом виде это выглядит так:
    Код (Text):

    int var = 0;

    void loop()
    {
      if(var == 0)
      {
        var = 1;
      }
    }
     
    Логический блок срабатывает всегда, так как значение var не изменяется. Что я не так делаю? Спасибо.
     
  2. rkit

    rkit Гуру

    Пытаетесь программировать, не прочитав учебника по программированию.
     
  3. Cynep

    Cynep Нерд

    Обоснуйте.
     
  4. Airbus

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

    Что делает сей код?
     
  5. Limoney

    Limoney Гик

    переменная изменяется единожды
     
  6. Cynep

    Cynep Нерд

    Это упрощенный вариант. Другими словами, убрал все лишние чтобы не перегружать людей.
    Важно, что переменная всегда остается равна нулю.

    Взял готовый пример с RС меткой и реле. Подносишь карточку к датчику и лампочка светится. Но в примере используется задержка, после которой реле включается снова и снова, снова и снова, снова и снова - лампочка светится, но реле продолжает включаться. Обычно те, кто "читают" учебники и "умничают" используют данную конструкцию, например, для учета количества нажатий на кнопку:
    Код (Text):

     if (нажата кнопка) {
           ++n;
           if (n>5) n=1;
       }
     
    Или этот код тоже не понятен?
     
  7. Cynep

    Cynep Нерд

    У меня переменная не изменяется.(((((
     
  8. Limoney

    Limoney Гик

    Как видите (чем определяете) , что не изменяется? Изменяется с 0 на 1
     
  9. Cynep

    Cynep Нерд

    1) Выводил в терминал
    2) реле продолжает щелкать

    Цикл видит только начальные значения при загрузке. Это похоже на изменение локальной переменной, вместо глобальной... Не смог найти решение своей проблемы. Может дело в том, что ардуино из китая?
     
  10. Limoney

    Limoney Гик

    Из Китая ардуино работают нормально.
    Изначально переменная равна 0, по условию изменяется на 1 один раз, и больше не изменяется
     
  11. Cynep

    Cynep Нерд

    Полный код:
    Код (Text):

    /* 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;
    }

    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();
      }
    }

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

    Cynep Нерд

    Фишка такая. Изначально она равна 0 и после изменения значения на 1 при следующем проходе цикла переменная опять равна 0.
     
  13. Cynep

    Cynep Нерд

    Этот код должен работать, но не работает. Думал, может бывали похожие случаи...

    В понедельник сниму видео. Спасибо за ответы.
     
  14. Limoney

    Limoney Гик

    ридер читает номер карты? т.е выводит в монитор номер карты
     
  15. rkit

    rkit Гуру

    Это у вас в коде и написано

     
  16. Airbus

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

    Много мусора в коде.Что делает эта строка?
    Код (C++):

    Serial.println(analogRead(YELLOW_LED));
         if (rfid.readCardSerial())
     
    У меня есть подобный код и он работает
    Код (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] = {100,156,237,226,247}; // Это брелок!
    unsigned char i;

    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);
    }

    void loop()
    {
        if (rfid.isCard())
        {
            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)
                    {
                      allow();
                    }
                    else
                    {
                      denied();
                    }
             }
        }
        rfid.halt();
    }

    void allow()
    {
      Serial.println("Access accept!");
      indication(BLUE_LED);
    }
    void denied()
    {
      Serial.println("Access denied!");
      indication(YELLOW_LED);
    }
    void indication(int led)
    {
      digitalWrite(led, HIGH);
      delay(1000);
      digitalWrite(led, LOW);
    }
     
    А Вот этот мусор в конце кода
    Код (C++):

        digitalWrite(YELLOW_LED, HIGH);
        isAllow = 0;
        // rfid.halt();
    каждый раз присваивает isAllow-0 и поэтому оно у Вас 0 постоянно и код выполняется постоянно. Кстати зачем закоментировали rfid.halt();?
     
    Последнее редактирование: 16 июн 2017
  17. Cynep

    Cynep Нерд

    Код работает. Номер картый читает, лампочка зажигатся. Проблема в том, что она в цикле включает, пауза, включает(хотя уже включено), пауза, опять включает и так далее...
     
  18. Limoney

    Limoney Гик

    Уважаемый Airbus
    помог с рабочим скетчем. А у вас в скетче это условие
    Код (C++):

    if(isAllow == 0){
      allow();
    }
    выполнялось один раз после сравнения правильной карты доступа,
    Код (C++):
    void allow()
    {
      Serial.println("Access accept!"); //доступ получен
      digitalWrite(YELLOW_LED, LOW);
      //delay(1000);
    [B]  isAllow = 1;[/B]
    }
    поэтому переменная не изменяется.
    Тоже закоментировали rfid.halt();
     
  19. Cynep

    Cynep Нерд

    В целом, этот код не мой. Скачал готовый. Работает не очень правильно. Решил добавить флаг isAllow для того, чтобы не включать включённое реле в цикле.

    Данная строка "Serial.println(analogRead(YELLOW_LED));" для дебага. Сначала она выглядела вот так: "Serial.println(digitalRead(YELLOW_LED));". В таком варианте она всегда выводила "1" вне зависимости от того, прикладывается метка к датчику или нет. Т.е. чтение пина всегда возвращает HIGH, хотя должно было меняться. Решил глянуть вывод аналога. Не влияет на функционал, использовалась для логирования, забыл ее удалить.

    Далее:
    Код (Text):

    digitalWrite(YELLOW_LED, HIGH); //выключает реле, если метка не приложена
        isAllow = 0; //флаг - выключено, если метка не приложена к датчику.
        // rfid.halt();//хз что это такое, было в оригинале, я не комментировал.
     
    Не каждый раз присваивает, а когда нет метки.Если есть метка флаг =1, если нет метки флаг = 0, если метка не правильная флаг = 0.
    Код (Text):

    //Если карта приложена
    if (rfid.isCard())
    {
      //делаем проверку карты и далее
    }
    //если карты нет
    else
    {
      //Выключаем реле, обнуляем флаг
    }
     
    [/QUOTE]

    Смысл использования флага такой: если мы приложили метку к датчику, то после проверки включаем реле 1 раз и ставим флаг isAllow =1. Метку с датчика не убираем. При последующих похождениях цикла смотрим значение флаг и понимаем, что реле уже включено и его не надо включать еще раз. Но!!! Переменная не изменяется.
    .
     
  20. Airbus

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

    Я не понял что Вам надо?Чтоб код выполнялся один раз?Тогда закоментируйте нах isAllow = 0 в самом конце и будет Вам щастье!