ciao a tutti, sto cercando da giorni un qualcosa che funziona in modo simile ma senza venirne a capo.
E' da un po che non pastrocchio con aruduino e mi sono arrugginito e ho difficoltà con questo.
Sto provando a realizzare questa funzione utilizzando 1 Pulsante Relè1 Relè2
Normalmente R1 e R2 sono LOW
Se P1 è premuto 1 secondo = STOP
Se P1 è premuto per 2 secondi = Rele1 High per X secondi e mantiene Relè 2 Stop (relè 2 dovrebbe essere già spento) poi si ferma e rimane in attesa di nuovi input
Se P1 è premuto per 3 secondi = Rele2 High per X secondi Relè1 Stop (relè 1 dovrebbe essere già spento) poi si ferma e rimane in attesa in input
SE Relè1 o Rele2 in quel momento è attivo premendo P1 per 1 secondo STOP del comando
Devo essere sicuro che NON si creino situazioni dove anche per un millesimo secondo i due relè NON devono essere attivi allo stesso momento.
A tal proposito questo è possibile evitarlo quando accendo arduino? solitamente quando inizia il ciclo dello sketch appena alimentato ho notato che accende e spegne velocemente i relè e poi funziona normalmente il tutto..
La destinazione di questo sketch è per un motore di una tenda elettrica e quindi se attivo il relè per salita non posso attivare il relè della discesa allo stesso momento e viceversa.
Se riuscite a darmi uno spunto per partire con qualcosa ve ne sarei grato
Se trovi un mio vecchio post, avevo postato un'esempio per eseguire diverse funzioni alla pressione, al rilascio, oppure al rilascio in base al tempo premuto ...
EDIT: non trovo piu il post, faccio prima a ripostarlo ...
// Esempio per diverse operazioni con pressioni di durata diversa (piu o meno
// di mezzo secondo, in questo esempio, ma puo essere qualsiasi intervallo di tempo)
// Ovviamente, in questo caso le operazioni sono eseguite solo al rilascio del tasto
st = digitalRead(pin) //leggi ingresso pulsante
if ((st != stp) && (stp == 0)) // pulsante appena premuto
{
stp = st; //setta flag per pulsante premuto
millis_p = millis(); //setta variabile controllo tempo
}
if ((st != stp) && (stp == 1)) //pulsante appena rilasciato
{
stp = st; //resetta flag per pulsante rilasciato
if (millis() - millis_prec <= 500) //pulsante premuto per meno di mezzo secondo
{
//qui ci vanno tutte le operazioni da compiere al RILASCIO del tasto,
//UNA SOLA VOLTA, se il tasto e' rimasto premuto per meno di 500mS
}
else
{
//qui vanno tutte le operazioni da compiere al RILASCIO del tasto,
//UNA SOLA VOLTA, se il tasto e' rimasto premuto per piu di 500mS
}
}
// puo essere usato anche per piu intervalli di tempo diversi, non solo due tempi
Puoi usarlo come traccia iniziale e derivarne una versione con le tre opzioni che servono a te ...
ciao,
ti ringrazio per la rapida risposta,
più o meno ho tirato fuori questo sketch ma come dicevo sono un po arrugginito, infatti presenta già l'errore st was not declared in this scope
magari sarà una cosa banale ma a questi acronimi non ci ero ancora arrivato, st stà per? Status? come lo dichiaro?
eventualmente nello sketch come posso implementare il comando di fermare tutto se il pulsante viene premuto?
int Apertura = 2;
int Chiusura = 3;
int Pulsante = 4;
void setup ()
{
pinMode(Apertura, OUTPUT);
pinMode(Chiusura, OUTPUT);
pinMode(Pulsante, INPUT);
}
void loop ()
{
st = digitalRead(4)
if ((st != stp) && (stp == 0))
{
stp = st;
millis_p = millis();
}
if ((st != stp) && (stp == 1))
{
stp = st;
if (millis() - millis_prec <= 2000) //pulsante premuto 2 secondi
{
digitalWrite (CHIUSURA, LOW); //mi assicuro che l'altro relè sia prima spento
delay (500); //dopo mezzo secondo faccio partire il reale comando che mi serve per tot secondi
digitalWrite (APERTURA, HIGH);
delay (5000);
}
if (millis() - millis_prec <= 3000) //pulsante premuto 3 secondi
{
digitalWrite (CHIUSURA, LOW); //mi assicuro che l'altro relè sia prima spento
delay (500); //dopo mezzo secondo faccio partire il reale comando che mi serve per tot secondi
digitalWrite (APERTURA, HIGH);
delay (5000);
}
else
{
digitalWrite (APERTURA, LOW); //diversamente spengo entrambi i relè
digitalWrite (CHIUSURA, LOW);
delay (500);
}
}
dunque... vediamo un po...
non mi da errore di compilazione ma non funziona niente.
Sto guardando un po per google esempi di sketch con le variabili, non ci sto capendo molto forse perchè ci sto smanettando da ore e ho confusione...
Sicuramente il fatto che non funziona niente dipende dalle variabili.
In cosa sbaglio?
int Apertura = 2;
int Chiusura = 3;
int Pulsante = 4;
int st = 0;
int stp = 0;
int millis_p = 0;
int millis_prec = 0;
void setup ()
{
pinMode(Apertura, OUTPUT);
pinMode(Chiusura, OUTPUT);
pinMode(Pulsante, INPUT);
}
void loop ()
{
st = digitalRead (4);
if ((st != stp) && (stp == 0))
{
stp = st;
millis_p = millis();
}
if ((st != stp) && (stp == 1))
{
stp = st;
if (millis() - millis_prec <= 2000) //pulsante premuto 2 secondi
{
digitalWrite (Chiusura, LOW); //mi assicuro che l'altro relè sia prima spento
delay (500); //dopo mezzo secondo faccio partire il reale comando che mi serve per tot secondi
digitalWrite (Apertura, HIGH);
delay (5000);
}
if (millis() - millis_prec <= 3000) //pulsante premuto 3 secondi
{
digitalWrite (Chiusura, LOW); //mi assicuro che l'altro relè sia prima spento
delay (500); //dopo mezzo secondo faccio partire il reale comando che mi serve per tot secondi
digitalWrite (Apertura, HIGH);
delay (5000);
}
else
{
digitalWrite (Apertura, LOW); //diversamente spengo entrambi i relè
digitalWrite (Chiusura, LOW);
delay (500);
}
}
}
DJTech84:
Se P1 è premuto 1 secondo = STOP
Se P1 è premuto per 2 secondi = Rele1 High per X secondi e mantiene Relè 2 Stop (relè 2 dovrebbe essere già spento) poi si ferma e rimane in attesa di nuovi input
Se P1 è premuto per 3 secondi = Rele2 High per X secondi Relè1 Stop (relè 1 dovrebbe essere già spento) poi si ferma e rimane in attesa in input
SE Relè1 o Rele2 in quel momento è attivo premendo P1 per 1 secondo STOP del comando
Come uso mi sembra... scomodissimo, tocca contare il tempo ad ogni manovra...
Visto che si è all'inizio del progetto considererei un uso più intuitivo:
Un click avvia in un senso
Una pressione lunga (superiore a 700ms) avvia nell'altro senso (importante: avvia senza attendere il rilascio del pulsante)
ciao Claudio,
grazie per esser intervenuto.
Volevo delucidarvi meglio sul perche della mia richiesta.
Questo codice lo sto adattando ad un sistema domotico esistente, solo che per una tenda da sole, non sto a spendere altri 130 euro di modulo per gestire un motore.
Siccome mi è avanzata un uscita relè di un altro modulo di cui posso gestire in secondi il tempo di attivazione e disattivazione, facendo dei test ho creato uno scenario in cui posso scegliere se attivarlo per 1 secondo 2 o 3 o anche piu...
in questo modo gli simulo l'impulso associato alla funzione del codice che sto cercando di implementare.
La scelta del ritardo tra un relè e l'altro l'ho inserita per esser certo che prima si spenga uno e poi si accenda l'altro (millisecondi che posso ridurre ancora).
Essendo poi gestito da uno scenario, una volta che do il comando di tot secondi io non mi devo preoccupare piu di nulla, se la vede arduino.
sto facendo dei test dalle 8 di stamattina e cercando di confrontare degli sketch di esempio senza esito positivo..
di sicuro sto al 90% del progetto completo grazie ad alcune dritte date, ma ho difficoltà a capire dov'è l'intoppo.
qualcuno riesce a venirmi incontro?
const int Apertura = 2;
const int Chiusura = 3;
const int Pulsante = 4;
int st;
int stp;
unsigned long millis_prec;
unsigned long millis_now;
void setup ()
{
pinMode(Apertura, OUTPUT);
pinMode(Chiusura, OUTPUT);
pinMode(Pulsante, INPUT);
stp = 0;
millis_prec = millis();
}
void loop ()
{
st = digitalRead (Pulsante);
if (st != stp) switch (stp) {
case LOW: // pulsante appena premuto
millis_prec = millis();
stp = st;
break;
case HIGH: //pulsante appena rilasciato
millis_now = millis();
if (millis_now - millis_prec <= 2000) //pulsante premuto meno di 2 secondi
{
digitalWrite (Chiusura, LOW); //mi assicuro che l'altro relè sia prima spento
delay (500); //dopo mezzo secondo faccio partire il reale comando che mi serve per tot secondi
digitalWrite (Apertura, HIGH);
delay (5000);
digitalWrite (Apertura, LOW);
}
else if (millis_now - millis_prec <= 3000) //pulsante premuto più di 2 secondi ma meno di 3 secondi
{
digitalWrite (Chiusura, LOW); //mi assicuro che l'altro relè sia prima spento
delay (500); //dopo mezzo secondo faccio partire il reale comando che mi serve per tot secondi
digitalWrite (Apertura, HIGH);
delay (5000);
digitalWrite (Apertura, LOW);
}
else //pulsante premuto più di 3 secondi
{
digitalWrite (Apertura, LOW); //diversamente spengo entrambi i relè
digitalWrite (Chiusura, LOW);
delay (500);
}
stp = st;
break;
}
}
ho testato ora il tutto, la parte break non funziona, ovvero
se in qualsiasi momento in cui uno dei due relè è attivo clicco il pulsante (massimo 1 secondo) non mi interrompe lo stato dei relè
inoltre se il pulsante lo premo brevemente il relè apertura (pin2) va su HIGH subito senza attendere i 2 secondi
const int Apertura = 2;
const int Chiusura = 3;
const int Pulsante = 4;
int st;
int stp;
unsigned long millis_prec;
unsigned long millis_now;
void setup ()
{
pinMode(Apertura, OUTPUT);
pinMode(Chiusura, OUTPUT);
pinMode(Pulsante, INPUT);
stp = 0;
millis_prec = millis();
}
void loop ()
{
st = digitalRead (Pulsante);
if (st != stp) switch (stp) {
case LOW: // pulsante appena premuto
millis_prec = millis();
stp = st;
break;
case HIGH: //pulsante appena rilasciato
millis_now = millis();
if (millis_now - millis_prec <= 2000)
{//APRO
digitalWrite (Chiusura, LOW); //mi assicuro che l'altro relè sia prima spento
delay (500); //dopo mezzo secondo faccio partire il reale comando che mi serve per tot secondi
digitalWrite (Apertura, HIGH);
delay (5000);
digitalWrite (Apertura, LOW);
}
else if (millis_now - millis_prec <= 5000)
{ //CHIUDO
digitalWrite (Apertura, LOW);//mi assicuro che l'altro relè sia prima spento
delay (500);
digitalWrite (Chiusura, HIGH);
delay (5000);
digitalWrite (Chiusura, LOW);
}
else
{
}
stp = st;
break;
}
}
La butto li ... io in quegli esempi non vedo alcuna flag per memorizzare lo stato dei rele' ... voglio dire, come fa lo sketch a sapere se il rele' e' acceso e deve spegnerlo, oppure se e' gia spento e puo non fare nulla ?
Oppure la cosa e' indifferente e basta che compia le azioni anche se non servono ?
Inoltre, ovviamente, se le azioni da compiere dipendono da quanto tempo il pulsante e' rimasto premuto, e' logico aspettarsi che le esegua solo nel momento in cui il pulsante viene rilasciato ...
Allora...
sono quasi le 3 di notte e non ne sto uscendo fuori.
posto il codice sintetizzato a 1 relè perche non mi stanno tornando delle cose!
Ho definito le costanti.
Ho incollato il codice proposto da Etemenanki inserendo parte di ciò che devo attivare e disattivare.
guardando i commenti mi succede il contrario, ovvero se premo il pulsante a meno di un secondo io ho lo stato impostato su LOW invece il LED mi si accende (al momento sto testando su BB con i led).
Se tengo premuto oltre il secondo non si spegne.
const int Apertura = 2;
const int Chiusura = 3;
const int Pulsante = 4;
int st;
int stp;
unsigned long millis_prec;
unsigned long millis_now;
unsigned long millis_p;
void setup ()
{
pinMode(Apertura, OUTPUT);
pinMode(Chiusura, OUTPUT);
pinMode(Pulsante, INPUT);
}
void loop ()
{
st = digitalRead(Pulsante); //leggi ingresso pulsante
if ((st != stp) && (stp == 0)) // pulsante appena premuto
{
stp = st; //setta flag per pulsante premuto
millis_p = millis(); //setta variabile controllo tempo
}
if ((st != stp) && (stp == 1)) //pulsante appena rilasciato
{
stp = st; //resetta flag per pulsante rilasciato
if (millis() - millis_prec <= 1000) //pulsante premuto per meno di mezzo secondo
{
//qui ci vanno tutte le operazioni da compiere al RILASCIO del tasto,
//UNA SOLA VOLTA, se il tasto e' rimasto premuto per meno di 1 S
digitalWrite (Apertura, LOW);
}
else
{
//qui vanno tutte le operazioni da compiere al RILASCIO del tasto,
//UNA SOLA VOLTA, se il tasto e' rimasto premuto per piu di 1 S
digitalWrite (Apertura, HIGH);
}
}
}
nella parte dopo ELSE ho provato a inserire anche il controllo dello stato del pulsante ma non mi cambia niente, anzi rimane tutto spento.
Tra tutti i test che sto facendo mi si sta creando troppa confusione!
Non so quante volte ho cambiato le variabili, ma senza risultato,
ho rivisto lo sketch passo per passo, cambiando il tipo di variabile
docsavatage, prendendo come riferimento la parte di sketch proposta da Etemenanki hai detto che la parte if millis, è sbagliata come variabile nel test! ho provato a cambiarla con quelle citate a inizio codice senza risultati, con cosa dovrei cambiarla?
DJTech84:
Allora...
sono quasi le 3 di notte e non ne sto uscendo fuori.
Omissis
Omissis
void loop ()
{
st = digitalRead(Pulsante); //leggi ingresso pulsante
if ((st != stp) && (stp == 0)) // pulsante appena premuto
{
stp = st; //setta flag per pulsante premuto
millis_p = millis(); //setta variabile controllo tempo
}
if ((st != stp) && (stp == 1)) //pulsante appena rilasciato
{
stp = st; //resetta flag per pulsante rilasciato
if (millis() - millis_prec <= 1000) //pulsante premuto per meno di mezzo secondo
{
Omissis
}
Lo vedi che setti millis_p e fai il test su millis_prec?
o usi una o l'altra, ma se le sconfondi, sconfondi anche il programma
ALLORA...
ho optato per un altro tipo di codice e questo mi da meno problemi. anzi ad essere sincero ne rimane solo 1 e poi ho esattamente quello che mi serve.
Il problema che è rimasto è il seguente...
quando opto per l'apertura o chiusura dopo tot secondi vorrei che il relè in uso passi da HIGH a LOW...
Non posso mettere un delay alla fine perche questo mi allunga il ciclo loop e non mi fà resettare lo stato dei relè se premo il pulsante durante la fase di apertura o chiusura.
come risolvo?
DA ORA IN POI uso questo sketch per il progetto.
float DURATAPRESSIONE_milliSeconds = 0;
int CHIUSURA_milliSeconds = 2000;
int APERTURA_milliSeconds = 3000;
int STOP_milliSeconds = 1000;
int PULSANTE = 4;
int CHIUDI = 3;
int APRI = 2;
void setup(){
pinMode(PULSANTE, INPUT_PULLUP);
pinMode(CHIUDI, OUTPUT);
pinMode(APRI, OUTPUT);
}
void loop() {
while (digitalRead(PULSANTE) == LOW ){
delay(100); //if you want more resolution, lower this number
DURATAPRESSIONE_milliSeconds = DURATAPRESSIONE_milliSeconds + 100;
}
if (DURATAPRESSIONE_milliSeconds >= STOP_milliSeconds){
digitalWrite(CHIUDI, LOW);
digitalWrite(APRI, LOW);
}
if (DURATAPRESSIONE_milliSeconds >= APERTURA_milliSeconds){
digitalWrite(CHIUDI, LOW);
delay(500);
digitalWrite(APRI, HIGH);
}
else if(DURATAPRESSIONE_milliSeconds >= CHIUSURA_milliSeconds){
digitalWrite(APRI, LOW);
delay(500);
digitalWrite(CHIUDI, HIGH);
}
DURATAPRESSIONE_milliSeconds = 500;
}