Глючит схема

1kovand1
Offline
Зарегистрирован: 31.08.2016

Сделал схему простой охранной ситемы, но она глючит: иногда она просто зависает, команды лок/анлок (Увидите в коде что это) работают (правда в случае с анлоком просто гаснет светодиод, надпись 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);
}

 

1kovand1
Offline
Зарегистрирован: 31.08.2016

Кстати, если не убирать метку с ридера, зависаний не происходит

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

1kovand1 пишет:

Кстати, если не убирать метку с ридера, зависаний не происходит

не убирай метку с ридера

1kovand1
Offline
Зарегистрирован: 31.08.2016

Не смешно

__Alexander
Offline
Зарегистрирован: 24.10.2012

Вы в лупе постоянно пишете в эпром? Киздец эпрому.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

45 строка прямо в loop означает, что EEPROM скорее всего уже мёртв.

Что говорит IDE после компиляции насчёт занимаемой памяти?

1kovand1
Offline
Зарегистрирован: 31.08.2016
 
Скетч использует 10 388 байт (4%) памяти устройства. Всего доступно 253 952 байт.
Глобальные переменные используют 516 байт (6%) динамической памяти, оставляя 7 676 байт для локальных переменных. Максимум: 8 192 байт.
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Понятно, значит, скоре всего память не при делах.

Тогда я бы начал копать в сторону убитого EEPROM, а также посмотрел бы на схемы включения.

1kovand1
Offline
Зарегистрирован: 31.08.2016

Нев Эпроме дело все, что связано с ним удалил, после первого же прочтения завис

1kovand1
Offline
Зарегистрирован: 31.08.2016

+ пример в либе тоже работает

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, видите, что такое завис. Вы же говорите, что на какие-то команды реагирует, так ведь?

Ну тогда ставьте вывод чего-нибудь в сериал буквально через строчку и смотрите по какому пути программа идёт - возможно, что-то поймёте из изучения пути.

Ну и на схему надо посмотреть, что там, да как.

1kovand1
Offline
Зарегистрирован: 31.08.2016

Хотя нет, карту он находит, но на выборе впадает в ступор

1kovand1
Offline
Зарегистрирован: 31.08.2016

При чем ладно, была бы такая ерунда постоянно, но нет, он работает, как положено и вдруг происходит эта ерунда

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Т.е. после строки 69 сразу прыгает на 67?

Ну, вот, уже лучше. Значит PICC_IsNewCardPresent сразу же возвращает true.

Теперь лезем в библиотеку, ставим печать там и пытаемся понять почему так.

Не удивлюсь, если выяснится ошибка подключения или ещё что. В общем, ставьте печать, смотрите, анализируйте, думайте.

1kovand1
Offline
Зарегистрирован: 31.08.2016

[quote=ЕвгенийП]

ставим печать там.

[quote]

Это как?

1kovand1
Offline
Зарегистрирован: 31.08.2016

Я подношу ключ, он находит его, но после выбора нет никаких сообщений

1kovand1
Offline
Зарегистрирован: 31.08.2016

Добавив сообщение в сам цикл выбора, получил, что он не выходит из сего цикла

1kovand1
Offline
Зарегистрирован: 31.08.2016

В ообщем я заменил while на if {return;} вроде пашет

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

1kovand1 пишет:

В ообщем я заменил while на if {return;} вроде пашет

безобразие

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

1kovand1 пишет:

Добавив сообщение в сам цикл выбора, получил, что он не выходит из сего цикла

По Вашему прошлому сообщению я понял, что она туда не входит.

А печать в библиотеку ставится также, как и в любое другое место.

1kovand1
Offline
Зарегистрирован: 31.08.2016

И еще проблема, Решил не создавать новую тему

Я хотел добавить защито по кодовому замку, но он не хочет открывать дверь, даже если он правильный.

Добаваи в сериал вывод кода по ходу написания получил:

При этом замечу, что последняя строчка появляется сразу за предпоследней, и я ничего не нажимал

код:

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;

 

1kovand1
Offline
Зарегистрирован: 31.08.2016

ЕвгенийП пишет:

1kovand1 пишет:

Добавив сообщение в сам цикл выбора, получил, что он не выходит из сего цикла

По Вашему прошлому сообщению я понял, что она туда не входит.

А печать в библиотеку ставится также, как и в любое другое место.

Не, в цикл входила, просто у меня то-ли порт лаганул, то-ли монитор порта сообщение про поиск карты не появлось, и я подумал что скетч его проскочил.

А вот про печать понятней не стало

1kovand1
Offline
Зарегистрирован: 31.08.2016

Продолжение вывода, в том месте, где дуина сравнивает пароль с правильным

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

1kovand1 пишет:

А вот про печать понятней не стало

Я имел в виду, что если у Вас непонятки и хочется вставить печать в тексты библиотеки, это можно делать точно также, как Вы вставляете её в свой скетч.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

В строке 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;