Buongiorno a tutti e buona Domenica.
Avrei l'esigenza di comandare due specchietti richiudibili elettricamente del mio furgone, in quanto è arrivato senza.
Una volta ordinati i suoi specchi originali motorizzati, ho realizzato il cablaggio ( perchè non era presente ) e attraverso un pulsante installato sulla portiera ( il suo originale modificato ) ho risolto il problema.
Arduino uno ( solo Atmega ) due relè, sketch a 2 stati temporizzati a 4 secondi e tutto funziona, memorizzo anche l'ultima posizione ( aperto o chiuso ) nella EEProm interna per "ricordare" dove si trovava prima di togliere alimentazione al sistema.
In un primo momento avevo usato la funzione delay per la temporizzazione, ma visto che Arduino si blocca fino a che non è finito il tempo, ho sostituito delay con millis per non bloccare tutto perchè avrei bisogno che durante l'apertura o la chiusura, un'ulteriore pressione del pulsante inverta il senso.
Spero di essere stato chiaro nell'esposizione e chiedo il permesso di postare il codice per capire come posso fare.
Grazie
Certo che puoi postare il codice, anzi mi permetterei anche di dire devi ![]()
Dal messaggio però non mi è chiaro quale sia il problema che hai riscontrato.
Grazie cotestatnt per l'interessamento. In realtà quello che vorrei facesse non è un problema , ma piuttosto una miglioria. Comunque posto il listato per far capire meglio il tutto.
#include <EEPROM.h>
unsigned long tempo = 4000; // valore di temporizzazione per apertura/chiusura specchi
unsigned long t1;
int stato;
int in;
void setup()
{
#define led_1 11 // assegno il pin 11 alla variabile led_1 che è usato per il LED 1 ( apre specchi )
#define led_2 12 // assegno il pin 12 alla variabile led_2 che è usato per il LED 2 ( chiude specchi )
#define puls 2 // il pin 2 è usato per il PULSANTE
stato = EEPROM.read(71); // legge il dato memorizzato alla posizione 71 della EEProm
pinMode(2, INPUT); // definisce il pin 2 di arduino come ingresso per il pulsante
pinMode(11, OUTPUT); // definisce il pin 11 come uscita per il pilotaggio del led o del relè
pinMode(12, OUTPUT); // definisce il pin 12 come uscita per il pilotaggio del led o del relè
digitalWrite(led_1, LOW); // parte con l'uscita 1 ( apertura specchi ) a zero cioè fermo
digitalWrite(led_2, LOW); // parte con l'uscita 2 ( chiusura specchi ) a zero cioè fermo
//stato = 0;
}
void loop()
{
switch (stato)
{
case 0:
apre();
break;
case 1:
chiude();
break;
}
}
void apre()
{
in = digitalRead(puls); // assegna lo stato del pulsante
if (in == LOW) // controlla se il pulsante è stato premuto
{
digitalWrite(led_1, HIGH); // accendiamo il LED 1 ( apertura specchi )
t1 = millis(); // leggo quanto vale millis
}
if ((millis() - t1) >= tempo) // controllo se il tempo è trascorso
{
digitalWrite(led_1, LOW); // spegniamo il LED 1 ( fermo apertura specchi )
t1 = millis(); // leggo quanto vale millis
stato = 1; // cambio stato
EEPROM.write(71, stato); // scrivo la posizione nella EEProm
delay(100); // ritardo per scrittura EEProm
}
}
void chiude()
{
in = digitalRead(puls); // assegna lo stato del pulsante
if (in == LOW) // controlla se il pulsante è stato premuto
{
digitalWrite(led_2, HIGH); // accendiamo il LED 2 ( apertura specchi )
t1 = millis(); // leggo quanto vale millis
}
if ((millis() - t1) >= tempo) // controllo se il tempo è trascorso
{
digitalWrite(led_2, LOW); // spegniamo il LED 2 ( fermo chiusura specchi )
t1 = millis(); // leggo quanto vale millis
stato = 0; // cambio stato
EEPROM.write(71, stato); // scrivo la posizione nella EEProm
delay(100); // ritardo per scrittura EEProm
}
}
A parte che con solo quei due case nel loop sembra che non possa fare nulla salvo l'intervento di un interrupt che non ho trovato, invece apre e chiude fanno ben altro che ciò che promettono, ancora non c'è una domanda...
Come dice @Datman, non assegni mai alcun valore alla variabile stato fatta eccezione all'inizio leggendo il valore dall'EPPROM
Gli stati, per come la vedo io dovrebbero essere almeno 4: CHIUSO, APERTURA, APERTO, CHIUSURA.
In questo modo puoi discriminare il comportamento del pulsante in funzione di ciò che è necessario.
Se lo stato è CHIUSO, sai che dovrai andare in APERTURA e stessa cosa se è APERTO.
Se invece è APERTURA o CHIUSURA sai che che devi invertire il movimento.
stato viene modificata in apre e in chiude trascorso il tempo previsto.
Dando un indice a led, poi, sarebbe sufficiente una sola funzione eseguita due volte.
Grazie a tutti e due, come dice Datman effettivamente non riesco a fargli fare altro. La mia esigenza è questa: premo il pulsante si aprono gli specchi, mentre si stanno aprendo avrei bisogno che ad un'altra pressione del pulsante si inverta il moto ( analogamente nell'altro senso ).
Ho provato ad inserire altri 2 "case", come dice cotestatnt, ma rimane bloccato fino a che non finisce il tempo e non riesco ad invertire il moto durante la temporizzazione.
Ovviamente non c'è nessun interrupt che possa intervenire perchè è un solo pulsante che deve gestire il tutto.
Specchietti chiusi: fase 0.
Se la fase è 0 e premo il pulsante, va in fase 1 e apre gli specchietti.
Quando gli specchietti sono aperti, va in fase 2.
Se la fase è 2 e premo il pulsante, va in fase 3 e chiude gli specchietti.
Quando gli specchietti sono chiusi, torna in fase 0.
Si infatti questo lavoro lo fa già. La mia esigenza è che mentre si stanno aprendo o chiudendo, premendo il pulsante si deve invertire la corsa, non quando sono già fermi.
Cioè l'inversione deve accadere alla pressione del pulsante ma prima che finisca il tempo.
Mi sono permesso di fare uno sketch wokwi (che trovo molto utile per queste piccole cose) partendo dal tuo codice.
Ho modificato però la connessione del pulsante mettendolo a pullup perché più semplice da disegnare. Ho aggiunto anche qualche messaggio sulla seriale per scandire con chiarezza le transizioni di stato.
Il concetto che sta alla base è: prima leggo la pressione del pulsante (a cui ho aggiunto un po' di codice per gestire il bouncing del contatto), e poi valuto il da farsi in funzione dello stato attuale.
Sarebbe interessante espandere ulteriormente lo sketch gestendo il tempo rimanente in caso di inversione del movimento in modo da non sforzare inutilmente il motorino.
Ho modificato però la connessione del pulsante mettendolo a pullup
Veramente vedo che tira giù a massa...
Si Dataman il pulsante è già a pullup, perchè sul mezzo il pulsante itra verso massa..
Comunque cotestatnt, semplicemente perfetto anche se devo capire bene come hai gestito il pulsante e la variabile in come argomento di if...
Grazie delle dritte, adesso vedo di gestire al meglio il tempo per non mettere i motorini in sofferenza.....grazie ancora a Dataman e cotestatnt...
Il pulsante è a pull-up quindi digitalRead() == LOW quando è premuto che è equivalente a scrivere digitalRead() == 0 ovvero !digitalRead() condizione che diventa vera quando il pulsante è premuto.
[quote] la variabile in come argomento di if.
[/quote]
Se devi fare un if quando la condizione di test è true (ovvero un numero diverso da zero), puoi omettere l'operatore ==
ok tutto chiaro. Grazie ancora
La resistenza sul pulsante è di pull-up, perché tira verso l'alto! Il pulsante chiude verso massa, quindi down.
è concettualmente sbagliato.
Si esatto il pulsante mi serviva così....Grazie anche a te per i suggerimenti
Non capisco cosa intendi in tutta sincerità. Se la resistenza è di pull-up il segnale corrispondente al pulsante premuto è a livello LOW quindi nell'if è quello il livello di tensione che vado a cercare.
Voglio dire che la resistenza, sì, è di pull-up, ma non si può dire che il pulsante è collegato in pull-up! Io solitamente dico che il pulsante chiude a massa, in modo da non poter dare luogo a fraintendimenti.