I did write my code which worked perfectly.
I now want to add a method to add a key to open the door by mobile phone and tried adding iot cloud.
But for some reason it resets all the time.
Once I remove the comment markings for the wifi.h and the connection for that theres no instant reset but it then seems to reset once I use the fingerprint sensor which works perfectly without iot cloud.
But then it seems to connect sometimes to the cloud (seen because of the last online marker in the cloud) and sometimes it does'nt (probably because of crashes and resets).
So what am I doing wrong?
I tried around all morning and came to the conclusion the problem must be any incompatibility between the cloud stuff and the esp or the libraries used before.
My board is an ESP32 devkit V1. Im using a R503 Fingerprint sensor a RGBLED a switch a button and a motor driver (without motor until now because it's still shipping).
As said all works perfectly fine and without any error once I use wifi.h and remove all that IOT stuff.
Here's the code:
//#include <WiFi.h>
#include <Arduino_ConnectionHandler.h>
#include <ArduinoIoTCloud.h>
#include <ArduinoOTA.h>
#include <HardwareSerial.h>
#include <Bounce2.h>
#include <AccelStepper.h>
#include <Adafruit_Fingerprint.h>
#include <EEPROM.h>
// Passwörter (WLAN etc.)
#define WLAN_Name "****"
#define WLAN_Passwort "****"
#define OTA_Passwort "****"
#define BoardID "****"
#define SecretKey "****"
//Serielle Schnittstelle2 initialisieren
HardwareSerial SerialPort2(2); // use UART2
// Variable für Online (ioT Cloud)
bool DoorOnlineOpen;
bool OpenLED;
bool StromausfallSpeicher;
// Variablen Fingerprint Sensor
uint8_t id;
byte FingerID = 0;
byte AdminFinger = 0;
void (*resetFunc)(void) = 0; //declare reset function at address 0
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&SerialPort2);
// Variablen Schloss
const byte DoorOPENAlarm = 14; // Reed Kontakt HIGH = Tür geöffnet, LOW = Tür geschlossen
const byte LockDoorSwitch = 22; // LOW = Schnapper, HIGH = Doppelt verriegelt ?????????
const byte OpenDoorButton = 23; // Taster zum Tür öffnen (innen) HIGH = gedrückt
Bounce DBDoorOPENAlarm = Bounce(); // 3 Debounce objecte für Taster/Schalter initialisieren
Bounce DBLockDoorSwitch = Bounce(); // 3 Debounce objecte für Taster/Schalter initialisieren
Bounce DBOpenDoorButton = Bounce(); // 3 Debounce objecte für Taster/Schalter initialisieren
// Variablen Motor
const bool EEpromOn = 0; // Soll Stromausfall während Bewegung detektiert werden? Achtung nur ca 10.000 Zyklen möglich! 0=AUS 1=AN
const byte MicroSteps = 4; // Eingestellte Microsteps am Stepper Controller
const byte MotorSteps = 200; // 200 Hardware-Steps per Umdrehung des Motors
const int Steps = MotorSteps * MicroSteps; // Gesamte reelle Steps Pro Umdrehung
const byte StepPin = 18;
const byte DirPin = 5;
const byte ENPin = 19;
const int Verriegeln = 2 * Steps; // Anzahl Umdrehungen zum Verriegeln (aus Nullstellung des Schlüssels)
const int Entriegeln = -2 * Steps; // Anzahl Umdrehungen zum Entriegeln (aus Nullstellung des Schlüssels)
const int Oeffnen = -65 * MicroSteps; // Anzahl Motorsteps * MicroSteps zum öffnen des Schnappers (aus Nullstellung des Schlüssels) //////////////////////// NOCH ANPASSEN !!!!!!
AccelStepper Motor(1, StepPin, DirPin); // AccelStepper Objekt Motor erstellen 1= Motortreiber verwenden
// Schlüsselpositionen
#define Nullstellung 0
#define Verriegelt 1
bool SchluesselPos = Nullstellung; // -1=Schlüssel links gedreht (Schnapper auf), 0=Schlüssel Nullstellung (Schnapper zu), 2= Schlüssel doppelt verriegelt
// Variablen LED
const byte LEDRed = 27;
const byte LEDGreen = 26;
// Variablen Musik
void setup() {
// LEDs initialisieren
pinMode(LEDRed, OUTPUT);
pinMode(LEDGreen, OUTPUT);
digitalWrite(LEDRed, HIGH); // HIGH = AUS
digitalWrite(LEDGreen, HIGH); // HIGH = AUS
// Serielle Schnittstellen initialisieren
Serial.begin(115200); // Serielle Ausgabe an
SerialPort2.begin(57600, SERIAL_8N1, 16, 17); // Serielle Schnittstelle 2 an
//WLAN verbinden
/*
WiFi.begin(WLAN_Name, WLAN_Passwort);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Verbindung wird hergestellt...");
}
Serial.println("WLAN Verbunden!");
*/
ArduinoCloud.setBoardId(BoardID);
ArduinoCloud.setSecretDeviceKey(SecretKey);
ArduinoCloud.addProperty(DoorOnlineOpen, READWRITE, ON_CHANGE, onDoorOnlineOpenChange);
ArduinoCloud.addProperty(OpenLED, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(StromausfallSpeicher, READWRITE, ON_CHANGE, NULL);
WiFiConnectionHandler ArduinoIoTPreferredConnection(WLAN_Name, WLAN_Passwort);
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
// OTA Update einrichten
ArduinoOTA.setHostname("Tuerschloss");
ArduinoOTA.setPassword(OTA_Passwort);
ArduinoOTA.begin();
ArduinoOTA.handle(); // OTA Update starten
FingerprintSetup(); // Fingerprint Sensor initialisieren
////////////////////////////////////////////////////////////////////////////////////////////// STROM-AUS VARIABLE ONLINE prüfen!
// Falls EEprom aktiv, initialisieren, einlesen und auf Stromausfall prüfen
if (EEpromOn == 1) {
EEPROM.begin(4); // EEprom initialisieren 4 Byte lang (minimum)
// Für EEPROM resett nach Stromausfall Kommentar dieser 2 Zeilen einmalig entfernen
/*
EEPROM.write(0, 255); // Zum Schluss EEprom wieder auf 255 setzen
EEPROM.commit();
*/
if (EEPROM.read(0) == 0) {
Error(); // EEprom war auf 0 also Stromausfall während Bewegung (Position unsicher, abschalten!)
}
}
// Motorvariablen initialisieren
pinMode(StepPin, OUTPUT);
pinMode(DirPin, OUTPUT);
pinMode(ENPin, OUTPUT);
Motor.setEnablePin(ENPin);
Motor.setMaxSpeed(1000);
Motor.setAcceleration(4000); // 1000 Steps/Sek = 1 Sek bis volle Geschwindigkeit. 4000 = 1/4 Sek
// Taster uns Schalter initialisieren
DBDoorOPENAlarm.attach(DoorOPENAlarm, INPUT_PULLUP); // 0 = Tür geschlossen, 1 = Tür offen
DBDoorOPENAlarm.interval(5);
DBLockDoorSwitch.attach(LockDoorSwitch, INPUT_PULLUP); // 0 = Schalter Position ?????????????????????????????????????????
DBLockDoorSwitch.interval(5);
DBOpenDoorButton.attach(OpenDoorButton, INPUT_PULLUP); // 0 = Taster gedrückt
DBOpenDoorButton.interval(5);
}
void loop() {
ArduinoOTA.handle(); // OTA Update starten
ArduinoCloud.update(); // Online Taste aktualisieren
DBLockDoorSwitch.update(); // Auslesen mit "!DBLockDoorSwitch.read()" (INVERTIERT! Dann 1= Schalter auf AN)
if (!DBLockDoorSwitch.read() == 0) { // Wenn Schalter auf Schnapper steht
if (SchluesselPos == Nullstellung) { // Falls schon auf Nullstellung
digitalWrite(LEDRed, LOW); // LED auf gelb
digitalWrite(LEDGreen, LOW);
} else if (SchluesselPos == Verriegelt) { // Falls verriegelt entriegeln und LED auf gelb
Serial.println("MOTOR AN");
Motor.runToNewPosition(Nullstellung);
Serial.println("MOTOR AUS");
SchluesselPos = Nullstellung;
digitalWrite(LEDRed, LOW); // LED auf gelb
digitalWrite(LEDGreen, LOW);
}
} else if (!DBLockDoorSwitch.read() == 1) {
if (SchluesselPos == Verriegelt) { // Falls schon verriegelt
digitalWrite(LEDRed, LOW); // LED auf rot
digitalWrite(LEDGreen, HIGH);
} else if (SchluesselPos == Nullstellung) { // Falls noch auf Nullstellung und verriegeln eingestellt, auf eingestellte Position fahren
Serial.println("MOTOR AN");
Motor.runToNewPosition(Verriegeln);
Serial.println("MOTOR AUS");
SchluesselPos = Verriegelt;
digitalWrite(LEDRed, LOW); // LED auf rot
digitalWrite(LEDGreen, HIGH);
}
}
DBOpenDoorButton.update(); // Auslesen mit "!DBOpenDoorButton.read()" (INVERTIERT! Dann 1 = Öffnen)
if (!DBOpenDoorButton.read() == 1) {
DoorOpen();
DBOpenDoorButton.update(); // Nach DoorOpen() Nochmal updaten ansonsten fährt er 2x durch DoorOpen()
}
// START FINGERPRINT SENSOR LOOP
getFingerprintID(); // Check Fingerprint
Checkfinger(); // Entsprechend erkanntem Print handeln
}
void FingerprintSetup() {
Serial.println("\n\nFinger detect test");
finger.begin(57600); // set the data rate for the sensor serial port
delay(5);
if (finger.verifyPassword()) {
Serial.println("Found fingerprint sensor!");
} else {
Serial.println("Did not find fingerprint sensor!");
while (1) {
Error();
}
}
// LEDs aus falls noch an
finger.LEDcontrol(FINGERPRINT_LED_OFF, 0, FINGERPRINT_LED_BLUE);
finger.LEDcontrol(FINGERPRINT_LED_OFF, 0, FINGERPRINT_LED_RED);
finger.LEDcontrol(FINGERPRINT_LED_OFF, 0, FINGERPRINT_LED_PURPLE);
// Einschaltsignal 10x15ms blau
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 15, FINGERPRINT_LED_BLUE, 10);
Serial.println(F("Reading sensor parameters"));
finger.getParameters();
Serial.print(F("Status: 0x"));
Serial.println(finger.status_reg, HEX);
Serial.print(F("Sys ID: 0x"));
Serial.println(finger.system_id, HEX);
Serial.print(F("Capacity: "));
Serial.println(finger.capacity);
Serial.print(F("Security level: "));
Serial.println(finger.security_level);
Serial.print(F("Device address: "));
Serial.println(finger.device_addr, HEX);
Serial.print(F("Packet len: "));
Serial.println(finger.packet_len);
Serial.print(F("Baud rate: "));
Serial.println(finger.baud_rate);
finger.getTemplateCount();
if (finger.templateCount == 0) {
Serial.print("Sensor doesn't contain any fingerprint Going to run 'enroll.");
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 100, FINGERPRINT_LED_RED, 50);
delay(5000);
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_RED, 0);
newfingerprint();
} else {
Serial.println("Waiting for valid finger...");
Serial.print("Sensor contains ");
Serial.print(finger.templateCount);
Serial.println(" templates");
}
}
uint8_t getFingerprintID() {
uint8_t p = finger.getImage();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image taken");
break;
case FINGERPRINT_NOFINGER:
FingerID = 0;
AdminFinger = 0;
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging error");
return p;
default:
Serial.println("Unknown error");
return p;
}
// fingerprint read ok
p = finger.image2Tz();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return p;
case FINGERPRINT_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return p;
case FINGERPRINT_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return p;
default:
Serial.println("Unknown error");
return p;
}
// fingerprint converted ok
p = finger.fingerSearch();
if (p == FINGERPRINT_OK) {
Serial.println("Found a print match!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return p;
} else if (p == FINGERPRINT_NOTFOUND) {
Serial.println("Did not find a match");
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_RED, 10);
return p;
} else {
Serial.println("Unknown error");
return p;
}
// found a match!
Serial.print("Found ID #");
Serial.print(finger.fingerID);
Serial.print(" with confidence of ");
Serial.println(finger.confidence);
FingerID = finger.fingerID;
return finger.fingerID;
}
// Add new fingerprint
void newfingerprint() // run over and over again
{
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_PURPLE, 0);
Serial.println("Ready to enroll a fingerprint!");
Serial.println("Id will be given in order First finger print is Admin");
finger.getTemplateCount();
Serial.print("Sensor contains ");
Serial.println(finger.templateCount);
id = (finger.templateCount + 1);
if (id == 0) { // ID #0 not allowed, try again!
Serial.println("first run setting id to 1");
id = 1;
return;
}
Serial.print("Enrolling ID #");
Serial.println(id);
while (!getFingerprintEnroll())
;
}
uint8_t getFingerprintEnroll() {
int s = -1;
Serial.print("Waiting for valid finger to enroll as #");
Serial.println(id);
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_PURPLE, 0);
while (s != FINGERPRINT_OK) {
s = finger.getImage();
switch (s) {
case FINGERPRINT_OK:
Serial.println("Image taken");
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_PURPLE, 1);
delay(2000);
break;
case FINGERPRINT_NOFINGER:
break;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
break;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging error");
break;
default:
Serial.println("Unknown error");
break;
}
}
// OK success!
s = finger.image2Tz(1);
switch (s) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return s;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return s;
case FINGERPRINT_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return s;
case FINGERPRINT_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return s;
default:
Serial.println("Unknown error");
return s;
}
// Cherck if Finger already exists in Database and skip if so
s = finger.fingerSearch();
if (s == FINGERPRINT_NOTFOUND) {
Serial.println("Did not find an existing match");
} else if (s == FINGERPRINT_OK) {
Serial.print("Found ID #");
Serial.println(finger.fingerID);
Serial.println("Known Fingerprint detected, skipping");
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 30, FINGERPRINT_LED_RED, 5);
delay(2000);
return s;
} // End of Check
Serial.println("Remove finger");
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_BLUE, 0);
s = 0;
while (s != FINGERPRINT_NOFINGER) {
s = finger.getImage();
}
Serial.print("ID ");
Serial.println(id);
s = -1;
Serial.println("Place same finger again");
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_PURPLE, 0);
while (s != FINGERPRINT_OK) {
s = finger.getImage();
switch (s) {
case FINGERPRINT_OK:
Serial.println("Image taken");
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_PURPLE, 1);
break;
case FINGERPRINT_NOFINGER:
break;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
break;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging error");
break;
default:
Serial.println("Unknown error");
break;
}
}
// OK success!
s = finger.image2Tz(2);
switch (s) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return s;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication error");
return s;
case FINGERPRINT_FEATUREFAIL:
Serial.println("Could not find fingerprint features");
return s;
case FINGERPRINT_INVALIDIMAGE:
Serial.println("Could not find fingerprint features");
return s;
default:
Serial.println("Unknown error");
return s;
}
// OK converted!
Serial.print("Creating model for #");
Serial.println(id);
s = finger.createModel();
if (s == FINGERPRINT_OK) {
Serial.println("Prints matched!");
} else if (s == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return s;
} else if (s == FINGERPRINT_ENROLLMISMATCH) {
Serial.println("Fingerprints did not match");
newfingerprint();
// return s;
} else {
Serial.println("Unknown error");
return s;
}
Serial.print("ID ");
Serial.println(id);
s = finger.storeModel(id);
if (s == FINGERPRINT_OK) {
Serial.println("Stored!");
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_BLUE, 20);
finger.LEDcontrol(FINGERPRINT_LED_GRADUAL_ON, 200, FINGERPRINT_LED_BLUE);
delay(2000);
finger.LEDcontrol(FINGERPRINT_LED_GRADUAL_OFF, 200, FINGERPRINT_LED_BLUE);
delay(2000);
finger.LEDcontrol(FINGERPRINT_LED_GRADUAL_ON, 200, FINGERPRINT_LED_BLUE);
delay(2000);
finger.LEDcontrol(FINGERPRINT_LED_GRADUAL_OFF, 200, FINGERPRINT_LED_BLUE);
delay(2000);
} else if (s == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication error");
return s;
} else if (s == FINGERPRINT_BADLOCATION) {
Serial.println("Could not store in that location");
return s;
} else if (s == FINGERPRINT_FLASHERR) {
Serial.println("Error writing to flash");
return s;
} else {
Serial.println("Unknown error");
return s;
}
return true;
}
void deletedata() {
finger.emptyDatabase();
Serial.println("All fingerprints Deleted");
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 5, FINGERPRINT_LED_RED, 0);
Serial.println("Doing a soft reset of the arduino");
resetFunc(); //call reset
}
void Checkfinger() {
if (FingerID == 1) { // Adminfinger erkannt
Serial.println("Admin Fingerprint detected");
AdminFinger = (AdminFinger + 1);
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_BLUE, 1);
if (AdminFinger == 5) {
finger.LEDcontrol(FINGERPRINT_LED_ON, 0, FINGERPRINT_LED_PURPLE);
delay(1000);
getFingerprintID();
if (FingerID == 0) {
Serial.println("ADD NEW USER");
newfingerprint();
}
}
if (AdminFinger >= 10) {
finger.LEDcontrol(FINGERPRINT_LED_ON, 0, FINGERPRINT_LED_RED);
delay(1000);
getFingerprintID(); // Prüfen ob Finger losgelassen
if (FingerID == 1) { // Wenn nicht, löschen und Reset
Serial.println("DELETE ALL USERS");
deletedata();
}
Serial.println("Doing a soft reset of the arduino");
resetFunc(); //call reset
}
} else if (FingerID != 0) {
Serial.println("Normal fingerprint detected");
finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_BLUE, 5);
DoorOpen();
}
}
void DoorOpen() {
if (EEpromOn == 1) { // Falls EEpromON Variable gesetzt
EEPROM.write(0, 0); // Vor Beginn EEprom auf 0 setzen (Stromausfallerkennung)
EEPROM.commit();
Serial.print("EEprom: ");
Serial.println(EEPROM.read(0));
}
/////////////////////////////////////////////////////////////////////////////////////////// STROM-AUS VARIABLE ONLINE SPEICHERN!
Motor.enableOutputs();
Serial.println("MOTOR öffnet");
if (SchluesselPos == Nullstellung) {
Motor.runToNewPosition(Oeffnen);
} else if (SchluesselPos == Verriegelt) {
Motor.runToNewPosition(Entriegeln);
Motor.runToNewPosition(Oeffnen);
}
digitalWrite(LEDRed, HIGH); // LED auf grün
digitalWrite(LEDGreen, LOW);
finger.LEDcontrol(FINGERPRINT_LED_ON, 0, FINGERPRINT_LED_BLUE); // Fingerprint LED AN
while (DBDoorOPENAlarm.read() == 0) { // Warten bis Tür geöffnet wurde
DBDoorOPENAlarm.update();
//////////////////////////////////////// Ggf. Zeit einfügen nach der autom. verriegelt wird
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Eintritts-Musik einfügen!
Serial.println("MOTOR Fährt auf Schnapper");
Motor.runToNewPosition(Nullstellung); // Sobald Tür geöffnet wurde Schnapper freigeben //// Nullstellung (0) RICHTIG? oder eher -Oeffnen
SchluesselPos = Nullstellung;
finger.LEDcontrol(FINGERPRINT_LED_OFF, 0, FINGERPRINT_LED_BLUE);
digitalWrite(LEDRed, LOW); // LED auf gelb
digitalWrite(LEDGreen, LOW);
while (DBDoorOPENAlarm.read() == 1) {
DBDoorOPENAlarm.update(); // Warten bis Tür geschlossen wurde
}
DBLockDoorSwitch.update(); // Auslesen mit "!DBLockDoorSwitch.read()" (INVERTIERT! Dann 1= Schalter auf AN)
if (!DBLockDoorSwitch.read() == 1) {
delay(500); // Sicherheitshalber delay damit Tür auch ganz zu ehe verschlossen wird
Serial.println("MOTOR verriegelt falls eingestellt");
Motor.runToNewPosition(Verriegeln); // Falls verriegeln eingestellt, auf eingestellte Position fahren
SchluesselPos = Verriegelt;
digitalWrite(LEDRed, LOW); // LED auf rot
digitalWrite(LEDGreen, HIGH);
}
Serial.println("MOTOR AUS");
Motor.disableOutputs();
/////////////////////////////////////////////////////////////////////////////////////////// STROM-AUS VARIABLE ONLINE ZURÜCKSETZEN
if (EEpromOn == 1) { // Falls EEpromON Variable gesetzt
EEPROM.write(0, 255); // Zum Schluss EEprom wieder auf 255 setzen
EEPROM.commit();
Serial.print("EEprom: ");
Serial.println(EEPROM.read(0));
}
return;
}
void onDoorOnlineOpenChange() { // Add your code here to act upon DoorOnlineOpen change
//if (DoorOnlineOpen == 1) {
DoorOpen();
//}
}
void Error() {
Serial.println("FEHLER! MOTOR AUS, LED AN, PROGRAMMENDE BIS RESET!");
finger.LEDcontrol(FINGERPRINT_LED_ON, 0, FINGERPRINT_LED_RED);
Motor.disableOutputs();
delay(600000);
}