Aiuto fare funzionare il relay di arduino a secondi

Salve a tutti, mi sono appena iscritto.
Mi sto cimentando a creare l impaurito della mia casa con la domotica di arduino, l intenzione è di collegare il relay di arduino q quello dell' impianto di casa come se fosse un pulsante, il problema è che questo relay rimane in stato chiuso in quanto a ogni singolo impululso lo stato cambia da NC a NO
.
Sarebbe possibile tramite codice dare un tempo a quest impulso in modo che passando da NO a NC ritorni dopo qualche secondo allo stato iniziale?

Non accettiamo richieste di aiuto che riguardano l' impianto elettrico casaligo perché sogetto a collaudo da parte di un perito abilitato. Un privato non puó modificare l' impianto elettrico.

Ciao Uwe

Scusa, io come mestiere faccione l elettricista, mi scuso nel modo in cui ho posto la domanda, ma la mia intenzione non era chiedervi come modificare l impianto di casa ma se c era un modo tramite codice di trasformare lo stato del relay di arduino da fisso a secondi

AntonioFranco2794: non avendolo ancora fatto, nel rispetto del regolamento, ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

P.S.: Nelle sezioni di lingua inglese si può scrivere SOLO in lingua Inglese, inoltre, come da suddetto regolamento, punto 13, il cross-posting è proibito (anche tra lingue diverse) per cui, il tuo post duplicato nella sezione Inglese è stato cancellato.

In merito al tuo problema, naturalmente la risposta è SI ...
... ti segni il momento in cui lo hai acceso, verifichi il tempo che è passato, e, superati gli X secondi, lo spegni.

Per fare questo, devi, con calma, studiarti come si usa la millis(), prima QUI, poi QUI ed infine leggi anche QUI e QUI ... vedrai che ti sarà tutto più chiaro :wink:

Guglielmo

Ho fatto un programma che controlla fino a 8 uscite, fisse oppure temporizzate.
Per il caso uso la libreria timerOne. Si imposta un vettore di interrupt e da lì si inizia a conteggiare all’ indietro il tempo di ogni uscita, fino a zero. Al raggiungimento dello zero si cambia di stato l’ uscita.

/* assunto che non mancano le definizioni per ogni variabile */
#include <TimerOne.h>

#define ACTIVE_LOW                      // Setting the level output, for all same

/* Questa è una peculiarità per definire se l' uscita deve essere attiva bassa.
Invece se si vuole uscite attive alte, allora commentare la riga. */

#ifdef ACTIVE_LOW
    #define OUT_LEVEL HIGH
#else
    #define OUT_LEVEL LOW
#endif
#define NUMTIMER 4                      // number of timer  used. Ne uso 4 al momento

uint16_t timers[NUMTIMER];           // timers array holding their time lapse maximum 32768 seconds
uint8_t timers_state;                      // mask to quick point a running timer
uint8_t port_state;                         // mask to index which output must turn on


// Assignment pins array. Here we can program a different pattern.

const uint8_t port_pin[] = {9, 10, 11, 12, A0, A1, A2, A3};


void setup() {
    uint8_t i;
    uint8_t x;

    for (i=0; i < NUMTIMER ; i++) {
        x = bitRead(port_state, x);
        pinMode(port_pin[i], OUTPUT);
        digitalWrite(port_pin[i], x ^ OUT_LEVEL);    // Setting all outputs off
    };
    Timer1.initialize(500000);                               // 1/2 second period
    Timer1.attachInterrupt( timerIsr );                  // called routine
}

void timerIsr() {
    bool i;
    uint8_t x;
    // Setting the output according the wanted level
    for (x = 0; x < NUMTIMER; x++) {
        if (bitRead(timers_state, x)) {
            if (timers[x]) {
                --timers[x];
                bitWrite(port_state, x, HIGH);
            }
            else {
                bitWrite(port_state, x, LOW);
                bitWrite(timers_state, x, LOW);
            }
        }
        i = bitRead(port_state, x);
        digitalWrite(port_pin[x], i ^ OUT_LEVEL);
    }
}

Quindi se si vuole una uscita fissa si imposta il bit relativo a port_state. Invece se si vuole una uscita temporizzata si imposta il relativo bit di timers_state e il suo valore nell’ array timers.
Per esempio per il timer 2 si imposta timers_state bit 1 e il timers[1] a 120 (per un minuto di tempo. (indicizzazione parte da 0, quindi si conta uno in meno.
Per lo sviluppo si ringrazia il meraviglioso aiuto del forum.

>ExperimentUno: lo segnalo ancora una volta (... l'ho detto e ripetuto centianaia di volte) ...
... almeno in prima battuta, EVITIAMO di fornire "pappa fatta" agli utenti che, in questo modo, imparano SOLO a fare degli inutili copia/incolla invece di provare a ragionare e capire come funziona la cosa.

Ritengo infatti che lo scopo del forum e della comunità sia "far crescere" le persone, non fornirgli subito "pappa fatta" con la quale, alla prossima difficoltà ... sono da capo a dodici ! :wink:

Grazie,

Guglielmo

Grazie a tutti per aver risposto e chiarito le idee comunque provvederò a Studiare

AntonioFranco2794:
comunque provvederò a Studiare

Guglielmo

@gpb01
Penso che quello che ho scritto non ha nessuna funzionalità di per sé. Piuttosto lo vedo come un esempio da dover studiare per come si comporta.

OP di fatto cerca un modo per fare un temporizzatore. Questo esempio, spiega come usare la classe TimerOne e come usufruire di indicizzazione a porte e a bytes.
Non ho assunto che OP sappia solo copiare.
Riterrei che gli esempi aiutano a sbrogliare dei dubbi.

Ragazzi scusate ma non riesco a capire come inserire millis qui

{
digitalWrite(2, HIGH);// attivo il relè collegato al pin12

mySerial.println("Relè 1 ON");
break;
}
case 'a': // Se ricevo la lettera a

>AntonioFranco2794: Per capire come usare la funzione millis(), devi leggere con attenzione prima QUI, poi QUI ed infine leggi anche QUI e QUI ... vedrai che ti sarà tutto più chiaro.

Guglielmo

Si ho letto ma non sto riuscendo ad abbinarlo a quella funzione non vi chiedo molto per lo meno ditemi a parole come potrei proseguire

Quando dai l'impulso (di cui parli nel tuo primo post) oltre a fare quello che devi fare, ti segni in una variabile di tipo "unsigned long" il valore di millis() (ovvero il "momento" in cui è arrivato l'impulso) dopo di che, con l'IF che dovresti aver studiato :

if ( millis() - tempo_Salvato > tempo_voluto) { ..... }

verifichi se è passato il tempo che vuoi e, se SI, esegui le operazioni che devi eseguire.

Guglielmo

Buon giorno Ragazzi, ho risolto in questo modo

digitalWrite(2, HIGH);
mySerial.println("Relè 1 ON");
delay(100);
digitalWrite(2, LOW);
break;

ho usato delay e gli ho dato il tempo giusto per un inpulso veloce

Purtroppo ti accorgerai presto che, al crescere della complessità del programma ... NON potrai più usare la delay() che, per quanto comoda, è una funzione bloccante, ovvero, per TUTTO il tempo della delay() il programma NON può fare altro.

Ora, in quel pezzetto di codice, se a te va bene, è ok ... ma vedrai che, ad esempio per tempi lunghi, in cui devi nel frattempo fare altre cose ... NON la portai usare, quindi il consiglio è ... IMPARA comunque AD USARE LA millis() che altrimenti, prima o poi, ti trovi nei guai. ::slight_smile:

Uomo avvisato mezzo salvato ...

Guglielmo

un decimo di secondo ?
Sembra alquanto poco.
Tanto per ricordare che delay prende come parametro millisecondi, se ne dai 100 significa un decimo di secondo.