RFID + millis
- Войдите на сайт для отправки комментариев
Сб, 04/05/2019 - 18:32
Здравствуйте, жители форума. Недавно начал изучать millis и уже написал код считывания показаний датчика с помощью millis (просто сам до этого решил дойти), но когда приступил к RFID-метке, возникла проблема.
Все, что у меня получилось, это написать код, в котором присутсвуют:
1) Функция возрвращения uid приложенной карты
2) И в loop'е сравнивает его, при вызове функции, с нужным, после чего должны последовать действия(например - вкл светодиод).
Но у меня не получается реализовать это с millis
Когда я прикладываю карту, у меня просто быстро начинает вкл-выкл светодиод. И так пока держу карту.
Надеюсь код будет понятен и вы сможете мне помочь.
#include <MFRC522.h>
//---------------------------------------------------------//
#define BUTTON_PIN A1 // Сенсорная кнопка
#define LIGHT_LINE 46 // Светодиодная лента на входе
boolean button_state = false;
boolean light_state = false;
boolean button_flag = false;
boolean card_flag = false;
unsigned long real_time;
MFRC522 mfrc522(53, 5); // SS_PIN and RST_PIN
//---------------------------------------------------------//
void setup() {
pinMode(BUTTON_PIN, INPUT);
SPI.begin();
mfrc522.PCD_Init();
Serial.begin(9600);
}
void loop() {
real_time = millis();
if (getID() == 911266) { // 911266 - uid моей карты
if (card_flag == false) {
card_flag = true;
light_state = !light_state;
real_time = millis();
}
if (card_flag == true && (millis() - real_time) < 1000) {
card_flag = false;
}
}
digitalWrite(LIGHT_LINE, light_state);
}
unsigned long getID() { // ----- Функция, возращающая uid приложеной карты ----- //
unsigned long uidDec, uidDecTemp;
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return 0;
}
if ( ! mfrc522.PICC_ReadCardSerial()) {
return 0;
}
uidDec = 0;
for (byte i = 0; i < mfrc522.uid.size; i++)
{
uidDecTemp = mfrc522.uid.uidByte[i];
uidDec = uidDec * 256 + uidDecTemp;
}
return uidDec;
}
Конечный автомат мы принципиально не применяем? Мол Аллах запретил. Но хоть по ночам, когда Аллах "не видит" поизучайте немного.
Мистер qwone, а что Вы в данном случае имеете ввиду под "конечный автомат". Если Вы про действие, которое должно произойти с помощью RFID-метки, то я написал, что должен загореться светодиод
Конечный автомат это внятные последовательности действия . А просто прилипить флаг и сказать что все ОК не выйдет. Поймите что при переходе из одного состояния в другое должна произходить выдержка времени организованая на millis а потом уже повторное считывание.
Хорошо, спасибо. Теперь понял, попробую реализовать
А Вы можете внятно, нормальными русскими словами, которые Вы понимаете, объяснить что делаетеся в строках №№ 26-35. По мне. так там бред, но, возможно, я ошибаюсь. Объясните, пожалуйста.
if (getID() == 911266) {на 26 строке мы вызываем функцию считывания uid карты, которую мы прикладываем, после чего сравниваем с uid нужной нам карты и выполнеем(или не выполняем) последующие действия
if (card_flag == false) { card_flag = true; light_state = !light_state; real_time = millis(); }В строках 27-31 мы делаем следующее:
если специальный флаг карты == false, то мы:
1) меняем его состояние на true
2) меняем значение переменной состояния светодиода на противоположное ему
3) обновляем значение переменной, хранящее аппартное время платы
if (card_flag == true && (millis() - real_time) < 1000) { card_flag = false; }Строки 32-34:
1) если флаг карты == true (т.е. предыдущий if выполнился), то меняем его состояние на false
2) Если все-таки флаг карты == true, то должно еще и пройти время(1 секунда), чтобы действия выполнились
Подаем(HIGH)/Не подаем(LOW) питание на светодиод, в зависимости от значения переменной light_state
#define LIGHT_LINE 46 // Светодиодная лента на входе unsigned long past; boolean card_flag = false; void set( bool f) { past = millis(); card_flag = f; if (f) { light_state = true; } else { light_state = false; } digitalWrite(LIGHT_LINE, light_state); } void setup() { pinMode(LIGHT_LINE, OUTPUT); set(false); } void loop() { uint32_t tmp = getID(); if (f) { // если включено if (millis() - past >= 1000) { // если прошло время if (tmp = 911266)// если карточка совпала set(false);// то выключить } }; else { // если выключено if (millis() - past >= 1000) { // если прошло время if (tmp = 911266)// если карточка совпала set(true);// то включить }; } }ПС: дальше жевать эту ботву не буду.
Хорошо, спасибо. Сейчас буду разбирать Ваш код и пробовать
Хорошо, спасибо. Сейчас буду разбирать Ваш код и пробовать
Очень плохая идея. Разбирать надо свой код.
В строках 27-31 мы делаем следующее:...
Ну, я же просил Вас смотреть на строки и писать что они делают. А Вы мне что написали? Вы написали, что он по Вашей задумке должны были бы делать.
Давайте я прокомментирую Ваш loop
void loop() { real_time = millis(); // нафиг ненужная операция, т.к. если правильную карту не поднесли, // то real_time никак не используется, а если поднесли, то ей // безусловно присваивается новое значение if (getID() == 911266) { // Если это правильная карта, то // сюда мы попадаем только тогда, когда поднесли правильную карту if (card_flag == false) {// Это условие истинно ВСЕГДА (см. ниже), поэтому оно лишнее card_flag = true; // Это ЕДИНСТВЕННОЕ место в программе, где card_flag становится true. // кроме как здесь он true стать не может light_state = !light_state; // Изменяем light_state на противоположное real_time = millis(); // real_time делаем равным текущему millis } // Условие в следующей строке истинно ВСЕГДА, поэтому оно лишнее. // Действительно card_flag мы ТОЛЬКО ЧТО сделали true, real_time ТОЛЬКО ЧТО сделали // равным текущему millis if (card_flag == true && (millis() - real_time) < 1000) { card_flag = false; // здесь мы возвращаем card_flag значение false, обеспечивая // вечную истинность условия в строке №7 выше "if (card_flag == false)" } } digitalWrite(LIGHT_LINE, light_state); // независимо ни от чего устанавливаем LIGHT_LINE в значение light_state }Надеюсь, Вы согласны с моими комментариями?
Теперь давайте повыбрасываем вечно истинные условия и бессмысленное манипулирование card_flag
и millis, и поймём, что Ваш код ПОЛНСТЬЮ эквивалентен вот такому.
void loop() { if (getID() == 911266) { // Если это правильная карта, то // сюда мы попадаем только тогда, когда поднесли правильную карту light_state = !light_state; // Изменяем light_state на противоположное } digitalWrite(LIGHT_LINE, light_state); // независимо ни от чего устанавливаем LIGHT_LINE в значение light_state }Вот и всё. Больше у Вас ничего не делается. Поднесли карту - на пине LIGHT_LINE сигнал поменялся на противоположный. Поднесли ещё раз - поменялся "взад". Так она себя ведёт? Собственно, как написано, так и ведёт.