invio segnale rf per TOT secondi

ciao a tutti, io avrei bisogno di inviare un codice in 433mhz per 20 secondi continui ma non riesco a capire come fare.
ho visto un po di guide ma tutte replicano un impulso secco, cosa che a me non va bene.

forse cè qualche funzione che non conosco o un determinato utilizzo di millis.

questo è quello che ho trovato per l’invio secco alla pressione del tasto.
io dovrei simulare la funzione di tasto5 e tasto6, ma dando io un impulso, lui deve inviare per 20 secondi :

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
#define debounce 200  //Tempo di rimbalzo

const int tasto1 = 2;        // tasto1  luce A
const int tasto2 = 3;        // tasto2  luce B 
const int tasto3 = 4;        // tasto3  luce C
const int tasto4 = 5;        // tasto4  luce D
const int tasto5 = 6;        // tasto5  luce giorno on
const int tasto6 = 7;        // tasto6  luce giorno off
const int tasto7 = 8;        // tasto7  LP on/off
const int tasto8 = 9;        // tasto8  cucina on/off
const int cancello = 12;     // output  per il relè cancelletto(relè con contatto NO. ,cablato in parallelo al tasto di un telecomando. 

const int segnaleout1 = 13;   // led di riscontro

// memoria dello stato 
int tastoState1 = 0;
int tastoState2 = 0;
int tastoState3 = 0;
int tastoState4 = 0;
int tastoState5 = 0;
int tastoState6 = 0;
int tastoState7 = 0;
int tastoState8 = 0;
//variabili di stato
int led1state=0; // stato riferito alla luce ......
int led2state=0; // stato riferito alla luce ......

unsigned long previousMillis1 = 0;       // memoria temporale pressione tasti
unsigned long previousMillis2 = 0;       // memoria temporale
unsigned long previousMillis3 = 0;       // memoria temporale
unsigned long previousMillis4 = 0;       // memoria temporale
unsigned long previousMillis5 = 0;       // memoria temporale
unsigned long previousMillis6 = 0;       // memoria temporale
unsigned long previousMillis7 = 0;       // memoria temporale
unsigned long previousMillis8 = 0;       // memoria temporale

const long interval = 300;              // intervallo dalla pressione tasti
const long interval1 = 300;              // intervallo dalla pressione ripetuta del tasto ( clic1=>on dopo 3 sec clic1=>off) 

void setup() 
{ 
//settaggio input/output
 mySwitch.enableTransmit(10);
 pinMode(tasto1, INPUT);       // tasto 
 pinMode(tasto2, INPUT);       // tasto
 pinMode(tasto3, INPUT);       // tasto 
 pinMode(tasto4, INPUT);       // tasto 
 pinMode(tasto5, INPUT);       // tasto 
 pinMode(tasto6, INPUT);       // tasto 
 pinMode(tasto7, INPUT);       // tasto
 pinMode(tasto8, INPUT);       // tasto
 pinMode(cancello, OUTPUT);   // uscita cancello
 pinMode(segnaleout1,OUTPUT);   // led di riscontro
 Serial.begin(9600);
}

void loop()
{
  
unsigned long currentMillis1 = millis(); // assegna il tempo alla variabile
unsigned long currentMillis2 = millis(); // assegna il tempo alla variabile
unsigned long currentMillis3 = millis(); // assegna il tempo alla variabile
unsigned long currentMillis4 = millis(); // assegna il tempo alla variabile
unsigned long currentMillis5 = millis(); // assegna il tempo alla variabile
unsigned long currentMillis6 = millis(); // assegna il tempo alla variabile
unsigned long currentMillis7 = millis(); // assegna il tempo alla variabile
unsigned long currentMillis8 = millis(); // assegna il tempo alla variabile

tastoState1 = digitalRead(tasto1);     // assegna il valoe del pin in alla variabile 
tastoState2 = digitalRead(tasto2);     // assegna il valoe del pin in alla variabile 
tastoState3 = digitalRead(tasto3);     // assegna il valoe del pin in alla variabile 
tastoState4 = digitalRead(tasto4);     // assegna il valoe del pin in alla variabile 
tastoState5 = digitalRead(tasto5);     // assegna il valoe del pin in alla variabile 
tastoState6 = digitalRead(tasto6);     // assegna il valoe del pin in alla variabile 
tastoState7 = digitalRead(tasto7);     // assegna il valoe del pin in alla variabile 
tastoState8 = digitalRead(tasto8);     // assegna il valoe del pin in alla variabile 

if (tastoState1 == HIGH) 
 { 
                 if (currentMillis1 - previousMillis1 >= interval1)      //se si verifica questa condizione, esegue il programma una volta, dopo si disabilita per un tempo:(intervallo) 
                      {   
                         previousMillis1 = currentMillis1;               // ripristina lintervallo
                         
                                                                         // FUNZIONE PASSO PASSO ACCENSIONE LUCI ( SEGNALE 433)
                                             if (led2state==LOW)
                                              {
                                              digitalWrite(segnaleout1,HIGH);      // accende il pin 13 di bordo per segnalare linvio dati
                                              led2state=HIGH;                      // porta allo stato alto la variabile memoria
                                              mySwitch.send(****, 24);              // accendi luce con il codice ( sostituire asterischi con il codice rf)
                                              digitalWrite (segnaleout1,LOW);       //spegne il pin 13 di bordo per segnalare linvio dati ( lampeggio)
                                              }
     
                                            else
                                              { 
                                               digitalWrite (segnaleout1,HIGH); 
                                               led2state=LOW;                       // porta allo stato basso la memoria
                                               mySwitch.send(****, 24);                  // spegni luce con il codice **** 
                                               digitalWrite (segnaleout1,LOW) ;   
                                              }   


        
                       }     
}
     
if (tastoState2 == HIGH) 
 { 



        if (currentMillis3 - previousMillis3 >= interval)    // se, continua il programma una volta, dopo si disabilita per un tempo:(intervallo) 

        {   
        digitalWrite(segnaleout1,HIGH);  
        previousMillis3 = currentMillis3;
        mySwitch.send(5393, 24);                      // LUCE salottoTV ( 5393  ) NB E USATO SOLO IL CODICE DI on del radiocomando e sulla ricevente funzione passo passo.
        digitalWrite (segnaleout1,LOW);  
        }
  }   

if (tastoState3 == HIGH) 
 { 
        if (currentMillis3 - previousMillis3 >= interval)    // continua il programma una volta, dopo si disabilita per un tempo:(intervallo) 

        {   
        digitalWrite(segnaleout1,HIGH);  
        previousMillis3 = currentMillis3;
                                                  // LUCE STUDIO  NB (cambiare il codice su rx E USATO SOLO IL CODICE DI OFF e sulla ricevente funzione passo passo.
        mySwitch.send(14562672, 24);                                // LUCE STUDIO (14441524/14562672) NB E USATO SOLO IL CODICE DI OFF e sulla ricevente funzione passo passo.
        digitalWrite (segnaleout1,LOW);  
        }
  }  

if (tastoState4 == HIGH)                                      // COMANDO CANCELLO, ( RELE CON CONTATTO NO.). 
{ 
        if (currentMillis4 - previousMillis4 >= interval)    // continua il programma una volta, dopo si disabilita per un tempo:(intervallo) 

        {   
        digitalWrite(segnaleout1,HIGH);  
        previousMillis4 = currentMillis4;
        digitalWrite(cancello,HIGH);           // eccitazione relè COMANDO relè per apertura cancello
        delay(500);                            // TEMPO di scambio contatto
        digitalWrite(cancello,LOW);            // SPEGNIMENTO.
        digitalWrite (segnaleout1,LOW);  
        }
  }  


if (tastoState5 == HIGH) 
 { 
        if (currentMillis5 - previousMillis5 >= interval)    // continua il programma una volta, dopo si disabilita per un tempo:(intervallo) 

        {   
        digitalWrite(segnaleout1,HIGH);  
        previousMillis5 = currentMillis5;
        mySwitch.send(4433, 24);                           // ACCENDI POMPA PISCINA
        digitalWrite (segnaleout1,LOW);  
        }
  }  


if (tastoState6 == HIGH) 
 { 
        if (currentMillis6 - previousMillis6 >= interval)    // continua il programma una volta, dopo si disabilita per un tempo:(intervallo) 

        {   
        digitalWrite(segnaleout1,HIGH);  
        previousMillis6 = currentMillis6;
        mySwitch.send(4436, 24);                       // SPEGNI POMPA PISCINA
        digitalWrite (segnaleout1,LOW);  
        }
  }

Forse il ciclo for fà al caso mio, ma tutti gli esempi spiegano che funziona a numero di ripetizioni. È possibile con qualche trucco farlo lavorare in relazione al tempo?

millis(), devi usare anche tu millis() :D

... visto che ce ne sono pochi :D

Se il programma si può bloccare e non fare nient’altro che inviare il segnale durante i 20 secondi, un delay() dopo l’istruzione che invia il segnale ti risolve il problema.

Altrimenti puoi usare un codice tipo questo, con l’utilizzo di millis(), che mi ero già fatto in un’altra applicazione simile alla tua:

nota: al posto della digitalWrite del LED ci metterai rispettivamente i comandi di attivazione e disattivazione del segnale RF.

const unsigned long ON_time = 20000UL;
unsigned long previousMillis;
bool memoState;
int button = 2;
int LED = 13;

void setup()
{
  pinMode(button, INPUT);
  pinMode(LED, OUTPUT);
}

void loop()
{
	bool buttonState = digitalRead(button);
	
	if (buttonState && !memoState) {
		memoState = true;
		previousMillis = millis();
	}

	if (((millis() - previousMillis) <= ON_time) && memoState) {
		digitalWrite(LED, HIGH);
	}
	else {
		digitalWrite(LED, LOW);
		memoState = false;
	}
}

sto facendo delle prove su simulatore e penso di essere sulla strada giusta, forse ci sarà qualche bug:

ora ho messo il lampeggio del led per vedere il comportamento su simulatore, poi al loro posto ci sarà la voce “mySwitch.send(3642, 1);” così invierà il segnale in continuo come fossi io a tenere premuto il pulsante del telecomando:

int papertura = 2; //pulsante
int pchiusura = 3; //pulsante
int apertura  = 4; //led
int chiusura = 5; //led
int statomovimento;
int i;
unsigned long corsa;
int tempomov = 5000;
unsigned long timeoutap;
unsigned long iniziomov;


void setup()
{
  pinMode(papertura, INPUT_PULLUP);
  pinMode (pchiusura, INPUT_PULLUP);
  pinMode (apertura, OUTPUT);
  pinMode (chiusura, OUTPUT);
  digitalWrite (apertura, LOW);
  digitalWrite (chiusura, LOW);
  statomovimento = 0;
}

void loop()
{
     if ((digitalRead(papertura) == LOW) and (statomovimento == 0))
  {
    statomovimento= 1;
    iniziomov= millis();
    corsa = ((unsigned long)(millis())-(unsigned long)(iniziomov));
    for(corsa;corsa<tempomov;){
      digitalWrite (apertura, HIGH);
  delay (200);
    digitalWrite (apertura, LOW);
      delay (200);
      statomovimento= 0;
    corsa = ((unsigned long)(millis())-(unsigned long)(iniziomov));
      if ((digitalRead(pchiusura) == LOW) or (digitalRead(papertura) == LOW)){
        statomovimento= 0;
        delay(500);
        break;      
}        
 }        
}
  
  if ((digitalRead(pchiusura) == LOW) and (statomovimento == 0))
  {
    statomovimento= 1;
    iniziomov= millis();
    corsa = ((unsigned long)(millis())-(unsigned long)(iniziomov));
    for(corsa;corsa<tempomov;){
      digitalWrite (chiusura, HIGH);
  delay (200);
    digitalWrite (chiusura, LOW);
      delay (200);
      statomovimento= 0;
    corsa = ((unsigned long)(millis())-(unsigned long)(iniziomov));
      if ((digitalRead(pchiusura) == LOW) or (digitalRead(papertura) == LOW)){
        statomovimento= 0;
        delay(500);
        break;      
}        
}
  }   
 }

avete qualche suggerimento in merito?
grazie

acuplush: avete qualche suggerimento in merito?

Indentare correttamente il codice prima di postarlo...

Claudio_FF:
Indentare correttamente il codice prima di postarlo…

L’ho già fatto con la funzione ctrl+t dell’ide

a me lo da così :slight_smile:

int papertura = 2; //pulsante
int pchiusura = 3; //pulsante
int apertura  = 4; //led
int chiusura = 5; //led
int statomovimento;
int i;
unsigned long corsa;
int tempomov = 5000;
unsigned long timeoutap;
unsigned long iniziomov;


void setup()
{
  pinMode(papertura, INPUT_PULLUP);
  pinMode (pchiusura, INPUT_PULLUP);
  pinMode (apertura, OUTPUT);
  pinMode (chiusura, OUTPUT);
  digitalWrite (apertura, LOW);
  digitalWrite (chiusura, LOW);
  statomovimento = 0;
}

void loop()
{
  if ((digitalRead(papertura) == LOW) and (statomovimento == 0))
  {
    statomovimento = 1;
    iniziomov = millis();
    corsa = ((unsigned long)(millis()) - (unsigned long)(iniziomov));
    for (corsa; corsa < tempomov;) {
      digitalWrite (apertura, HIGH);
      delay (200);
      digitalWrite (apertura, LOW);
      delay (200);
      statomovimento = 0;
      corsa = ((unsigned long)(millis()) - (unsigned long)(iniziomov));
      if ((digitalRead(pchiusura) == LOW) or (digitalRead(papertura) == LOW)) {
        statomovimento = 0;
        delay(500);
        break;
      }
    }
  }

  if ((digitalRead(pchiusura) == LOW) and (statomovimento == 0))
  {
    statomovimento = 1;
    iniziomov = millis();
    corsa = ((unsigned long)(millis()) - (unsigned long)(iniziomov));
    for (corsa; corsa < tempomov;) {
      digitalWrite (chiusura, HIGH);
      delay (200);
      digitalWrite (chiusura, LOW);
      delay (200);
      statomovimento = 0;
      corsa = ((unsigned long)(millis()) - (unsigned long)(iniziomov));
      if ((digitalRead(pchiusura) == LOW) or (digitalRead(papertura) == LOW)) {
        statomovimento = 0;
        delay(500);
        break;
      }
    }
  }
}

e questa non l’ho capita :slight_smile:

for (corsa; corsa < tempomov;) {
...
corsa = ((unsigned long)(millis()) - (unsigned long)(iniziomov));
...

Patrick_M:
a me lo da così :slight_smile:

int papertura = 2; //pulsante

int pchiusura = 3; //pulsante
int apertura  = 4; //led
int chiusura = 5; //led
int statomovimento;
int i;
unsigned long corsa;
int tempomov = 5000;
unsigned long timeoutap;
unsigned long iniziomov;

void setup()
{
 pinMode(papertura, INPUT_PULLUP);
 pinMode (pchiusura, INPUT_PULLUP);
 pinMode (apertura, OUTPUT);
 pinMode (chiusura, OUTPUT);
 digitalWrite (apertura, LOW);
 digitalWrite (chiusura, LOW);
 statomovimento = 0;
}

void loop()
{
 if ((digitalRead(papertura) == LOW) and (statomovimento == 0))
 {
   statomovimento = 1;
   iniziomov = millis();
   corsa = ((unsigned long)(millis()) - (unsigned long)(iniziomov));
   for (corsa; corsa < tempomov;) {
     digitalWrite (apertura, HIGH);
     delay (200);
     digitalWrite (apertura, LOW);
     delay (200);
     statomovimento = 0;
     corsa = ((unsigned long)(millis()) - (unsigned long)(iniziomov));
     if ((digitalRead(pchiusura) == LOW) or (digitalRead(papertura) == LOW)) {
       statomovimento = 0;
       delay(500);
       break;
     }
   }
 }

if ((digitalRead(pchiusura) == LOW) and (statomovimento == 0))
 {
   statomovimento = 1;
   iniziomov = millis();
   corsa = ((unsigned long)(millis()) - (unsigned long)(iniziomov));
   for (corsa; corsa < tempomov;) {
     digitalWrite (chiusura, HIGH);
     delay (200);
     digitalWrite (chiusura, LOW);
     delay (200);
     statomovimento = 0;
     corsa = ((unsigned long)(millis()) - (unsigned long)(iniziomov));
     if ((digitalRead(pchiusura) == LOW) or (digitalRead(papertura) == LOW)) {
       statomovimento = 0;
       delay(500);
       break;
     }
   }
 }
}



e questa non l'ho capita :)


for (corsa; corsa < tempomov;) {

corsa = ((unsigned long)(millis()) - (unsigned long)(iniziomov));

Allora sono un pirla, ho incollato quello del simulatore e non quello dell’ide :sweat_smile:

Quella funzione l’ho scritta per far sì che corsa superi tempomov così da uscire dal loop

acuplush:
Quella funzione l’ho scritta per far sì che corsa superi tempomov così da uscire dal loop

In sostanza ‘corsa’ è il tempo trascorso (ma se è il tempo trascorso… perché non chiamarlo ‘trascorso’?)

Il for che hai scritto è un “while simulato”, infatti bastava:

while(millis() - iniziomov < (unsigned long)tempomov)
{
    ....
}

…ma probabilmente non volevi usare while per non restare bloccato dentro il ciclo.

La soluzione l’ha già scritta krypton18. La sua variabile ‘memoState’ è la tua ‘statomovimento’. La sua variabile ‘previousMillis’ è la tua ‘iniziomov’. La sua costante 'ON_TIME è la tua ‘tempomov’.

Quel codice continua ad eseguire ripetutamente la digitalWrite(LED, HIGH) per il tempo specificato senza bisogno di alcun while o for, come ciclo è sufficiente il loop principale.

Quel codice continua ad eseguire ripetutamente la digitalWrite(LED, HIGH) per il tempo specificato

A tal proposito, ho fatto una versione nuova :D. Non mi piaceva scrivere continuamente uno stato che è sufficiente settare una volta sola.

const unsigned long ON_time = 20000UL;
unsigned long previousMillis;
bool memoState;
int button = 2;
int LED = 13;

void setup()
{
  pinMode(button, INPUT);
  pinMode(LED, OUTPUT);
}

void loop()
{
    bool buttonState = digitalRead(button);

    if (buttonState && !memoState) {
        memoState = true;
        digitalWrite(LED, HIGH);
        previousMillis = millis();
    }

    if (memoState) {
        if ((millis() - previousMillis) >= ON_time) {
            memoState = false;
            digitalWrite(LED, LOW);
        }
    }
}

ho provato la soluzione di krypton ma non mi va bene perchè non mi ripete in continuo il comando ma una volta fatto “rimane in attesa fino allo scadere del tempo”.
modificando quello che avevo fatto io e aggiungendo la modifica di claudioff ad ogni “giro mi invia il comando” quindi fa quello che voglio.
però quando è a “riposo” mi scrive sempre la variabile “movapertura = 0;” in continuo, non so se gli fà bene o cè un modo per evitarla.

allego il codice con solo la parte di apertura dato che sto facendo le prove solo con quella:

int papertura = 2; //pulsante
int pchiusura = 3; //pulsante
int apertura  = 4; //led
int chiusura = 5; //led
int movapertura;
int statomovimento;
int i;
int flag;
unsigned long corsa;
int tempomov = 5000;
unsigned long timeoutap;
unsigned long iniziomov;
unsigned long modval;


void setup()
{
  pinMode(papertura, INPUT_PULLUP);
  pinMode (pchiusura, INPUT_PULLUP);
  pinMode (apertura, OUTPUT);
  pinMode (chiusura, OUTPUT);
  digitalWrite (apertura, LOW);
  digitalWrite (chiusura, LOW);
  statomovimento = 0;
  flag =  0;
  Serial.begin(9600); // inizializzo la comunicazione seriale
}

void loop()
{
  if ((digitalRead(papertura) == LOW) && (flag == 0))
  {
    movapertura = 1;
    flag = 1;
  }

  if ((digitalRead(papertura) == HIGH) && (flag == 1))
  {
    flag = 0;
  }

  if ((movapertura == 1) and (statomovimento == 0))
  {
    Serial.println("primo avvio");
    statomovimento = 1;
    iniziomov = millis();

    while (millis() - iniziomov < (unsigned long)tempomov) {
      digitalWrite (apertura, HIGH);
      delay (100);
      statomovimento = 0;
      Serial.println("loop");

      if ((digitalRead(pchiusura) == LOW) or (digitalRead(papertura) == LOW)) {
        statomovimento = 0;
        delay(500);
        Serial.println("blocco");
        break;
      }
    }
  }

  movapertura = 0;
  Serial.println("fine");
}

acuplush: ho provato la soluzione di krypton ma non mi va bene perchè non mi ripete in continuo il comando ma una volta fatto "rimane in attesa fino allo scadere del tempo".

Intendevo il codice del post #3, che è la soluzione giusta perché non usa while/for/delay bloccanti.

però quando è a "riposo" mi scrive sempre la variabile "movapertura = 0;" in continuo, non so se gli fà bene o cè un modo per evitarla.

Hai realizzato un riconoscitore dell'istante di pressione, e la variabile 'movapertura' è un segnale impulsivo che va a 1 per un solo ciclo di loop. Lasciala così che va bene. Scrivere continuamente in una cella di memoria RAM non fa alcun danno.

Claudio_FF: Intendevo il codice del post #3, che è la soluzione giusta perché non usa while/for/delay bloccanti. Hai realizzato un riconoscitore dell'istante di pressione, e la variabile 'movapertura' è un segnale impulsivo che va a 1 per un solo ciclo di loop. Lasciala così che va bene. Scrivere continuamente in una cella di memoria RAM non fa alcun danno.

si, l'ho fatto in modo da non avere il rischio che mi vada in break se clicco male il tasto. ok, allora posso copiare lo stesso codice per la discesa e ci siamo. a breve dovrebbe arrivarmi anche il modulo rf così faccio le prove "sul campo"

grazie

Però ci sono alcune cose che non mi tornano…

L’uso di millis serviva solo per fare qualcosa per tot tempo, oppure doveva anche servire per non bloccare il resto del programma? Così come lo hai scritto è bloccante: per il tempo ‘tempomov’ nessun altro ingresso o uscita viene gestito, e allora tanto valeva scrivere una cosa come:

// chiama ripetutamente trasmetti per (circa) 20 secondi  

for(x=0; x<1000; x++;){
    ...trasmetti...
    delay(20);
}

Un’altra cosa è la condizione seguente. Se non sbaglio se il pulsante rimane premuto il ciclo viene interrotto subito, per poi ricominciare, per poi interrompersi, per poi ricominciare ecc…

if ((digitalRead(pchiusura) == LOW) or (digitalRead(papertura) == LOW)) {
    statomovimento = 0;
    delay(500);
    Serial.println("blocco");
    break;

Una terza è il fatto che la variabile ‘statomovimento’ mi sembra non serva a niente… O meglio, sarebbe un’ottima idea se servisse a gestire diversi stati di funzionamento con una logica non bloccante, ma qui non è così (fuori dall’if è sempre zero, e dentro viene messa a 1 e riportata subito a zero).

Un’idea di logica non bloccante a sei stati (variabile ‘statomovimento’ da 0 a 5) in grado di gestire sia apertura che chiusura che pressioni e rilasci può essere la seguente:

fidocad-32492__.png

1) Non ho utilizzato la funzione for perché quella lavora con il numero di ripetizioni, invece a me serve un tempo di ripetizione.

2)a questo non ci ho pensato ma non è un utilizzo che farò (quello di tenere premuto)

3)quello lo avevo messo come controllo che tutto sia fermo prima di cominciare a muovere. Forse hai ragione che non serve a nulla dato che se sono dentro al movimento alla pressione di qualsiasi tasto mi esce

acuplush: 1) Non ho utilizzato la funzione for perché quella lavora con il numero di ripetizioni, invece a me serve un tempo di ripetizione.

:D ripetere 1000 volte un delay di 20 millisecondi equivale ad attendere 20.000 millisecondi cioè 20 secondi ;)