Salve a tutti ,
Vengo subito al sodo;
Ho realizzato un piccolo circuito per testare il funzionamento di una scheda con 4 rele.
Ho utilizzato quindi 4 pulsanti che a loro volta comandano singolarmente i 4 rele , ma siccome l'appetito vien mangiando mi sono spinto un pelino oltre in quanto vorrei che il mio programma funzionasse in questo modo:
Per comodità prenderò in esame solo una canale
- premo il pulsante
- accendo il rele
- rilascio il pulsante
- attendo i secondi impostati
- spengo il rele
e tutto questo lo vorrei fare su ogni rele indipendentemente come se fossero dei temporizzatori singoli.
invece il mio test funziona in questo modo:
- premo il pulsante (qualche secondo di attesa)
- accendo il rele
- rilascio il pulsante
- attendo i secondi impostati
- spengo il rele
Per comodità prenderò in esame solo una canale
scusate gli errori ortografici (ma come dico sempre) le correzioni sono ad esclusivo carico di chi legge!
Grazie in anticipo
// Gestione di 4 ingressi e quattro uscite a rele di cui 2 temporizzate
const int buttonPin1 = 13; // assegna indirizzo ingresso
const int buttonPin2 = 12; // assegna indirizzo ingresso
const int buttonPin3 = 11; // assegna indirizzo ingresso
const int buttonPin4 = 10; // assegna indirizzo ingresso
const int ledPin1 = 7; // assegna indirizzo uscita
const int ledPin2 = 6; // assegna indirizzo uscita
const int ledPin3 = 5; // assegna indirizzo uscita
const int ledPin4 = 4; // assegna indirizzo uscita
int buttonState1 = 0; // azzera la variabile
int buttonState2 = 0; // azzera la variabile
int buttonState3 = 0; // azzera la variabile
int buttonState4 = 0; // azzera la variabile
// definizione uscite
void setup() {
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
// definizione ingressi
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
pinMode(buttonPin3, INPUT);
pinMode(buttonPin4, INPUT);
}
void loop() {
buttonState1 = digitalRead(buttonPin1); // leggi lo stato del pin13
if (buttonState1 == HIGH) { // se il pulsante è alto
delay(2000); // aspetta 2sec
digitalWrite(ledPin1, HIGH); // scrivi lo stato alto del pin7
} else { // atrimenti
digitalWrite(ledPin1, LOW); // scrivi lo stato basso del pin7
}
buttonState2 = digitalRead(buttonPin2);
if (buttonState2 == HIGH) {
delay(2000);
digitalWrite(ledPin2, HIGH);
} else {
digitalWrite(ledPin2, LOW);
}
buttonState3 = digitalRead(buttonPin3);
if (buttonState3 == HIGH) {
delay(2000);
digitalWrite(ledPin3, HIGH);
} else {
digitalWrite(ledPin3, LOW);
}
buttonState4 = digitalRead(buttonPin4);
if (buttonState4 == HIGH) {
delay(2000);
digitalWrite(ledPin4, HIGH);
} else {
digitalWrite(ledPin4, LOW);
}
}
scusate ho commesso un errore nella spiegazione del funzionamento:
- premo il pulsante
2.attendo i secondi impostati
- accendo il rele
- rilascio il pulsante
- spengo il rele
mentre funziona cosi:
- premo il pulsante
2.attendo i secondi impostati
- accendo il rele
- rilascio il pulsante
pausa du qualche secondo
- spengo il rele
hai messo le resistenze di pull-down sui pulsanti....
Il problema è il delay()...devi usare millis()...cambiando ovviamente l'impostazione del programma.
ORSO2001:
Il problema è il delay()...devi usare millis()...cambiando ovviamente l'impostazione del programma.
se il problema è sul ritardo nello spegnimento... non credo siano i delay presumo che il pin dell'interruttore non vada subito a zero quando rilasciato
ad ogni modo servirebbe anche lo schema elettrico
sicuramente serve che il tutto sia cablato a dovere (resistenze incluse)...però se ci pensi bene al rilascio del pulsante avrà sempre un effetto di ritardo di 2 secondi dato da delay()...perchè la prima cosa che fa è la verifica dell'if...se premuto aspetta 2 secondi ...la verifica se tasto ancora premuto o no lo fa dopo questi
Patrick_M:
hai messo le resistenze di pull-down sui pulsanti....
certo sotto il punto di vista elettrico non ho alcun problema , in una versione precedente di questo sketch, cioè quella con l'accensione ON OFF non ho alcun problema
ORSO2001:
sicuramente serve che il tutto sia cablato a dovere (resistenze incluse)...però se ci pensi bene al rilascio del pulsante avrà sempre un effetto di ritardo di 2 secondi dato da delay()...perchè la prima cosa che fa è la verifica dell'if...se premuto aspetta 2 secondi ...la verifica se tasto ancora premuto o no lo fa dopo questi
assodato che tutto è stato cablato correttamente questa è un interessante considerazione ...... quindi?
di seguito un esempio che puoi provare per un pulsante collegato al pin 2 che, se premuto per più di due secondi accende il LED di arduino collegato al pin 13...se pulsante rilasciato si spegne subito:
#define PULS 2
#define RELE 13
unsigned long myMillis;
void setup() {
pinMode(PULS, INPUT);
pinMode(RELE, OUTPUT);
digitalWrite(RELE, LOW);
}
void loop() {
if (!digitalRead(PULS)) {
myMillis = millis();
}
if (millis() - myMillis >= 2000) {
digitalWrite(RELE, HIGH);
}
else {
digitalWrite(RELE, LOW);
}
}
ORSO2001:
di seguito un esempio che puoi provare per un pulsante collegato al pin 2 che, se premuto per più di due secondi accende il LED di arduino collegato al pin 13...se pulsante rilasciato si spegne subito:
#define PULS 2
#define RELE 13
unsigned long myMillis;
void setup() {
pinMode(PULS, INPUT);
pinMode(RELE, OUTPUT);
digitalWrite(RELE, LOW);
}
void loop() {
if (!digitalRead(PULS)) {
myMillis = millis();
}
if (millis() - myMillis >= 2000) {
digitalWrite(RELE, HIGH);
}
else {
digitalWrite(RELE, LOW);
}
}
ho provato il tuo codice ma fà quasi la stessa cosa .....
se hai provato esattamente il mio codice...cioè con un solo pulsante e facendo riferimenti al LED_BUILTIN di arduino (quello sulla scheda)...è impossibile che non si spenga subito al rilascio del pulsante...salvo problemi hardware/cablaggio...io l'ho testato con il PIN 2 impostato come INPUT_PULLUP e quindi devo chiudere il pulsante verso GND per cambio stato...e quindi la logica di lettura del PIN 2 è invertita...ma ti garantisco che funziona...controlla le pull down...pubblica lo schema di come hai cablato
con la scheda nuda 
cambia
pinMode(PULS, INPUT);
in pinMode(PULS, INPUT_PULLUP);
compila e trasferisci
collegando a gnd il pin 2 con un cavetto
e farà esattamente questo
- premo il pulsante
2.attendo i secondi impostati
- accendo il rele
- rilascio il pulsante
- spengo il rele
come dice ORSO2001
edit no, fino a quando non rilascio il pulsante non parte il conteggio del tempo e il led non si accende... io l'ho modificato così
#define PULS 2
#define RELE 13
unsigned long myMillis;
boolean flag = false;
void setup() {
pinMode(PULS, INPUT_PULLUP);
pinMode(RELE, OUTPUT);
digitalWrite(RELE, LOW);
}
void loop() {
if (!digitalRead(PULS) && (flag==false)) {
myMillis = millis();
flag=true;
}
if ((millis() - myMillis >= 2000) && (flag==true)) {
digitalWrite(RELE, HIGH);
flag= false;
}
else if (digitalRead(PULS)){
digitalWrite(RELE, LOW);
}
}
non capisco...in questo caso il flag pulsante non serve...ragioniamo....:
millis avanza
pulsante NON premuto ->mioTempo = millis
è millis > di mioTempo di 2 secondi -> NO
millis avanza
pulsante premuto ->non salvo più millis in mioTempo
è millis > di mioTempo di 2 secondi -> se mantengo premuto il pulsante si
a me funziona alla grande...così:
#define PULS 2
#define RELE 13
unsigned long myMillis;
void setup() {
pinMode(PULS, INPUT_PULLUP);
pinMode(RELE, OUTPUT);
digitalWrite(RELE, LOW);
}
void loop() {
if (digitalRead(PULS) == HIGH) {
myMillis = millis();
}
if (millis() - myMillis >= 2000) {
digitalWrite(RELE, HIGH);
}
else {
digitalWrite(RELE, LOW);
}
}
Buongiorno, sono riuscito finalmente a venirne a capo ...... ho modificato qualcosa rispetto lo sketch di ORSO e ho cambiato qualcosa anche sul cablaggio.
#define PULS1 13
#define PULS2 12
#define PULS3 11
#define PULS4 10
#define RELE1 7
#define RELE2 6
#define RELE3 5
#define RELE4 4
unsigned long myMillis1;
unsigned long myMillis2;
unsigned long myMillis3;
unsigned long myMillis4;
void setup() {
pinMode(PULS1, INPUT);
pinMode(PULS2, INPUT);
pinMode(PULS3, INPUT);
pinMode(PULS4, INPUT);
pinMode(RELE1, OUTPUT);
pinMode(RELE2, OUTPUT);
pinMode(RELE3, OUTPUT);
pinMode(RELE4, OUTPUT);
digitalWrite(RELE1, LOW);
digitalWrite(RELE2, LOW);
digitalWrite(RELE3, LOW);
digitalWrite(RELE4, LOW);
}
void loop() {
if (!digitalRead(PULS1)) {
myMillis1 = millis();
}
if (millis() - myMillis1 >= 2000) {
digitalWrite(RELE1, LOW);
}
else {
digitalWrite(RELE1, HIGH);
}
if (!digitalRead(PULS2)) {
myMillis2 = millis();
}
if (millis() - myMillis2 >= 2000) {
digitalWrite(RELE2, LOW);
}
else {
digitalWrite(RELE2, HIGH);
}
if (!digitalRead(PULS3)) {
myMillis3 = millis();
}
if (millis() - myMillis3 >= 2000) {
digitalWrite(RELE3, LOW);
}
else {
digitalWrite(RELE3, HIGH);
}
if (!digitalRead(PULS4)) {
myMillis4 = millis();
}
if (millis() - myMillis4 >= 2000) {
digitalWrite(RELE4, LOW);
}
else {
digitalWrite(RELE4, HIGH);
}
}
adesso il programma fà esattamente ciò che volevo
bene!
...comunque a me sembra esattamente quello che avevo postato la prima volta ripetuto per 4 pulsanti... 
poi se vuoi si possono evitare tutti quegli if/else creando delle array e usando for().
ORSO2001:
non capisco...in questo caso il flag pulsante non serve...ragioniamo....:
millis avanza
pulsante NON premuto ->mioTempo = millis
è millis > di mioTempo di 2 secondi -> NO
millis avanza
pulsante premuto ->non salvo più millis in mioTempo
è millis > di mioTempo di 2 secondi -> se mantengo premuto il pulsante si
a me funziona alla grande...così:
#define PULS 2
#define RELE 13
unsigned long myMillis;
void setup() {
pinMode(PULS, INPUT_PULLUP);
pinMode(RELE, OUTPUT);
digitalWrite(RELE, LOW);
}
void loop() {
if (digitalRead(PULS) == HIGH) {
myMillis = millis();
}
if (millis() - myMillis >= 2000) {
digitalWrite(RELE, HIGH);
}
else {
digitalWrite(RELE, LOW);
}
}
Si hai ragione mi ha inganato il tuo discorso successivo riferito alla input_pullup per cui ragionavo al contrario 
usando la negazione nell'if e il pullup funziona anche il mio 
ovviamente è più semplice togliere la negazione e anche il flag...
ORSO2001:
bene!
...comunque a me sembra esattamente quello che avevo postato la prima volta ripetuto per 4 pulsanti... 
poi se vuoi si possono evitare tutti quegli if/else creando delle array e usando for().
certo è esattamente il tuo codice ma se noti ho dovuto invertire gli stati del pulsante e del rele (ma forse è dovuto al cablaggio)
Lavorare per semplificare il codice è un lavoro che ho intenzione di fare ......