Помогите решить проблему с RFID
- Войдите на сайт для отправки комментариев
Ср, 22/11/2017 - 00:35
Есть RFID считыватель. Задача такая: нужно, чтобы при поднесении карты с одним номером начинался цикл while и при повторном поднесении этой же карты он прекращался. Как это осуществить?
bool onCicle = false; void loop() { if(rfid.CardPresent()) { onCicle = !onCicle; if(onCicle) echo "work"; else echo "idle"; } }Псевдокод, для демонстрации подхода.
Понял. А как мне зафиксировать значение? В сериал выводит поочередно ON и OFF
boolean tinker_flag = false; #include <SoftwareSerial.h> #include <SPI.h> #include <MFRC522.h> // библиотека "RFID". #define SS_PIN 10 #define RST_PIN 9 unsigned long uidDec, uidDecTemp; // для храниения номера метки в десятичном формате MFRC522 mfrc522(SS_PIN, RST_PIN); void setup() { pinMode(8, OUTPUT); Serial.begin(9600); Serial.println("Waiting for card..."); SPI.begin(); // инициализация SPI / Init SPI bus. mfrc522.PCD_Init(); // инициализация MFRC522 / Init MFRC522 card. } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } // Выбор метки if ( ! mfrc522.PICC_ReadCardSerial()) { return; } uidDec = 0; // Выдача серийного номера метки. for (byte i = 0; i < mfrc522.uid.size; i++) { uidDecTemp = mfrc522.uid.uidByte[i]; uidDec = uidDec * 256 + uidDecTemp; } Serial.println("Card UID: "); Serial.println(uidDec); if (uidDec == 3237618307) { tinker_flag = !tinker_flag; if (tinker_flag) { digitalWrite(8, 1); Serial.println("ON"); } else if (!tinker_flag){ digitalWrite(8, 0); Serial.println("OFF"); } } }Понял. А как мне зафиксировать значение? В сериал выводит поочередно ON и OFF
Фиксируйте карту и время её приложения. Т.е. - приложили карту, вы смотрите флаг - эта карта уже была приложена на крайнем проходе loop? Если нет - инвертируете флаг работы, запоминаете, что карта приложена. Если да - ничего не делаете. Как только считыватель скажет, что карты нет на нём - сбрасываете флаг приложенной карты. Псевдокод:
bool onWork = false; bool ourCard = false; void loop() { if(!rfid.cardPresent()) {ourCard = false; return;} if(card == ...) { if(ourCard) return; ourCard = true; onWork = !onWork; if(onWork) echo "work"; else echo "idle"; } }boolean onWork = false; boolean ourCard = false; #include <SoftwareSerial.h> #include <SPI.h> #include <MFRC522.h> // библиотека "RFID". #define SS_PIN 10 #define RST_PIN 9 unsigned long uidDec, uidDecTemp; // для храниения номера метки в десятичном формате MFRC522 mfrc522(SS_PIN, RST_PIN); void setup() { pinMode(8, OUTPUT); Serial.begin(9600); Serial.println("Waiting for card..."); SPI.begin(); // инициализация SPI / Init SPI bus. mfrc522.PCD_Init(); // инициализация MFRC522 / Init MFRC522 card. } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } // Выбор метки if ( ! mfrc522.PICC_ReadCardSerial()) { return; } uidDec = 0; // Выдача серийного номера метки. for (byte i = 0; i < mfrc522.uid.size; i++) { uidDecTemp = mfrc522.uid.uidByte[i]; uidDec = uidDec * 256 + uidDecTemp; } Serial.println("Card UID: "); Serial.println(uidDec); if (!uidDec == 3237618307) { ourCard = false; return; } if (uidDec == 3237618307) { if (ourCard) { return; } ourCard = true; onWork = !onWork; if (onWork) { digitalWrite(8, 1); } else { digitalWrite(8, 0); } } }boolean onWork = false; boolean ourCard = false; #include <SoftwareSerial.h> #include <SPI.h> #include <MFRC522.h> // библиотека "RFID". #define SS_PIN 10 #define RST_PIN 9 unsigned long uidDec, uidDecTemp; // для храниения номера метки в десятичном формате MFRC522 mfrc522(SS_PIN, RST_PIN); void setup() { pinMode(8, OUTPUT); Serial.begin(9600); Serial.println("Waiting for card..."); SPI.begin(); // инициализация SPI / Init SPI bus. mfrc522.PCD_Init(); // инициализация MFRC522 / Init MFRC522 card. } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } // Выбор метки if ( ! mfrc522.PICC_ReadCardSerial()) { return; } uidDec = 0; // Выдача серийного номера метки. for (byte i = 0; i < mfrc522.uid.size; i++) { uidDecTemp = mfrc522.uid.uidByte[i]; uidDec = uidDec * 256 + uidDecTemp; } Serial.println("Card UID: "); Serial.println(uidDec); if (!uidDec == 3237618307) { ourCard = false; return; } if (uidDec == 3237618307) { if (ourCard) { return; } ourCard = true; onWork = !onWork; if (onWork) { digitalWrite(8, 1); } else { digitalWrite(8, 0); } } }Вы невнимательно читали мой пример. Перед 23 строкой вставьте сброс флага, когда карты нету.
Получается так, что снова поочередно выводит ON и OFF. Объясните мне на пальцах, как это работает? У меня в голове эти флажки не укладываются
Получается так, что снова поочередно выводит ON и OFF. Объясните мне на пальцах, как это работает? У меня в голове эти флажки не укладываются
Давайте на примере: вам надо, чтобы при первом приложении ключа к считывателю - мотор закрутился (например), при втором приложении ключа к считывателю - остановился. Считыватель необязателен, это может быть кнопка, геркон и т.п. - важен принцип работы.
С точки зрения МК всё происходит очень быстро - 16 Мгц, функция loop вызывается со страшной скоростью. Микроконтроллеру неведомо, что вы хотите сделать - он каждый раз честно выполняет то, что написано у вас в loop.
Итак, мы имеем задачу. Для успешного решения этой задачи нам надо как-то дать понять контроллеру о двух простейших вещах: что не надо срабатывать постоянно, пока карточка приложена к считывателю (нажата кнопка и т.п.), и что надо как-то понимать, что карточка убрана со считывателя (кнопка отпущена). И только при смене состояний делать то, что нам нужно.
Вот тут и нужны разные флаги, с помощью которых мы можем манипулировать состоянием системы. Есть ещё один подход - конечный автомат, я сознательно не стал его приводить, т.к. он сложнее в понимании. Но он также прекрасно демонстрирует управление ветками программного кода. Смотрите ниже псевдокод:
typedef enum { msWaitForCardPresent, // ждём карты на считывателе msWaitForCardReleased, // ждём, когда карду уберут со считывателя } MachineState; MachineState machineState; bool motorRunning; void loop() { switch(machineState) { case msWaitForCardPresent: { if(rfid.CardPresent()) { if(rfid.getCardNumber() == 123456) { echo "Found our card, switch motor state!"; motorRunning = !motorRunning; if(motorRunning) echo "work"; else echo "idle"; echo "Wait for card released..."; machineState = msWaitForCardReleased; } } } break; case msWaitForCardReleased: { if(!rfid.CardPresent()) { machineState = msWaitForCardPresent; echo "card released, switch to wait mode..."; } } break; } }Думаю, по примеру очевидно, что мы простыми методами передаём управление то одной, то другой ветке кода. То же самое можно сделать и с кучей разных флагов, важен сам принцип.
Не запутал?
Процессор не может стоять (в нормальных услових). Процессор всегда в секунду выполняет определеное количество команд. Но пользователю хватает только определеное количество. Остальные процессор делает в холостую. И важно что бы в холостую процессор что-то сделал не так. Дальше у процессора нет памяти , а та память что есть это скорее записная книжка. Вот по ней процессор и сверяется что делать. Процессор обнаружил что есть карточка. А раньше была? Если была то идем на новый круг. А если не была. То она появилась. Надо что то сделать. А что сделать? Если в книжке написана-"лампочка погашена" , то включить и записать в книжку "лампочка включена". А если иначе то сделать на оборот.
И так два флага- 1 это состоние наличия карточки раньше - Есть/Нет 2 - состояние лампочки - Погашена/Включена.
ПС: В общем считайте что процессор это Колобок Коллега из этого. https://www.youtube.com/watch?v=tIWbdsbHZN8
Нет, спасибо) Буду разбираться дальше. Если что - отпишусь.
Процессор не может стоять (в нормальных услових). Процессор всегда в секунду выполняет определеное количество команд. Но пользователю хватает только определеное количество. Остальные процессор делает в холостую. И важно что бы в холостую процессор что-то сделал не так. Дальше у процессора нет памяти , а та память что есть это скорее записная книжка. Вот по ней процессор и сверяется что делать. Процессор обнаружил что есть карточка. А раньше была? Если была то идем на новый круг. А если не была. То она появилась. Надо что то сделать. А что сделать? Если в книжке написана-"лампочка погашена" , то включить и записать в книжку "лампочка включена". А если иначе то сделать на оборот.
И так два флага- 1 это состоние наличия карточки раньше - Есть/Нет 2 - состояние лампочки - Погашена/Включена.
ПС: В общем считайте что процессор это Колобок Коллега из этого. https://www.youtube.com/watch?v=tIWbdsbHZN8
Спасибо))