Vai al contenuto
PLC Forum


dubbio su I2C


D80

Messaggi consigliati

Bene!

La sintassi che usi continua ad essere sbagliata, strano che tutto funzioni ugualmente... devi scrivere digitalRead(pin) == HIGH e non digitalRead(pin == HIGH), questa mi era sfuggita anche l'altra volta.

Poi potresti iniziare a fare qualche ottimizzazione, ad esempio :

 

void apri()
{
  if(digitalRead(fcap)==HIGH && digitalRead(out2)==LOW) digitalWrite(out1,HIGH);
  else digitalWrite(out1,LOW)
}

void chiudi()
{
  if(digitalRead(fcch)==HIGH && digitalRead(out1)==LOW) digitalWrite(out2,HIGH);
  else digitalWrite(out2,LOW)
}

così nel loop puoi fare :

if (digitalRead(manualmode) == HIGH)
{
  if(digitalRead(P1) == HIGH) apri();
  if(digitalRead(P2) == HIGH) chiudi();
}
else
{
  //codice per in funzionamento automatico
}

Dipende molto anche dai gusti dalle attitudini individuali, ma a me così pare più leggibile ed interpretabile.

Se vuoi qualche esempio di codice non bloccante per gestire l'automatico non hai che da chiedere.

 

Ciao, Ale.

 

DISCLAIMER : il codice non è testato, quindi può contenere errori/incongruenze.

Link al commento
Condividi su altri siti


  • Risposte 66
  • Created
  • Ultima risposta

Top Posters In This Topic

  • D80

    33

  • Livio Orsini

    21

  • ilguargua

    6

  • gabri-z

    2

if(digitalRead(fcap)==HIGH && digitalRead(out2)==LOW) digitalWrite(out1,HIGH);

 

Io scrivrei

 

if((digitalRead(fcap)==HIGH) && (digitalRead(out2)==LOW)) 
                                     digitalWrite(out1,HIGH);

 

Se guardi in una precedente discussione (credo fosse aperta da Francesco Querin) ho messo il codice per il timer1 che genera il clock per gestire le varie letture e scritture periodiche.

Se non lo trovi o hai difficoltà lo posso ripubblicare con esempi di lettura.

Link al commento
Condividi su altri siti

 il collaudo ha funzionato a metà, nel senso che se le condizioni sono instabili la tenda apre e chiude continuamente, anche con istreesi dei valori minimi e massimi di vento, evidentemente devo usare qualcosa che  possa sostituire il delay , sto provando a documentarmi sui timer e interrupt e non appena sarà possibile posterò nuovamente il programma

Link al commento
Condividi su altri siti

Al di la del fatto che documentarsi su cose che non si conoscono è sempre bene, non hai necessariamente bisogno di timer e interrupt per un ritardo non bloccante. In genere si usa la funzione millis () , registrando in una variabile (unsigned long) quando l'evento appare e controllando nei cicli successivi se l'evento è ancora presente sommando al valore salvato il ritardo desiderato. Per un esempio guarda tra gli esempi dell'IDE di arduino sotto digital->blinkWithoutDelay.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

sono riuscito a snellire il codice utilizzando gli operatori || e && , ho provato a correggere la sintassi, aggiungere un'ulteriore condizione per evitare il conflitto dei due pulsanti attivi contemporaneamente e ho inserito un solo delay di un minuto,

 

dalla "prova al banco" ora funziona bene anche dopo diverse prove sia in modalità manuale che automatica,  non mi resta che fare il pcb per le regolazioni delle soglie del vento e della luminosità con i  potenziometri, cosa che ho simulato finora con gli interruttori, 

 

 

 

 

eccovi il nuovo sketch:

 

const int manualmode = 31;     // interruttore man/auto: man = chiuso(HIGH), auto = aperto (LOW)
const int P1 = 33;                     // pulsante apertura manuale (N.O.)
const int P2 = 35;                     // pulsante chiusura manuale (N.O.)     N.B:  P1+P2 = pulsante doppio N.O.  con interblocco meccanico 
const int fcap = 37;                  // finecorsa tenda aperta (N.C.)
const int fcch = 39;                  // finecorsa tenda chiusa (N.C.)
const int sventomin = 41;        // contatto(N.C.)sensore vento soglia minima (soglia tarabile tramite potenziometro pot1)
const int sventomax =43;        // contatto(N.C.)sensore vento soglia massima (soglia tarabile tramite potenziometro pot2)
const int spioggia = 45;           // contatto  sensore pioggia (N.O. in assenza di pioggia)
const int slum = 47;                 // contatto rele sensore luminosità (N.O. in condizioni di bassa luminosità tarabile tramite potenziometro pot3)
const int out1 = 49;                 // uscita relè apertura
const int out2 = 51;                 // uscita relè chiusura

 

int manualmodeState = 0;
int P1State = 0;         
int P2State = 0; 
int fcapState = 0;
int fcchState = 0;
int sventominState = 0;
int sventomaxState =0;
int spioggiaState = 0;
int slumState = 0;

 

 void setup(){
pinMode(manualmode,INPUT);  
pinMode(P1, INPUT);         
pinMode(P2, INPUT);
pinMode(fcap, INPUT);
pinMode(fcch, INPUT);
pinMode(sventomin, INPUT);
pinMode(sventomax, INPUT);
pinMode(spioggia, INPUT);
pinMode(slum, INPUT);
pinMode(out1,OUTPUT);
pinMode(out2,OUTPUT);
}


void loop()

{
if (out1 == HIGH ){digitalWrite(out2,LOW);} 
if (out2 == HIGH) {digitalWrite(out1,LOW);}
if (digitalRead(P1) == HIGH&& digitalRead(P2) == HIGH)

{digitalWrite(out1,LOW);  digitalWrite(out2,LOW);}                                                                    

 

//comando manuale
if (digitalRead(manualmode) == HIGH && digitalRead(P1) == HIGH && digitalRead (fcap) == HIGH){digitalWrite(out1, HIGH); }                                                           
else {digitalWrite(out1, LOW); }                                                              

if (digitalRead(manualmode) == HIGH && digitalRead(P2) == HIGH && digitalRead (fcch) == HIGH){digitalWrite(out2, HIGH); }                                                           
else {digitalWrite(out2, LOW); }  

 

//comando automatico
if (digitalRead(manualmode) == LOW && digitalRead(sventomin) == LOW && digitalRead(spioggia) == LOW && digitalRead(slum) == HIGH   && digitalRead (fcap) == HIGH)
{digitalWrite(out1, HIGH); }
else{digitalWrite(out1, LOW); }

if (digitalRead(manualmode) == LOW && digitalRead (fcch) == HIGH || digitalRead(sventomax) == HIGH || digitalRead(spioggia) == HIGH || digitalRead(slum) == LOW  )
{delay(60000);}
if (digitalRead(manualmode) == LOW && digitalRead (fcch) == HIGH || digitalRead(sventomax) == HIGH || digitalRead(spioggia) == HIGH || digitalRead(slum) == LOW  )
{digitalWrite(out2, HIGH); }

 

else {digitalWrite(out2, LOW); }
}
 

 

 

P.S.: 

ho notato che arduino legge corretto sia  la sintassi

 

"digitalRead(P1) == HIGH"

 

che 

 

" digitalRead(P1 == HIGH) "

 

 

Link al commento
Condividi su altri siti

Quote

In genere si usa la funzione millis () , .....

 

Con questa funzione ottieni un ritardo più o meno preciso, a meno di stare in loop sul test eseguendo una funzione bloccante.

Se invece si vuole una temporizzazione precisa ed un uso della risorsa CPU su più tasks e jobs si deve necessariamente ricorrere alle interruzioni di un timer.

 

1 ora fa, D80 scrisse:

non mi resta che fare il pcb per le regolazioni delle soglie del vento e della luminosità con i  potenziometri, cosa che ho simulato finora con gli interruttori, 

 

Cura bene le alimentazioni ed i percorsi degli I/O di arduino. Sono i punti di ingresso dei disturbi che possono bloccare o mandare la CPU "per farfalle".

 

Rifai tutto arduino o ti limiti al pcb degli I/O?

Se usi la scheda arduino hai previsto l'uso della shield con morsettiere?

Per un'applicazione del genere potrebbe essere sufficiente un arduino nano montato su un PCB con morsettiere, se ne trovano per pochi euro su ebay; io è una soluzione che ho usato con soddisfazione.

Link al commento
Condividi su altri siti

1 ora fa, Livio Orsini scrisse:

Con questa funzione ottieni un ritardo più o meno preciso, a meno di stare in loop sul test eseguendo una funzione bloccante.

 

Quale sarebbe la funzione bloccante? Nel loop ti limiti a controllare quanto tempo è passato leggendo millis(), non capisco dove stia il blocco. Sulla precisione in effetti puoi perdere qualche millisecondo, infatti si controlla sempre che il valore sia >=, ma francamente su un ritardo di 5/6 secondi mi sembra ininfluente. Io ad esempio il timer con interrupt lo uso per leggere un encoder rotativo (intendo quelli tipo potenziometro che si usano nelle GUI), i pulsanti ed i sensori "lenti" come in questo caso si leggono senza problemi anche nel loop, se lo si mantiene veloce e senza blocchi.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

sto studiando un po' tutta la situazione:

 

 metto l'arduino in un supporto da barra din e uso la shield con le morsettiere, sarà posto in un quadretto assieme ai relè, il  pcb dove saranno presenti le resistenze  e regolazione delle soglie  ,  un alimentatore per la parte elettronica, un trasformatore di isolamento per il motore della la tenda,   protezioni ecc 

 

utilizzo un quadro da parete a 36 moduli in tre linee, nella prima ci sarà tutta la sezione a tensione di rete, nella seconda l'arduino e tutta l'elettronica e nella terza le morsettiere

 

 

dentro una 503  saranno presenti l'interruttore per la modalità manuale e il pulsante sali scendi 

 

dal quadretto vi saranno:

un tubo che viene da una scatola di derivazione per portare la tensione di rete, 

un tubo per i cavi dei finecorsa ,

un tubo per i cavi provenienti dai sensori

un tubo per i cavi per i comandi.

 

come cavo di potenza per alimentare il motore uso un H07RNF 4x1.5mmq

 

mentre per i  segnali ho intenzione di usare  un cavo schermato utp cat5  che ho in casa , ( tutti i conduttori non collegati e lo schermo andranno collegati a gnd)

 

 

 

 

la distanza dal quadro ai sensori è di 8 metri

la distanza dal quadro alla tenda è di 5 metri

la distanza dal quadro alla 503 dove sono i comandi è di 2 metri

tutti i tubi sono tutti da 20mm 

 

 

Link al commento
Condividi su altri siti

Per curiosità : i fine corsa come sono fatti? Quanti contatti hanno? Perchè, per sicurezza, non sarebbe male usarli anche per bloccare direttamente il motore.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

il 27/8/2017 at 12:04 , D80 scrisse:

per quanto riguarda il punto cieco in cui ero incappato non ho proprio risolto nella maniera che mi sarebbe piaciuta , ma ... funge:

 

utilizzo i contatti dei finecorsa   di apertura e chiusura per alimentare dei  dei relè ( due per l'apertura e due per la chiusura)  utilizzo  il contatto di un relè per il comando del motore ed il contatto di un secondo relè lo utilizzo come digital input per  l'indicazione di tenda aperta o chiusa  , in questo modo potrò visualizzare lo stato della tenda  qualsiasi sia la modalità impostata, aggiungendo però due ulteriori input nell' Arduino e ben 4 relè in più ( due di potenza e due non di potenza , tutti con boboina a 230V ) , è poco ortodosso  per il momento non mi viene in mente altro,

lo avevo già spiegato un po' di tempo fà , l'obbiettivo era di utilizzare un diplay lcd per visualizzare lo stato della tenda e dei sensori, è una parte dello sketch che non ho ancora scritto ma lo farò a breve,  comunque appena posso posterò tutti gli schemi ed il tutto sarà più comprensibile, i relè comandati dai finecorsa  saranno posizionati all'interno del quadro e quelli di potenza che comanderanno il senso di marcia del motore  verranno alimentati dalla scheda relè di arduino, posti sempre all'interno del quadro,  i finecorsa sono normalissimi, quelli con un contatto in scambio

 

 

Link al commento
Condividi su altri siti

6 ore fa, ilguargua scrisse:

Quale sarebbe la funzione bloccante? Nel loop ti limiti a controllare quanto tempo è passato leggendo millis(), non capisco dove stia il blocco.

 

Lggi bene quello che ho scritto:

7 ore fa, Livio Orsini scrisse:

Con questa funzione ottieni un ritardo più o meno preciso, a meno di stare in loop sul test eseguendo una funzione bloccante.

 

O accetti l'errore perchè lo leggi ciclicamente oppure se vuoi aver la precisione al millisecondo devi testare in continuazione la funzione e comparare il valore di partenza con quello attuale. In pratica devi ciclare solo in quel punto, quindi il programma è bloccato ne più ne meno della funzione delay, funzione che lavora esattamente in modo simile.

L'uso di un inerrupt temporizzato da uncontatore/timer non è ne difficile, ne complicato, occupa pochissimo codice e ti libera da confronti dandoti un'otti a precisione; inoltre ti permette di ripartire le risorse in modo ottimale.

 

6 ore fa, D80 scrisse:

 metto l'arduino in un supporto da barra din e uso la shield con le morsettiere, sarà posto in un quadretto assieme ai relè, il  pcb dove saranno presenti le resistenze  e regolazione delle soglie  ,  un alimentatore per la parte elettronica, un trasformatore di isolamento per il motore della la tenda,   protezioni ecc 

 

Non voglio essere profeta di sventura, ma per esperienza personale su  Arduino questo è un caso in cui si rischano blocchi e resettamenti di programma.

Devi prevdere un filtraggio pesante dell'alimentazione di arduino, fatta con un trsformatore solo per lui; con filtro di rete prima del trasfo e con filtri L-C posti sulla continua che alimenta la scheda. Lo zero volt di arduino dovrà essere flottante rispetto a tutti gli altri in modo che arduino sia completamente isolato.

Anche la collocazione fisica della scheda nel contenitore, ha la sua imortanza perchè è molto sensibile ai distrubi irradiati.

Tutti i relè van pilotati tramite opto isolatore aventi comuni separati. Sembra un controsenso od una preoccupazione eccessiva perchè il relè di suo è galvanicamente isolato tra bobina e contatti, però i disturbi sui contatti si accoppiao meravigliosamente sulla bobina.:(

 

Se usi i contatti dei fine corsa devi separarli con opto isolatori; non solo devi prestare attenzione al percorso dei fili, per il problma di sensibilità che ho descritto in precedenza.

 

Il problema potrebbe vinire dagli ingrssi analogici. Qusti non li puoi separare galvanicamente, quindi devi studiarli bene. Io son solito spararli tramite un amplificatore differenziale a guadagno unitario.

Link al commento
Condividi su altri siti

aspettate che vi posti gli schemi poi datemi i vostri pareri

 

 

comunque non utilizzo i pin analogici, ma solamente i/o digitali , possono ugualmente creare disturbi ? 

per l'alimentatore di arduino uso un alimentatore stabilizzato da 9v 2A, da barra din e a monte di esso ho previsto un filtro rete a doppioT, un altro a p greco a valle sulla continua  

un altro alimentatore identico  ma a 12V lo uso per alimentare la scheda relè con identico filtraggio

il gnd di arduino è in comune con il gnd della scheda relè così come le schermature dei cavi ed i fili non utilizzati, 

vi sarà anche un filtro capacitivo in parallelo ad ogni bobina dei relè a 230V, 

dovrei aggiungere altro?

 

altre protezioni sono un magnetotermico da 2A 1p+n per arduino e shield relè ed uno da 6A per la sezione a 230V, più un magnetoermico generale da 10A,

 

 

 

 

i componenti a 230V sono sul lato destro, mentre la parte elettronica sta sul lato sinistro e per quanto possibile cerco di tenere lontanni i cavi di segnale coi cavi a tensione di rete

 

 

Link al commento
Condividi su altri siti

Quote

il gnd di arduino è in comune con il gnd della scheda relè così come le schermature dei cavi ed i fili non utilizzati, 

 

Hai già 2 alimentatori separati, separa anche gli zeri volt usando degli opto isolatori.

Questo sia per comandare i relè,che per interfacciare gli ingressi da campo.

 

I probelmi di disturbi son particolarmente rognosi.

Se non disponi della strumentazione adeguata come, ad esempio, ilgeneratore Shafner che genera disutrbi di ampiezza e banda normalizzati, non sai cosa succederà. TI parlo per esperienza pregressa. Ti puoi ritorvare con il dispositivo che funziona egragamente per mesi poi imporvvisamente impazzidìsce; oppure lavora bene salvo ogni tanto bloccarsi o resettarsi, oppure andare "per rane".

 

Quote

e per quanto possibile cerco di tenere lontanni i cavi di segnale coi cavi a tensione di rete

 

Il per quanto possibile non esiste, i percorsi devono essere rigidamente separati. Le normative EMC lo prescrivono non  per sadismo, ma per evitare in partenza accoppiamenti "incestuosi".

Link al commento
Condividi su altri siti

10 ore fa, Livio Orsini scrisse:

 

Hai già 2 alimentatori separati, separa anche gli zeri volt usando degli opto isolatori.

 

la shield relè che uso ha già gli optoisolatori integrati in ingresso, ma se vedo che mi darà delle rogne allora li metterò ,  per gli ingressi digitali sono già predisposti nel pcb

purtroppo non possiedo un generatore di disturbi, solo un po' di strumentazione elettronica tra cui oscilloscopio, gdf e ponte LCR, oltre a un multimetro ice680R e un HT210, stazione saldante e dissaldatore

il pcb una volta disegnato lo farò fare ad un mio amico , per cui sarà un po' un'incognita, ma spero che funzioni una volta montato così come ha funzionato al banco, 

 

Link al commento
Condividi su altri siti

13 ore fa, D80 scrisse:

la shield relè che uso ha già gli optoisolatori integrati in ingresso,

 

Però se è uno di quelli soliti che si trovano su ebay, non c'è separazione di alimentazione. Quelli che ho usato io eran così, quindi son stato costretto ad usare un opto proprio per semparare le alimentazioni.

13 ore fa, D80 scrisse:

ppo non possiedo un generatore di disturbi,

Nemmeno io, è difficile che un dilettante o un amatore, possa spendere qaulche migliaio di euro per uno strumento da specialisti di EMC. Ne disponevo ai tempi in cui lavoravo in un'azienda ben attrezzata.

 

Purtroppo con i problemi EMC se non si dispone di strumentazione adatta non si hanno certezze. L'apperecchio funziona correttamente poi, saltuariamente ha dei problemi.

L'unica via è eliminare in partenza ogni possibile fonte di accoppiamento.

Link al commento
Condividi su altri siti

ho recepito il messaggio e anche dietro diversi consigli sto apportando alcune modifiche al progetto, tra cui mettere arduino , shield relè e pcb per la regolazione , e un pcb apposta per gli optoisolatori per gli ingressi in una scatola separata mentre tutto quello che riguarda la tensione di rete andrà installata  nel centralino,   un pcb separato anche per le uscite da mettere con un supporto da barra din per i relè di uscita,, questo andrà messo  nel centralino, così da tenere fisicamente  separati tensione di rete e segnali, 

 

 

Link al commento
Condividi su altri siti

  • 2 weeks later...

sto rivedendo assieme ad un mio amico ( quello che mi deve stampare i pcb ) gli schemi delle schede perchè come le avevo pensate io non andava bene, ( ho commesso degli errori da principiante )

ma non appena saranno pronti vi posterò tutto, solo mi serve qualche giorno ancora , comunque  mi sono fatto aiutare e ho provato a montare il tutto sul campo  simulando ancora i sensori con degli interruttori  e pare funzionare, è già un piccolo passo, purtroppo non riesco andare spedito come vorrei, 

 

 

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora

×
×
  • Crea nuovo/a...