Глючит схема
- Войдите на сайт для отправки комментариев
Ср, 31/08/2016 - 15:14
Сделал схему простой охранной ситемы, но она глючит: иногда она просто зависает, команды лок/анлок (Увидите в коде что это) работают (правда в случае с анлоком просто гаснет светодиод, надпись waiting for card не появляется) помогает только ресет(и кнопкой, и программный)
Вот код
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Servo.h>
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 53
#define RST_PIN 5
MFRC522 mfrc522(SS_PIN, RST_PIN);
unsigned long lastErr, lastOpen;
unsigned long uidDec, uidDecTemp; // для хранения номера метки в десятичном формате
unsigned long Time, gtime;
LiquidCrystal lcd(4, 9, 30, 31, 32, 33);
Servo servo;
byte antihack;
void(*resetFunc) (void) = 0; // Reset MC function
void setup() {
Serial.begin(9600);
Serial.println("Waiting for card...");
SPI.begin();
mfrc522.PCD_Init();
servo.attach(8);
servo.write(0);
pinMode(3, OUTPUT);
pinMode(2,OUTPUT);
pinMode(12, OUTPUT);
analogWrite(12, 10);
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0, 0);
if(EEPROM.read(0) == 1)
lockMute(65535);
}
void loop() {
EEPROM.write(0, 0);
if(Serial.available()){
switch(Serial.read())
{
case 'l' :
{
lockMute(65535);
break;
}
case 'r' :
{
resetFunc();
break;
}
}
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Waiting");
lcd.setCursor(0, 1);
lcd.print("for card...");
// Поиск новой метки
while ( ! mfrc522.PICC_IsNewCardPresent())
{if(Serial.available()){
switch(Serial.read())
{
case 'l' :
{
lockMute(65535);
break;
}
case 'r' :
{
resetFunc();
break;
}
}
}
}
// Выбор метки
while ( ! mfrc522.PICC_ReadCardSerial())
{if(Serial.available()){
switch(Serial.read())
{
case 'l' :
{
lockMute(65535);
break;
}
case 'r' :
{
resetFunc();
break;
}
}
}
}
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);
lcd.clear();
lcd.setCursor(0, 0);
if (uidDec == 1450513790)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Open");
antihack = 0;
tone(22, 2000, 3000);
digitalWrite(2, 1);
servo.write(90);
delay(3000);
digitalWrite(2, 0);
servo.write(0);
}
else
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Error");
antihack++;
Time = millis() - lastErr;
lastErr = millis();
if(antihack >= 5){
if(Time < 30000)
{
lock();
}
else
{
antihack = 0;
}
}
tone(22, 5000, 300);
digitalWrite(3, 1);
delay(1000);
digitalWrite(3, 0);
}
}
void lock()
{
digitalWrite(3, 1);
tone(22, 300, 5000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Locked");
for(byte i = 30; i>0; i--)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Locked!");
lcd.setCursor(0, 1);
lcd.print(i);
delay(1000);
if(Serial.available()){
switch(Serial.read())
{
case 'u' :
{
digitalWrite(3, 0);
return;
break;
}
case 'r' :
{
resetFunc();
break;
}
}
}
digitalWrite(3, 0);
antihack = 0;
servo.write(0);
}
}
void lockMute(unsigned int secs)
{
EEPROM.write(0, 1);
digitalWrite(3, 1);
for (unsigned i = secs; secs >0; i--)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Locked!");
lcd.setCursor(0, 1);
lcd.print(i);
if(Serial.available()){
switch(Serial.read())
{
case 'u' :
{
digitalWrite(3, 0);
return;
break;
}
case 'r' :
{
resetFunc();
break;
}
}
}
delay(1000);
}
digitalWrite(3, 0);
}
Кстати, если не убирать метку с ридера, зависаний не происходит
Кстати, если не убирать метку с ридера, зависаний не происходит
не убирай метку с ридера
Не смешно
Вы в лупе постоянно пишете в эпром? Киздец эпрому.
45 строка прямо в loop означает, что EEPROM скорее всего уже мёртв.
Что говорит IDE после компиляции насчёт занимаемой памяти?
Понятно, значит, скоре всего память не при делах.
Тогда я бы начал копать в сторону убитого EEPROM, а также посмотрел бы на схемы включения.
Нев Эпроме дело все, что связано с ним удалил, после первого же прочтения завис
+ пример в либе тоже работает
Ну, видите, что такое завис. Вы же говорите, что на какие-то команды реагирует, так ведь?
Ну тогда ставьте вывод чего-нибудь в сериал буквально через строчку и смотрите по какому пути программа идёт - возможно, что-то поймёте из изучения пути.
Ну и на схему надо посмотреть, что там, да как.
Хотя нет, карту он находит, но на выборе впадает в ступор
При чем ладно, была бы такая ерунда постоянно, но нет, он работает, как положено и вдруг происходит эта ерунда
Т.е. после строки 69 сразу прыгает на 67?
Ну, вот, уже лучше. Значит PICC_IsNewCardPresent сразу же возвращает true.
Теперь лезем в библиотеку, ставим печать там и пытаемся понять почему так.
Не удивлюсь, если выяснится ошибка подключения или ещё что. В общем, ставьте печать, смотрите, анализируйте, думайте.
[quote=ЕвгенийП]
ставим печать там.
[quote]
Это как?
Я подношу ключ, он находит его, но после выбора нет никаких сообщений
Добавив сообщение в сам цикл выбора, получил, что он не выходит из сего цикла
В ообщем я заменил while на if {return;} вроде пашет
В ообщем я заменил while на if {return;} вроде пашет
безобразие
Добавив сообщение в сам цикл выбора, получил, что он не выходит из сего цикла
По Вашему прошлому сообщению я понял, что она туда не входит.
А печать в библиотеку ставится также, как и в любое другое место.
И еще проблема, Решил не создавать новую тему
Я хотел добавить защито по кодовому замку, но он не хочет открывать дверь, даже если он правильный.
Добаваи в сериал вывод кода по ходу написания получил:
При этом замечу, что последняя строчка появляется сразу за предпоследней, и я ничего не нажимал
код:
int i = 0; char right[5] = "1233"; char passw[5]; lcd.clear(); lcd.setCursor(0, 0); lcd.print("Enter"); lcd.setCursor(0,1); lcd.print("Password:"); char key = keypad.getKey(); while(key != '#'){ key = keypad.getKey(); if(key && key != '*' && key!='#') {passw[i] = key; Serial.println(passw); i++; } else if (key == '*') { i = 0; } } Serial.println("if "); Serial.println(passw); Serial.println(right); if(right ==passw) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Open"); antihack = 0; tone(22, 2000, 3000); digitalWrite(2, 1); servo.write(90); delay(3000); digitalWrite(2, 0); servo.write(0); return; } else return;Добавив сообщение в сам цикл выбора, получил, что он не выходит из сего цикла
По Вашему прошлому сообщению я понял, что она туда не входит.
А печать в библиотеку ставится также, как и в любое другое место.
Не, в цикл входила, просто у меня то-ли порт лаганул, то-ли монитор порта сообщение про поиск карты не появлось, и я подумал что скетч его проскочил.
А вот про печать понятней не стало
Продолжение вывода, в том месте, где дуина сравнивает пароль с правильным
А вот про печать понятней не стало
Я имел в виду, что если у Вас непонятки и хочется вставить печать в тексты библиотеки, это можно делать точно также, как Вы вставляете её в свой скетч.
В строке 10 - нет проверки на выход за границы массива. В строке 27 - массивы так не сравниваются, вы сравниваете указатели на них, они всегда разные, даже если содержимое массивов одинаковое. Поправленный навскидку код:
int i = 0; char right[5] = "1233"; char passw[5] = {0}; lcd.clear(); lcd.setCursor(0, 0); lcd.print("Enter"); lcd.setCursor(0,1); lcd.print("Password:"); char key = keypad.getKey(); while(key != '#' && i < 5) { key = keypad.getKey(); if(key && key != '*' && key!='#') { passw[i] = key; Serial.println(passw); i++; } else if (key == '*') { i = 0; } } Serial.println("if "); Serial.println(passw); Serial.println(right); if( !strcmp(right, passw) ) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Open"); antihack = 0; tone(22, 2000, 3000); digitalWrite(2, 1); servo.write(90); delay(3000); digitalWrite(2, 0); servo.write(0); return; } else return;