již jednou jsem zde řešil můj problém s tím, že se mně zastaví po nějaké době (někdy po pár hodinách, někdy to trvá klidně 3-4 dny) samovolně cyklus programu a já opravdu nevím proč. Zkusil jsem to řešit kompletně přeprogramováním (podstatně lepším řešením než minule, zkusil jsem napájet Arduino samostatným (5 V zdrojem přes USB port), neboť jsem měl podezření buď na přehřátí samotného stabilizátoru, který jsem si v obvodu sestavil, který mně činí z 12 V 9 V konstantní, (nebo na jeho nesprávnou funkci, možná z důvodu poklesu vstupního napětí při sepnutí relé a připojení zátěže) - ovšem tím to tedy nebude.
Dle udaných důvodů se někdy stalo, že se cyklus zastavil, kdy přestala blikat žlutá LED dioda úplně (mám tu diodu vlastně zvlášť a pro uživatele kontroluje chod kontroléru Někdy se stalo, že dioda LED žlutá místo blikání (kde vidíte v kódu - v rámci sekund) prostě svítila trvale... Ovšem kontrolér zamrznul... A někdy se stalo, což je nejméně žádoucí, že k zamrznutí kontroléru došlo v cyklu, kdy byl schválený přístup a byl přiveden impulz na relátka a došlo k otevření el. mag. ventilů a došlo k odpočtu (50 s) - tohle je asi nejméně žádoucí - zamrzlo to třeba při 45 vteřinách a pomohl jen restart kontroléru...... Viz kod níže, umažu pouze některé texty a v datové struktuře uživatele (je jich tam 217, pro vzor nechám pouze dva). Budu moc vděčný za každou radu, protože nerad bych restartoval zařízení watchdogem, ale opravdu přišel na skutečný problém... Mě napadá, že by problémem mohl být ten čas.. Ale nemohu ho odstranit, prostě měřím tímto časem, kdy vlastně dojde k restartu hodnot (tzn. odblokování karet a přiřazení času přístupu zpět na výchozí hodnotu, tj. 50s). Dále viz kód. Budu opravdu vděčný za každou radu.
Používám Arduino Mega 2560, klon.
Kód: Vybrat vše
#include <TimeLib.h> // Time library
#include <SPI.h> // SPI library
#include <Wire.h> // Include Wire.h to control I2C
#include <LiquidCrystal_I2C.h> //Download & include the code library can be downloaded below
//#include <EEPROM.h>
#include <avr/pgmspace.h> //PROGMEM LIBRARY
#include <avr/wdt.h> //MEMORY (FREE RAM)
// Definig the relay pin
#define RELAY_IN1 32
#define RELAY_IN2 30
#define RELAY_IN3 31
#define RELAY_IN4 33
// LED
byte LED_RED = 53;
byte LED_YELLOW = 52;
byte LED_BLUE = 48;
//Cyklus
byte a = 0; // pro hledani karty
byte b = 0; // cas pro cyklus (meni se, cas)
byte w = 0; // pro cyklus schvaleno
byte d = 0; // pro nulovani hodnot
//texty LCD
byte text = 0;
// BEEPER
byte BEEP_BEEP = 25;
// BUTTON
byte vyp = 6;
byte button = HIGH;
// MINUTES
int minuty = 778;
byte pocet_dnu = 0;
boolean nebyl_tam = 0; //Pro zamitnuti
// variables of times
int h,m,s;
int set_hours=00;
int set_minutes=00;
int set_seconds=00;
int secs=1000;
// LCD display
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE); // Initialize LCD Display at address 0x27
// Pohyblivy napis schvaleno
char array1[17] = " Schvaleno ";//the string to print on the LCD
byte tim = 100; //the value of delay time
// RFID reader
#define MAX_BITS 100 // max number of bits
#define WEIGAND_WAIT_TIME 1 // time to wait for another weigand pulse.
unsigned char databits[MAX_BITS]; //
unsigned char bitCount; // number of bits currently captured
unsigned char flagDone; // goes low when data is currently being captured
unsigned int weigand_counter; // countdown until we assume there are no more bits
unsigned long facilityCode= 0; // decoded facility code
unsigned long cardCode=0; // decoded card code
// pro zobrazovani nactenych bitu RFID cteckou
// interrupt that happens when INTO goes low (0 bit)
void ISR_INT0() {
Serial.print("0"); // uncomment this line to display raw binary
bitCount++;
flagDone = 0;
weigand_counter = WEIGAND_WAIT_TIME;
}
// interrupt that happens when INT1 goes low (1 bit)
void ISR_INT1() {
Serial.print("1"); // uncomment this line to display raw binary
databits[bitCount] = 1;
bitCount++;
flagDone = 0;
weigand_counter = WEIGAND_WAIT_TIME;
}
//Vytvoření struktůry typu Uzivatel
struct Uzivatel {
const PROGMEM char *jmeno; // jméno uživatele
const PROGMEM unsigned long card; //cislo mag. cipu karty
byte total_time; // celkovy cas po kterou dobu budou "otevřeny" relátka - výchozí hodnota 50 - mění se
boolean blokovan; // karta se zablokuje, pokud uživatel vyčerpá svých 50 s v rámci 13 h (odpovídá těmi 780 minutami.. následne dojde k restartu hodnot a zase se každému uživateli přiřadí 50 s.
boolean trvale_blokovan; // Administrátorské zablokování karty
};
Uzivatel user []
{
{"Eduard", 1555578, 50, 0, 0},//0
{"xxxxxx", 1363527, 50, 0, 0};//1
};
// nasledujici kody pro kontrolu a zjisteni delky pole
byte length_users = sizeof(user) / sizeof (user[0]);
void setup() {
//relay
Serial.begin(9600); //Serial output
//RFID READER
Serial.println (F("RFID readers"));
// binds the ISR functions to the falling edge of INTO and INT1
attachInterrupt(0, ISR_INT0, FALLING);
attachInterrupt(1, ISR_INT1, FALLING);
weigand_counter = WEIGAND_WAIT_TIME;
// Initialization of the relay
pinMode (RELAY_IN1, OUTPUT);
pinMode (RELAY_IN2, OUTPUT);
pinMode (RELAY_IN3, OUTPUT);
pinMode (RELAY_IN4, OUTPUT);
digitalWrite(RELAY_IN1, HIGH);
digitalWrite(RELAY_IN2, HIGH);
digitalWrite(RELAY_IN3, HIGH);
digitalWrite(RELAY_IN4, HIGH);
// LED
pinMode(LED_RED, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
pinMode (LED_YELLOW, OUTPUT);
// Beeper
pinMode(BEEP_BEEP, OUTPUT);
digitalWrite(BEEP_BEEP, HIGH); // High = off
//Button
pinMode (vyp, INPUT);
//Display
lcd.begin (16,2);
pinMode (2, INPUT); //DATA0 (INT0)
pinMode (3, INPUT); //DATA1 (IN1)
}
//Funkce kvuli casu
void printChar()
{
// cas (ktery se zobrazuje na LCD displeji
Serial.print(h/10);
Serial.print(h%10);
Serial.print(":");
Serial.print(m/10);
Serial.print(m%10);
Serial.print(":");
Serial.print(s/10);
Serial.print(s%10);
Serial.println ();
}
void loop() {
// put your main code here, to run repeatedly:
lcd.clear ();
Serial.print (F("Pocet uzivatelu je: "));
Serial.println (length_users);
for(h=set_hours;h<24;h++) //hOURS
{
for(m=set_minutes;m<60;m++) //mINUTES
{
// navyseni p - pocet minut o +1 vlastne kazdou novou minut
minuty++;
Serial.print (F("Minuty po navyseni: "));
Serial.println (minuty);
//Nulovani hodnot
if (minuty == 780){
lcd.clear ();
lcd.setCursor (0,0);
lcd.print (F("Vyckej provadim"));
lcd.setCursor (0,1);
lcd.print (F("RESTART HODNOT"));
digitalWrite (LED_BLUE, HIGH);
digitalWrite (LED_RED, HIGH);
digitalWrite (LED_YELLOW, HIGH);
minuty = 0;
for (d = 0; d != length_users; d++){
user[d].total_time = 50;
user[d].blokovan = 0;
}
delay (4000);
digitalWrite (LED_BLUE, LOW);
digitalWrite (LED_RED, LOW);
digitalWrite (LED_YELLOW, LOW);
}
for(s=set_seconds;s<60;s++) //Seconds
{
//Pocita pocet dnu zarizeni v chodu
if (set_hours == 23 && set_minutes == 59 && set_seconds == 59)
pocet_dnu++;
printChar();
nebyl_tam = 0;
digitalWrite (LED_YELLOW, HIGH);
delay(secs-(millis()%1000));
digitalWrite (LED_YELLOW, LOW);
// TOTO je jen text, který se mění
if (text >= 0 && text < 6) {
lcd.clear ();
lcd.setCursor(0, 0);
lcd.print(F(" SWver.: 03"));
Serial.println (F("SWver.: 03"));
}
if (text >= 6 && text <11) {
lcd.clear ();
lcd.setCursor(0, 0);
//lcd.print (F(" "));
lcd.print(F("Zarizeni v chodu"));
Serial.println (F("Zarizeni v chodu"));
}
if (text >= 11 && text <= 15) {
lcd.clear ();
lcd.setCursor(0, 0);
//lcd.print (F(" "));
lcd.print (F("D: "));
Serial.print (F("D: "));
Serial.println (pocet_dnu);
lcd.setCursor (4,0);
lcd.print (pocet_dnu);
lcd.setCursor (8, 0);
lcd.print(h/10);
lcd.print(h%10);
lcd.print(F(":"));
lcd.print(m/10);
lcd.print(m%10);
lcd.print(":");
lcd.print(s/10);
lcd.print(s%10);
}
text++;
if (text > 15)
text = 0;
lcd.setCursor(0, 1);
lcd.print(F("Pocet minut: "));
lcd.setCursor(13, 1);
lcd.print (minuty);
Serial.print (F("Pocet minut: "));
Serial.println (minuty);
/* lcd.setCursor (8, 0);
lcd.print(h/10);
lcd.print(h%10);
lcd.print(F(":"));
lcd.print(m/10);
lcd.print(m%10);
lcd.print(":");
lcd.print(s/10);
lcd.print(s%10); */
if (!flagDone) {
if (--weigand_counter == 0)
flagDone = 1;
}
// if we have bits and we the weigand counter went out
if (bitCount > 0 && flagDone) {
unsigned char i;
Serial.print(F("Read "));
Serial.println(bitCount);
Serial.print(F(" bits. "));
if (bitCount == 35) {
// 35 bit HID Corporate 1000 format
// facility code = bits 2 to 14
for (i=2; i<14; i++) {
facilityCode <<=1;
facilityCode |= databits[i];
}
Serial.println (facilityCode);
// card code = bits 15 to 34
for (i=14; i<34; i++) {
cardCode <<=1;
cardCode |= databits[i];
}
printBits();
}
else if (bitCount == 26) {
// standard 26 bit format
// facility code = bits 2 to 9
for (i=1; i<9; i++) {
facilityCode <<=1;
facilityCode |= databits[i];
}
Serial.println (facilityCode);
// card code = bits 10 to 23
for (i=3; i<25; i++) {
Serial.print (F("I: "));
Serial.println (i);
Serial.print (F("Databits: "));
Serial.println (databits [i]);
Serial.print (F("CARDCODE: "));
Serial.println (cardCode);
cardCode <<=1;
cardCode |= databits[i];
}
printBits();
}
else {
// you can add other formats if you want!
// Serial.println("Unable to decode.");
}
// cleanup and get ready for the next card
bitCount = 0;
facilityCode = 0;
cardCode = 0;
for (i=0; i<MAX_BITS; i++)
{
databits[i] = 0;
}
}
}
set_seconds=00;
}
set_minutes=00;
}
set_hours=00;
}
void printBits() {
Serial.print(F("FC = "));
Serial.print(facilityCode);
Serial.print(F(", CC = "));
Serial.println(cardCode);
for (a = 0; a != length_users; a++){
if (cardCode == user[a].card){
Serial.println(F("Autorizace OK"));
Serial.print (F("Uzivatel: "));
Serial.println (user[a].jmeno);
nebyl_tam = 1;
if (user[a].blokovan == 1){
digitalWrite (LED_RED, HIGH);
digitalWrite (BEEP_BEEP, LOW);
lcd.clear();
lcd.setCursor (0, 0);
lcd.print (F("Prekrocen denni"));
lcd.setCursor (0, 1);
lcd.print (F("limit."));
Serial.println (F("Prekrocen denni limit"));
delay (100);
digitalWrite (LED_RED, LOW);
digitalWrite (BEEP_BEEP, HIGH);
delay (100);
digitalWrite (LED_RED, HIGH);
digitalWrite (BEEP_BEEP, LOW);
delay (100);
digitalWrite (LED_RED, LOW);
digitalWrite (BEEP_BEEP, HIGH);
delay (100);
digitalWrite (LED_RED, HIGH);
digitalWrite (BEEP_BEEP, LOW);
delay (100);
digitalWrite (LED_RED, LOW);
digitalWrite (BEEP_BEEP, HIGH);
delay (100);
digitalWrite (LED_RED, HIGH);
delay (100);
digitalWrite (BEEP_BEEP, LOW);
delay (100);
digitalWrite (LED_RED, LOW);
delay (100);
digitalWrite (LED_RED, HIGH);
digitalWrite (BEEP_BEEP, HIGH);
delay (2000);
lcd.clear();
lcd.setCursor (0, 0);
lcd.print (F("Reset bude za: "));
lcd.setCursor (0, 1);
lcd.print (780 - minuty);
lcd.setCursor (4, 1);
lcd.print (F("minut."));
delay (5000);
digitalWrite (LED_RED, LOW);
break;
}
else if (user[a].trvale_blokovan == 1) {
digitalWrite (LED_RED, HIGH);
digitalWrite (BEEP_BEEP, LOW);
lcd.clear();
lcd.setCursor (0, 0);
lcd.print (F("Karta byla"));
lcd.setCursor (0, 1);
lcd.print (F("zablokovana."));
Serial.println (F("Karta byla zablokovana."));
delay (200);
digitalWrite (LED_RED, LOW);
digitalWrite (BEEP_BEEP, HIGH);
delay (200);
digitalWrite (LED_RED, HIGH);
digitalWrite (BEEP_BEEP, LOW);
delay (200);
digitalWrite (LED_RED, LOW);
digitalWrite (BEEP_BEEP, HIGH);
delay (200);
digitalWrite (LED_RED, HIGH);
digitalWrite (BEEP_BEEP, LOW);
delay (200);
digitalWrite (LED_RED, LOW);
digitalWrite (BEEP_BEEP, HIGH);
delay (200);
digitalWrite (LED_RED, HIGH);
delay (2000);
lcd.clear();
lcd.setCursor (0, 0);
lcd.print (F("Kontaktuj admin."));
lcd.setCursor (0, 1);
lcd.print (F("xxx"));
delay (2000);
lcd.clear();
lcd.setCursor (0, 0);
lcd.print (F("Jmeno: "));
lcd.setCursor (8, 0);
lcd.print (user[a].jmeno);
lcd.setCursor (0, 1);
lcd.print (F("ID: "));
lcd.setCursor (5, 1);
lcd.print (user[a].card);
delay (5000);
digitalWrite (LED_RED, LOW);
break;
}
else {
b = user[a].total_time;
lcd.clear();
lcd.setCursor(0, 0);
for (int positionCounter1 = 0; positionCounter1 < 16; positionCounter1++)
{
digitalWrite (LED_BLUE, HIGH);
lcd.print(array1[positionCounter1]); // Print a message to the LCD.
delay(tim); //wait for 250 microseconds
}
// zde na displeji se zobrazi napis cepuj a pod nim jmeno daneho uzivatele
lcd.setCursor(0, 1);
lcd.print(F("Cepuj: "));
Serial.println (F("Cepuj: "));
lcd.setCursor(0, 0);
lcd.print (F(" "));
lcd.setCursor(0, 0);
lcd.print (user[a].jmeno);
//Cyklus, pro odpocet cepovani
for (w = b; w > 0; w = w - 1) {
digitalWrite(RELAY_IN1, LOW);
digitalWrite(RELAY_IN2, LOW);
digitalWrite(RELAY_IN3, LOW);
digitalWrite(RELAY_IN4, LOW);
digitalWrite (LED_BLUE, HIGH);
// Vypis casu na LCD displej, prvni podminka je kvuli casu < 10 s
if (w < 10) {
lcd.setCursor (0,1);
lcd.print (F(" "));
lcd.setCursor (0,1);
lcd.print (F("Cepuj: "));
lcd.print (w);
Serial.println (w);
}
else {
lcd.setCursor (7,1);
lcd.print (w);
Serial.println (w);
}
user[a].total_time = w;
if (user[a].total_time == 1)
user[a].blokovan = 1;
button = digitalRead (vyp);
if (button == LOW) //bylo tu LOW (ted tu dam high pro test)
{
lcd.setCursor (0,0);
lcd.print (F(" "));
lcd.setCursor (3,0);
lcd.print (F("!Ukonceno!"));
Serial.print (F("Ukonceno zmacknutim tlacitka"));
digitalWrite (LED_YELLOW, HIGH);
delay (300);
digitalWrite (LED_RED, HIGH);
delay (300);
digitalWrite (LED_BLUE, HIGH);
delay (300);
digitalWrite (LED_YELLOW, LOW);
delay (300);
digitalWrite (LED_RED, LOW);
delay (300);
digitalWrite (LED_BLUE, LOW);
delay (300);
break;
}
delay (1000);
}
digitalWrite (LED_BLUE, LOW);
digitalWrite(RELAY_IN1, HIGH);
digitalWrite(RELAY_IN2, HIGH);
digitalWrite(RELAY_IN3, HIGH);
digitalWrite(RELAY_IN4, HIGH);
}
}
}
if (nebyl_tam == 0)
{
lcd.clear();
digitalWrite (LED_RED, HIGH);
lcd.setCursor (0, 0);
lcd.print (F("Zamitnuto"));
Serial.println (F("Uzivatel zamitnut"));
digitalWrite(BEEP_BEEP, LOW);
delay(200);
digitalWrite(BEEP_BEEP, HIGH);
delay(200);
digitalWrite(BEEP_BEEP, LOW);
delay(200);
digitalWrite(BEEP_BEEP, HIGH);
delay(200);
digitalWrite(BEEP_BEEP, LOW);
delay(200);
digitalWrite(BEEP_BEEP, HIGH);
delay (2000);
lcd.clear ();
lcd.setCursor (0, 1);
lcd.print (F("ID: "));
lcd.setCursor (5, 1);
lcd.print (cardCode);
delay (10000);
digitalWrite (LED_RED, LOW);
}
lcd.clear ();
}