kemosabe Inserito: 21 febbraio 2020 Segnala Inserito: 21 febbraio 2020 Signori Buongiorno, proseguendo sulla comprensione della programmazione, ho un quesito da chiedervi. Preferirei non avere soluzioni, ma indicazioni sul procedimento da adottare. Dovrei inserire in una funzione esterna questo procedimento relativo alla temporizzazione di una porta con il suo relativo sensore magnetico arriva il comando alla funzione ho la porta chiusa, parte il tempo, se la porta rimane chiusa e scade il tempo, esco dalla funzione. se apro la porta mentre il tempo non è ancora scaduto, attendo di chiudere la porta per poter uscire dalla funzione, anche se nel frattempo è scaduto il tempo ci sto provando in vari modi da piu di una settimana, ma immancabilmente, sebbene abbia provato varie soluzioni, è come se il tempo di apertura non venisse mai calcolato, e quindi esce subito dalla funzione sia che la porta sia aperta o chiusa. Vi ringrazio dei suggerimenti
Livio Orsini Inserita: 21 febbraio 2020 Segnala Inserita: 21 febbraio 2020 11 minuti fa, kemosabe ha scritto: Preferirei non avere soluzioni, ma indicazioni sul procedimento da adottare Allora ti do le indicazioni. Fissi una differenza di tempo massimo Metti la condizione di uscita (ad esempio break) se si verifica una delle 2 condizioni: porta chiusa o differenza di tempo > del tempo massimo In pratica di basta un if di un OR di 2 condizioni.
kemosabe Inserita: 21 febbraio 2020 Autore Segnala Inserita: 21 febbraio 2020 ci sto provando in tutte le maniere ma continua a saltare l'if del millis. per curiosità ho provato a inserire l'esempio del blink without delay di arduino, dentro a quella funzione, e come volevasi dimostrare 😈 ...... fa sempre la stessa cosa, cioè salta a piè pari il millis. Sto impazzendo....????? spiegami perchè se il blink lo metto nel loop funziona, se invece è in una funzione esterna chiamata dal loop no. cosa cambia ????? grazie
Livio Orsini Inserita: 22 febbraio 2020 Segnala Inserita: 22 febbraio 2020 Perchè, probabilmente, come ti ho spiegato nell'altra discussione, stai usando variabili locali della funzione. Dichiara la variabile dove memorizzi il valore di partenza del tempo come globale e, probabilmente, funziona.
kemosabe Inserita: 22 febbraio 2020 Autore Segnala Inserita: 22 febbraio 2020 fatto, tutte globali, ma niente di fatto
Livio Orsini Inserita: 22 febbraio 2020 Segnala Inserita: 22 febbraio 2020 Prova a mettere ilcodice di quello che non funziona
kemosabe Inserita: 22 febbraio 2020 Autore Segnala Inserita: 22 febbraio 2020 (modificato) ti metto questo ma è uguale a qualsiasi altro void open_door() { // check the button if (digitalRead(door) == LOW) { // update the time when button was pushed buttonPushedMillis = currentMillis; door_state = true; } // make sure this code isn't checked until after button has been let go if (door_state) { //this is typical millis code here: if ((currentMillis - buttonPushedMillis) >= ledTurnedOnAt) { // okay, enough time has passed since the button was let go. digitalWrite(serratura, HIGH); // setup our next "state" door_time = true; // save when the LED turned on ledTurnedOnAt = currentMillis; // wait for next button press door_state = false; } } // see if we are watching for the time to turn off LED if (door_time) { // okay, led on, check for now long if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) { door_time = false; digitalWrite(serratura, LOW); } } fatto, tutte globali, ma niente di fatto Modificato: 22 febbraio 2020 da kemosabe
Livio Orsini Inserita: 22 febbraio 2020 Segnala Inserita: 22 febbraio 2020 Cosa non funziona di questa funzione? Secondo quello che leggo ogni volta che la richiami viene eseguita con i vari test e condizioni e le variabili vengono post alte o basse secondo il risultato del test.
Livio Orsini Inserita: 22 febbraio 2020 Segnala Inserita: 22 febbraio 2020 Hai anche scritto 12 ore fa, kemosabe ha scritto: spiegami perchè se il blink lo metto nel loop funziona, se invece è in una funzione esterna chiamata dal loop no. cosa cambia ????? Prova a mettere il codice di quello che non funziona così lo verifico
kemosabe Inserita: 22 febbraio 2020 Autore Segnala Inserita: 22 febbraio 2020 quella sopra, appena entra ne esce senza temporizzazione. Ne metto un'altra, che non funziona: void open_door() { door_state= digitalRead(door); if ( door_state== HIGH) { leds[1]=CRGB(0,255,0); //led porta verde on aperta FastLED.show(); door_state = HIGH; } else { leds[0]=CRGB(255,0,0); // led porta rosso on chiusa FastLED.show(); door_state = LOW; } // unsigned long currentMillis = millis(); if (door_state == LOW || door_time==true) { if (stop_time_door - start_time_door >= tempo_door ) { start_time_door = stop_time_door; door_time=false; } } if (door_state == LOW && door_time == true) { digitalWrite ( serratura, HIGH); // serratura on tone (buzzer,3000); // buzzer medio Serial.println ("door close time serratura on 2 sec suono medio"); Serial.println (" "); } else if (door_state == LOW && door_time==false) { digitalWrite ( serratura, LOW); // serratura on noTone (buzzer); // buzzer medio Serial.println ("door close no time no serratura suono stop"); Serial.println (" "); delay(100); } } anche questa si comporta nello stesso modo per chiarezza ti metto anche il pezzo di codice della chiamata; char customKey = myKeypad.getKey(); if (customKey) { // Serial.println(customKey); keys[count] = customKey; count++; if (count == 4) { //Serial.println(keys); if (strcmp(keys, password[n]) == 0) { open_door(); state = INIT_LCD; } count = 0; } } if (millis() - time > 10000) // exceed 10 seconds ? { state = INIT_LCD; }
Livio Orsini Inserita: 22 febbraio 2020 Segnala Inserita: 22 febbraio 2020 if (millis() - time > 10000) // exceed 10 seconds ? { state = INIT_LCD; } Prova a riscriverla così if ((millis() - time) > 10000) // exceed 10 seconds ? { state = INIT_LCD; } A parte questo, tu avevi scritto 16 ore fa, kemosabe ha scritto: spiegami perchè se il blink lo metto nel loop funziona, se invece è in una funzione esterna chiamata dal loop no. cosa cambia ????? Metti il codice di programmino che non va, compreso il codice che lo richiama, che vediamo il perchè non funziona.
kemosabe Inserita: 22 febbraio 2020 Autore Segnala Inserita: 22 febbraio 2020 (modificato) il problema, credo non è il quel ritardo che mi hai chiesto di modificare, quello aspetta solo 10 secondi per l'inserimento del codice e poi esce. adesso, per semplificare, ho temporaneamente disinserito la parte del codice, facendo l'accesso solo con l' RFID. ti mando il tutto, con un'altra prova, ma anche questa non funge grazie //enum {INIT_LCD, SCAN_TAG, KEY_IN_PASSWORD} state = INIT_LCD; enum {INIT_LCD, SCAN_TAG} state = INIT_LCD; // define for keypad #include <Keypad.h> #include <Keypad_I2C.h> #define I2CADDR 0x20 #include <Wire.h> //FASTLED #include <FastLED.h> #define DATA_PIN 3 #define NUM_LEDS 6 #define CLOCK_PIN 13 CRGB leds[NUM_LEDS]; // define for nfc #include <SPI.h> #include <MFRC522.h> #define NOT_FOUND -1 #define RST_PIN 9 #define SS_PIN 10 MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance #define NR_KNOWN_CARDS 2 #define CARD_SIZE 4 // init paralle arrays byte knownCards[NR_KNOWN_CARDS][CARD_SIZE] = { {0x04, 0x49, 0x81, 0x40}, {0xe5, 0xa2, 0x9c, 0x2c} }; char name[NR_KNOWN_CARDS][10] = { "Usul", "Richard" }; char password[NR_KNOWN_CARDS][5] = { "1111", "8888" }; int n; // current tag index const byte numRows = 4; //number of rows on the keypad const byte numCols = 4; //number of columns on the keypad //define the cymbols on the buttons of the keypads char keymap[numRows][numCols] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; byte rowPins[numRows] = {0, 1, 2, 3}; //Rows 0 to 3 byte colPins[numCols] = {4, 5, 6, 7}; //Columns 0 to 3 int count = 0; char keys[5]; unsigned long time; Keypad_I2C myKeypad( makeKeymap(keymap), rowPins, colPins, numRows, numCols, I2CADDR); // define for lcd #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,20,4); // Set the LCD I2C address int buzzer = 8; int door = 4; int serratura =7; //millis door unsigned long buttonPushedMillis; // when button was released unsigned long ledTurnedOnAt; // when led was turned on unsigned long turnOnDelay = 2500; // wait to turn on LED unsigned long turnOffDelay = 5000; // turn off LED after this time unsigned long previousMillis = 0; unsigned long start_time_door; unsigned long stop_time_door; const unsigned long tempo_door = 5000; bool door_time= false; bool door_state = false; bool consenso=false; int serratura_state = LOW; void setup() { myKeypad.begin( ); // setup nfc Serial.begin(9600); while (!Serial); SPI.begin(); mfrc522.PCD_Init(); FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); FastLED.setBrightness(50); FastLED.clear (); FastLED.show(); // setup keypad (assumed serial began) keys[4] = 0; // setup lcd lcd.begin(16,2); // setup PIN pinMode(buzzer, OUTPUT); pinMode(door, INPUT); pinMode (serratura, OUTPUT); } void loop() { door_state=digitalRead(door); if (digitalRead(door)==HIGH) { //Serial.println(fc_door, DEC); leds[0]=CRGB(0,255,0); //porta FastLED.show(); door_state= true; }else { leds[0]=CRGB(255,0,0); FastLED.show(); door_state=false; } init_lcd(); scan_new_card(); //key_in_password(); } void scan_new_card() { if (state != SCAN_TAG) { return; } if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } if ( ! mfrc522.PICC_ReadCardSerial()) { return; } mfrc522.PICC_HaltA(); tone(buzzer, 1500, 100); delay(50); tone(buzzer, 3000, 60); dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size); // Serial.print(F(" (")); // Serial.print(mfrc522.uid.size, DEC); // Serial.println(F(")")); n = indexOf(mfrc522.uid.uidByte, mfrc522.uid.size); if ( n != NOT_FOUND) { Serial.print(" Ciao "); Serial.println(name[n]); //show_user(name[n]); time = millis(); //Serial.println(time); //state = KEY_IN_PASSWORD; open_door(); //state = INIT_LCD; } else { user_not_found(); state = INIT_LCD; } } void dump_byte_array(byte *buffer, byte bufferSize) { for (byte i = 0; i < bufferSize; i++) { //Serial.print(buffer[i] < 0x10 ? " 0" : " "); // Serial.print(buffer[i], HEX); } } int indexOf(byte *buffer, byte bufferSize) { if (CARD_SIZE == bufferSize) { for (byte i = 0; i < NR_KNOWN_CARDS; i++) { byte j; for (j = 0; j < CARD_SIZE; j++) { if (buffer[j] != knownCards[i][j]) break; } if (j == CARD_SIZE) return i; } } return NOT_FOUND; } /*void key_in_password() { if (state != KEY_IN_PASSWORD) { return; } char customKey = myKeypad.getKey(); if (customKey) { // Serial.println(customKey); keys[count] = customKey; count++; if (count == 4) { //Serial.println(keys); if (strcmp(keys, password[n]) == 0) { open_door(); state = INIT_LCD; } count = 0; } } if (millis() - time > 10000) // exceed 10 seconds ? { state = INIT_LCD; } }*/ void init_lcd() { if (state != INIT_LCD) { return; } lcd.clear(); for (int i = 0; i< 3; i++) { lcd.backlight(); delay(250); lcd.noBacklight(); delay(250); } lcd.backlight(); lcd.setCursor(0,0); lcd.print("Hallo World!"); Serial.println("Hallo World! "); lcd.setCursor(0,1); lcd.print("Tag a NFC card"); Serial.print("Ready.... "); Serial.println("Cod or Card? "); state = SCAN_TAG; } void user_not_found() { lcd.clear(); lcd.setCursor(0,0); lcd.print("User not found!"); Serial.print("Utente non presente "); Serial.println("Error "); toggle_led(); //delay(3000); } void show_user(char name[10]) { lcd.clear(); lcd.setCursor(0,0); lcd.print("Hi "); // Serial.print("Ciao "); // Serial.println("name "); lcd.print(name); lcd.setCursor(0,1); lcd.print("Key in your PIN"); Serial.println("Il tuo pin prego... "); } void toggle_led() { lcd.clear (); lcd.setCursor ( 0, 0 ); lcd.print ( "ID NON VALIDO" ); Serial.println ( "ID NON VALIDO" ); unsigned long previousMillis = millis(); while(millis() - previousMillis < 5000) { leds[4].setRGB(0,0,0); //white leds[3].setRGB(255,64,0); //orange FastLED.show(); delay(50); leds[4].setRGB(255,255,255); //white leds[3].setRGB(0,0,0); //red FastLED.show(); delay(50); leds[4].setRGB(0,0,0); //white FastLED.show(); } } void open_door() { Serial.print( " dentro"); unsigned long currentMillis = millis(); if ( currentMillis - previousMillis >= tempo_door) { // save the last time you blinked the LED // // if the LED is off turn it on and vice-versa: if (serratura_state == LOW) { serratura_state = HIGH; } else { serratura_state = LOW; previousMillis = currentMillis; } // set the LED with the ledState of the variable: digitalWrite(serratura, serratura_state); state = INIT_LCD; } } Modificato: 22 febbraio 2020 da kemosabe
Livio Orsini Inserita: 22 febbraio 2020 Segnala Inserita: 22 febbraio 2020 Cosa non ti funziona? Come ti ha già detto, il problema si deve spezzare in tanti piccoli problemi. Si mettono a punto e poi, uno alla volta si integrano nell'applicazione generale. Contino a ripeterti. 1 ora fa, Livio Orsini ha scritto: A parte questo, tu avevi scritto 18 ore fa, kemosabe ha scritto: spiegami perchè se il blink lo metto nel loop funziona, se invece è in una funzione esterna chiamata dal loop no. cosa cambia ????? Metti il codice di programmino che non va, compreso il codice che lo richiama, che vediamo il perchè non funziona. Cominciamo a risolvere il problema elementare.
kemosabe Inserita: 22 febbraio 2020 Autore Segnala Inserita: 22 febbraio 2020 Scusa, ma te l'ho scritto 3 0 4 volte quale è il problema!!!!! Evidentemente scrivo in un'altra lingua. non ti preoccupare, prima o poi lo risolverò. Grazie Ciao
Livio Orsini Inserita: 22 febbraio 2020 Segnala Inserita: 22 febbraio 2020 Se ti chiedo di fare una cosa e non la fai poi come posso aiutarti?
diegosar Inserita: 10 marzo 2020 Segnala Inserita: 10 marzo 2020 Il 21/2/2020 alle 23:24 , kemosabe ha scritto: spiegami perchè se il blink lo metto nel loop funziona, se invece è in una funzione esterna chiamata dal loop no. cosa cambia ????? Ciao kemosabe, probabilmente visto il tempo passato hai già risolto il tuo problema. Se così non fosse vorrei farti un esempio di BlinkWithoutDelay funzionante col codice inserito in una funzione chiamata dal loop: const int ledPin = LED_BUILTIN; // the number of the LED pin int ledState = LOW; // ledState used to set the LED unsigned long previousMillis = 0; // will store last time LED was updated const long interval = 1000; // interval at which to blink (milliseconds) void setup() { pinMode(ledPin, OUTPUT); } void Controllo(){ unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } digitalWrite(ledPin, ledState); } } void loop() { Controllo(); } Questo codice funziona perché il loop continua a chiamare la funzione e quindi il codice inserito in questa viene continuamente eseguito come se fosse stato inserito direttamente nel loop. Per quanto riguarda il tuo codice, da quanto ho capito nella tua descrizione del problema, tu pensi che chiamando la funzione open_door() il codice all'interno di questa venga continuamente eseguito fino al verificarsi della condizione : currentMillis - previousMillis >= tempo_door Non è così. Il codice all'interno della funzione, non essendoci cicli, viene eseguito una sola volta quando la funzione viene chiamata e se in quella occasione il codice: if ( currentMillis - previousMillis >= tempo_door) non è verificato le istruzioni che seguino l'"if" non vengono eseguite. Dovresti quindi modificare il tuo programma in modo che la funzione open_door() venga chiamata più spesso oppure trasformare l'"if" in un "while" e il >= in <. Questa seconda soluzione vanificherebbe però l'utilizzo di millis() in quanto durante l'attesa della fine del ciclo il micro non potrebbe far altro.
Messaggi consigliati