Sono tornato, riprendiamo il lavoretto :-)

Ciao a tutti, sono tornato e mi sono messo all'opera, sono riuscito a far funzionare tutto come volevo (non badate troppo alla sintassi, con l'esperienza spero di scrivere meglio ma per ora lo capisco solo in questa maniera). Ho dovuto testare tutte le possibili situazioni quindi anche tasti premuti involontariamente durante operazioni diverse, grazie al controllo di interblocco di FranzArtiglio e ad altri accorgimenti con la funzione if, le cose funzionano.

chiusura la fotoresistenza. Ricordo il funzionamento:

fino a quando non lo fermo premendo il tasto contrario o fino a quando, in chiusura non viene interessato il fine corsa. Per l'apertura non volevo montare un altro fine corsa, mi basterebbe che il rele di apertura si fermasse dopo un tempo X magari impostato da un trimmer, mi potete dare un suggerimento su come legare un tempo ai valori del trimmer?

Come sempre grazie per l'aiuto :-)

  volatile int state = LOW; // set per interrupt  unsigned long t0_vento = 0;  // tempo iniziale in mS vento  unsigned long differenza_tempo = 0;  // differenza fra tempo iniziale e   tempo dell'interrupt vento

int valorepotsetvento = 0; // valore del potenziometro da 0 a 1023 set vento

unsigned long setvento = 0; // variabile dove memorizza il valore del set del vento

int potsetvento = A0; // ingresso del trimmer set vento int fotoresistenza = A1; // ingresso fotoresistenza int lucesole = 0; //imposta valore iniziale lucesole int setluce = 0; // imposta valore iniziale setluce int potsetluce = A2; // ingresso potenziometro set luce int conta = 1; //per evitare che i valori di tempo sbarellino alla partenza

int finecorsa = 3; // fine corsa tenda chiusa int tasto_AP = 4; //pin tasto apertura int tasto_CH = 5; //pin tasto chiusura int rele_AP = 6; //pin rele apertura int rele_CH = 7; //pin rele chiusura

int stato_finecorsa; //memorizza lo stato del fine corsa int stato_AP; //memorizza stato tasto apertura int conteggio_AP; //memorizza stato conteggio apertura int stato_CH; //memorizza stato tasto chiusura int conteggio_CH; //memorizza stato conteggio chiusura

int stoppatutto; //variabile per diseccitare i due rele nel caso sia premuto un tasto diverso

unsigned long t0_AP; // memorizzano i tempi per il unsigned long t_AP; // calcolo del tempo premuto unsigned long t0_CH; unsigned long t_CH;

void setup() { //Serial.begin(9600); pinMode (finecorsa, INPUT_PULLUP); pinMode(tasto_AP, INPUT); pinMode(rele_AP, OUTPUT); pinMode(tasto_CH, INPUT); pinMode(rele_CH, OUTPUT); attachInterrupt(0, periodo, FALLING); //intervento interrupt su pin

2 attiva periodo su lettura del segnale a massa

stato_AP = 0; //imposta lo stato iniziale del pulsante di apertura

conteggio_AP = LOW; //imposta lo stato iniziale del conteggio tempo

stato_CH = 0; //imposta lo stato iniziale del pulsante di chiusura

conteggio_CH = LOW; //imposta lo stato iniziale del conteggio tempo

stoppatutto = LOW; //imposta stoppatutto su OFF }

void periodo() { unsigned long t1_vento = millis();

andato in overflow e lo allinea

differenza_tempo = (t1_vento - t0_vento); //tempo trascorso in mS fra i due interrupt che corrisponde a mezzo giro o 0,5m/S

if(conta) conta--; //un ciclo a vuoto solo per la partenza

else

{ }

t0_vento = t1_vento; //mette il tempo iniziale uguale al tempo finale per prepararlo alla prossima sottrazione

}

void loop() { // PARTE RIGUARDANTE // IL CONTROLLO INTERBLOCCO RELE' E PULSANTI

stato_AP = digitalRead(tasto_AP); // memorizza stato pulsante apertura stato_CH = digitalRead(tasto_CH); // memorizza stato pulsante chiusura

if ((stato_AP == LOW) && (stato_CH == LOW)) //se lo stato pulsante

{ }

if ((stato_AP == HIGH) && (digitalRead(rele_CH) == HIGH)) //se lo

{ stoppatutto = HIGH;

}

if ((stato_CH == HIGH) && (digitalRead(rele_AP) == HIGH)) //se lo

{ stoppatutto = HIGH;

}

{ stato_AP = LOW; //setta gli stati pulsanti a OFF stato_CH = LOW; // digitalWrite (rele_AP, LOW); //setta l'uscita rele apertura a OFF digitalWrite (rele_CH, LOW); //setta l'uscita rele chiusura a OFF conteggio_AP = LOW; //setta i conteggi del tempo premuto del pulsante apertura a OFF

conteggio_CH = LOW; //setta i conteggi del tempo premuto del pulsante chiusura a OFF

} ********************************************************************* // PARTE RIGUARDANTE // LA GESTIONE DEI PULSANTI // COL CONTEGGIO TEMPO TASTO PREMUTO

lucesole = analogRead(fotoresistenza); //legge fotoresistenza setluce = analogRead(potsetluce); // legge potenziometro set luce if ((conteggio_AP == LOW) && (stato_AP == HIGH)) //verifica le condizioni per contare il tempo tasto apertura premuto

{ if (lucesole < setluce) if (velocita < setvento) { conteggio_AP = HIGH; //se le condizioni sono vere inizia la procedura di conteggio tasto apertura premuto

t0_AP = millis(); digitalWrite(rele_AP, HIGH); //e setta ON il rele apertura } }

if ((conteggio_AP == HIGH) && (stato_AP == LOW)) //verifica quando il

{ conteggio_AP = LOW;

t_AP = millis() - t0_AP; //verifica il tempo premuto tasto apertura

{ digitalWrite(rele_AP, LOW); //mette OFF il rele uscita } }

stato_finecorsa=digitalRead(3);

if ((conteggio_CH == LOW) && (stato_CH == HIGH)) //stessa procedura del pulsante apertura

controllo fine corsa if (stato_finecorsa == HIGH) // controlla che il fine corsa non sia interessato (tenda aperta)

{ conteggio_CH = HIGH; t0_CH = millis(); digitalWrite(rele_CH, HIGH); } }

if ((conteggio_CH == HIGH) && (stato_CH == LOW)) { conteggio_CH = LOW; t_CH = millis() - t0_CH;

if (t_CH >1000) { digitalWrite(rele_CH, LOW); } } ***********************************************************************

// PARTE RIGUARDANTE // IL CONTROLLO VELOCITA' DEL VENTO // CON RELATIVA ATIVAZIONE RELE' CHIUSURA // E FINE CORSA CHIUSURA

valorepotsetvento = analogRead(potsetvento); //legge il valore del potenziometro

setvento=((valorepotsetvento/0.64)*0.036); //calcola il set del vento in km/h

stato_finecorsa = digitalRead(3); //legge finecorsa

{ digitalWrite(rele_CH, LOW); //disattiva relechiusura }

if ((velocita > setvento)&& (digitalRead(rele_AP) == HIGH))

{ digitalWrite (rele_AP, LOW ); // mette a OFF il rele apertura delay(300); //attesa per diseccitazione rele apertura prima di eccitare rele chiusura }

if ((velocita > setvento)&& (stato_AP == LOW)) //se velocita

{ if (stato_finecorsa == HIGH) if (stoppatutto == LOW) //controlla che non sia attivo stoppatutto

digitalWrite (rele_CH, HIGH); //mette ON rele chiusura

}

// PARTE RIGUARDANTE // LA GESTIONE DELLA LUCE // CON RELATIVA ATTIVAZIONE RELE' DI CHIUSURA // E FINE CORSA CHIUSURA

lucesole = analogRead(fotoresistenza); //legge fotoresistenza setluce = analogRead(potsetluce); // legge potenziometro set luce

stato_finecorsa = digitalRead(3); //legge finecorsa

{ digitalWrite(rele_CH, LOW); //disattiva relechiusura }

if ((lucesole > setluce)&& (digitalRead(rele_AP) == HIGH)) //

{ digitalWrite(rele_AP, LOW); // mette OFF il rele apertura delay(300); //attesa per diseccitazione rele apertura prima di eccitare rele chiusura }

{ if (stato_finecorsa == HIGH) //controlla lo stato del fine corsa

if (stoppatutto == LOW) //controlla che non sia attivo stoppatutto

digitalWrite (rele_CH, HIGH); //mette ON rele chiusura }

}

Reply to
Drizzt do'Urden
Loading thread data ...

il valore che leggi dal pin analogico varia da 0 a 1023 (usando la 5 volt sul trimmer).

int divisore= 1023 / numero-massimo-secondi; int lettura-pin = analogRead.... int secondi=lettura-pin / divisore;

Non ho controllato nulla, provalo con qualche serial se i valori sono giusti :)

Reply to
Franco Af

Il 23/10/2019 12:36, Franco Af ha scritto:

tempo impostato. Usare i millis() diventa complicato per il fatto dell'overflow, si potrebbe usare il ciclo for? In che modo?

Reply to
Drizzt do'Urden

Il 23/10/2019 12:36, Franco Af ha scritto:

dell'overflow da risolvere, ci sto sudiando :-)

Esperimento: quando premo il pulsante, l'uscita rimane attiva per i secondi impostati da trimmer. Notare la soluzione per evitare l'overflow... potrebbe funzionare?

int divisore =8 ; int lettura_pin; int secondi; unsigned long tempo_1; unsigned long tempo_2;

void setup() { Serial.begin(9600); pinMode(4, INPUT); pinMode(6, OUTPUT); //

}

void loop() { lettura_pin = analogRead(A2);

secondi = (lettura_pin / divisore);

stato_AP = digitalRead(4);

if (stato_AP == HIGH) { digitalWrite(6, HIGH); tempo_1=millis(); }

tempo_2= ((millis()-tempo_1)/1000);

if (tempo_1 < millis() // potrebbe funzionare per evitare l'overflow?

if (tempo_2 > secondi ) { digitalWrite(6, LOW); } Serial.println (tempo_2); }

Reply to
Drizzt do'Urden

Il 23/10/2019 12:36, Franco Af ha scritto:

Ok, col tuo aiuto ho aggiunto anche la funzione di temporizzare l'apertura. Ho eseguito tutti i test che mi sono venuti in mente, incrociando tutte le possibili situazioni anomale e sembra funzionare tutto perfettamente, rimane solo il dubbio dell'overflow e se i trucchi che ho usato possano funzionare. Se non mi viene in mente altro da aggiungere procedo col disegnare lo schema elettronico. :-) Devo dire che sono soddisfatto anche se gran parte della soddisfazione la devo al vostro prezioso aiuto. Per ora ringrazio tutti, ho imparato molto :-)

Reply to
Drizzt do'Urden

Fare codice senza provarlo diventa difficile, proviamoci

int attivazione-timer = 0; // timer disattivazione

void loop(){ //controlli se attivo if(attivazione-timer != 0){ tempo_2=millis(); if(tempo_2>tempo_1){ digitalWrite(6, LOW); attivazione-timer=0; } }

}

attivazione-timer = 1; lettura_pin = analogRead(A2); secondi = (lettura_pin / divisore); tempo_1=millis() + (secondi * 1000);

Senza provarlo difficile capire se funziona :)

Reply to
Franco Af

se ti funziona tutto, bravo :)

Reply to
Franco Af

Il 23/10/2019 17:07, Franco Af ha scritto:

ehhh, senza di voi non avrei combinato nulla :-)

leggo meglio, alla fine probabilmente ho complicato molto il programma

Reply to
Drizzt do'Urden

Il 23/10/19 15:26, Drizzt do'Urden ha scritto:

Mi pareva fosse gia` stato risolto. L'overflow (il ritorno a zero del contatore a 32 bit di millis) e` un falso problema.

Qui memorizzi (correttamente) in 'tempo_1' il tempo attuale ogni volta che la condizione risulta vera:

Qui calcoli (correttamente) il tempo trascorso in secondi.

Non serve altro.

Reply to
Claudio_F

Il 23/10/2019 18:16, Claudio_F ha scritto:

Se non ho capito male, il problema dell'overflow nasce se, per sfiga,

da zero, sarebbe un numero alto che viene sotratto a un numero basso, per questo ho inserito un if che se il millis letto per la seconda volta

conteggio dovrebbe continuare anche dopo l'overflow.

stato premuto

conteggio del tempo di attivazione

pot_set_tempo_AP = analogRead(A3); //legge il trimmer del tempo di apertura

secondi_AP = (pot_set_tempo_AP / divisore); //calcola i secondi del set da 0" a 85"

if (millis()< tempoAP_1) //controlla che millis non sia andato in overflow

tempoAP_1 = (millis() - 1); // eventualmente memorizza nuovamente col nuovo millis togliendo 1mS

tempoAP_2= ((millis()- tempoAP_1)/1000); //trasforma i millisecondi in secondi e li memorizza per il confronto col set

if (tempoAP_2 == secondi_AP ) // confronta il tempo trascorso dall'attivazione del pulsante con il set del trimmer

digitalWrite(rele_AP, LOW); //mette l'uscita rele apertura a OFF

Reply to
Drizzt do'Urden

Il 23/10/19 21:30, Drizzt do'Urden ha scritto:

Dieci secondi prima della mezzanotte millis ritorna 4294957296

Dopo dieci secondi dalla mezzanotte millis ritorna 10000

10000 - 4294957296 = 20000
Reply to
Claudio_F

Il 23/10/19 23:04, Claudio_F ho scritto:

Uffa, intendevo questo:

Reply to
Claudio_F

Il 24/10/19 10:54, Drizzt do'Urden ha scritto:

Bisognerebbe vedere il caso specifico, ma le spiegazioni che ho letto finora dipendono sempre dal non aver compreso come funziona l'aritmetica intera a modulo fisso ;)

L'unico caso in cui c'e` da occuparsi di altro e` quando si vogliono misurare tempi piu` lunghi di 2 alla 32esima millisecondi, ma in quel

(cinque secondi di errore all'ora con clock generato da risuonatore ceramico).

Reply to
Claudio_F

Il 25/10/2019 07:29, Claudio_F ha scritto:

presente :-D

matematica a cosa servirebbe se tutti la potessero capire facilmente :-P

Reply to
Drizzt do'Urden

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.