Instabilità letture opto per AC

Ho implementato una scheda per leggere la presenza di una tensione di 24V AC, per farlo ho interfacciato ad Arduino un multiplexer e a quest'ultimo degli opto H11AA1 che nascono per rilevare appunto l'alternata.
Lato software ho letto i vari ingressi nel seguente modo:

digitalWrite(PIN_MULTIPLEXER_IN_EN, LOW);
delay(nDelayMultiplexerIn);
byte attDeviceStatus = digitalRead(PIN_MULTIPLEXER_IN_DATA);
delay(nSineWaveSemiperiodDurationDelay);
byte attDeviceStatus2 = digitalRead(PIN_MULTIPLEXER_IN_DATA);
byte nMaxReads = 5;
while(attDeviceStatus2!=attDeviceStatus || nMaxReads<1)
{
    attDeviceStatus=attDeviceStatus2;
    delay(nSineWaveSemiperiodDurationDelay);
    attDeviceStatus2 = digitalRead(PIN_MULTIPLEXER_IN_DATA);
    nMaxReads--;
}
if(nMaxReads==0)
{
    #ifdef DEBUG_MODE
      Serial.print(F(" NOT INSPECTED!!! "));
    #endif
    attDeviceStatus = DEVICE_STATUS_NOT_INSPECTED;
}
digitalWrite(PIN_MULTIPLEXER_IN_EN, HIGH);

Sul banco di test tutto funzionante senza problemi, messo in campo con tutti gli ingressi collegati ho una forte instabilità nelle letture, probabile interferenze tra i vari cavi?
Per ovviare avrei pensato a inserire un condensatore sui vari contatti in modo da avere letture "stabili" in considerazione che la variazine degli ingressi è infinitamente lenta elettronicamente parlando, ovvero gli stati cambiano da assenza/presenza nell'ordine di minuti/ore.
Può essere una valida soluzione oppure c'è di meglio? Lato software non mi viene in mente nulla oltre a quanto implementato ma magari la soluzione potrebbe essere implementata anche lato software con grande gioia da parte mia :slight_smile:

La frequenza è quella di rete?
Perchè non fai letture cadenzate e ti calcoli la media mobile?
Ti tari per fare ad es. 20 letture (o vedi tu quante a seconda della precisione che desideri) per ogni ciclo (cioè ogni cinquantesimo di secondo) cadenzando con millis e usando un array circolare.
Ad ogni lettura o ogni tot ti calcoli la media e se scende sotto una certa soglia assumi che l'accoppiatore si sia spento.
Ragionando a soglie anche se calcoli male le letture, al massimo la media oscillerà un po' ma non scenderà mai sotto certi valori che puoi monitorare empiricamente.

Il ritardo di rilevazione sarà inferiore a 1/50s, a seconda della soglia che sceglierai.
Se la tua soglia di spegnimento è 0 la raggiungi dopo un intero ciclo, cioè 1/50s, se la soglia è 12V la raggiungi molto prima.

Diciamo che potresti anche ragionare su mezzo ciclo, visto che l'accoppiatore ti raddrizza la semionda negativa, quindi arrivi a zero in 1/100s

E così non usi manco i delay() ;D

Maurizio

@maubarzi: Grazie del tuo tempo, si la frequenza è quella di rete prendo la tenzione da un alimentatore commerciale. Potrei ragionare su una serie di letture e far vincere lo stato rilevato più volte in effetti. La media, a meno che non mi sfugga qualcosa, non è molto utile in quanto in uscita ho valori o zero o uno.
il delay... :slight_smile: è uno dei pochi che ho concesso perchè in fase di analisi dell'ingresso non voglio proprio fare altro, le restanti 1800 (circa) linee di codice sono tutte non bloccanti, o quasi.
Ho capito che è una battuta ma mi dilungo uguale :smiley:
Altro punto con delay è quando a fronte di una segnalazione precisa tutti gli ingressi vengono verificati e se risutano spenti vengono pilotate le relative uscite per accenderli tutti, dopo questo giro rapido con delay (far scattare a raffica troppo ravvicinata 16 relé con relative accensioni di luci anche a led l'elettricista mi avrebbe picchiato) la procedura continua a monitorare gli ingressi ciclicamente con millis() e nel frattempo fa anche un fade su un led empre con millis() e, se serve, fa lampeggiare un altro led a intervalli variabili sempre con millis() il tutto girando solo sul loop principale che grazie alla MSF e chiamate a funzioni è lungo ben 30 righe :smiley:
Grazie del tuo spunto ci ragiono su e poi aggiorno il topic

Scusa, pensavo che nei tuoi J4, 6, 8, 12 ci finisse un'onda sinusoidale che tu disaccoppiavi con l'accoppiatore ottico :o

E che quindi nei tuoi ingressi avessi un'onda sinusoidale raddrizzata, per quello parlavo di media.

Poi bisognerebbe capire meglio cosa ottieni quando dici "instabile" per essere più mirati.
Si, sul delay la mia era una battuta ;D

Maurizio

Instabile intendo che senza un effettivo cambio di stato la logica rileva la variazione da spento ad acceso e viceversa un po' a casaccio, ovvero un po' su tutti gli ingressi e con frequanza variabile da alcune volte entro un minuto a una volta ogni molti minuti

Ulteriore possibilità: con un ingresso aggiuntivo (magari gestito con interrupt) ti agganci allo zerocrossing, e 15 ms 5ms dopo leggi tutti gli altri (attraverso il mux). Non serve fare medie e hai gli stati degli ingressi stabili e aggiornati cinquanta cento volte al secondo.

In alternata gli accoppiamenti capacitivi potrebbero far sbriluccicare qualche opto che in realtà non è alimentato, basta ridurre l'impedenza degli ingressi con una R tra ingresso e GND.

Claudio_FF:
In alternata gli accoppiamenti capacitivi potrebbero far sbriluccicare qualche opto che in realtà non è alimentato, basta ridurre l'impedenza degli ingressi con una R tra ingresso e GND.

Questa mi pare l'ipotesi più probabile, che è quello che volevo ottenere con il condensatore (almeno nella mia testa), dici che già con 100 ohm potrei provare a risolvere?
Grazie

Se le metti corazzate su dissipatore si :slight_smile:

Per me delle 3,3k 0,5W sono sufficienti, e anche le 2,2k verso gli opto le metterei uguali, in modo da limitare la corrente di picco nei LED a 10mA.

Alla fine ogni ingresso assorbirà 0,35W distribuiti e dissipati sulle due resistenze.

Ok @Claudio_FF provo con quelle e poi faccio sapere, per le 2,2k ormai sono montate su PCB se posso evito di dissaldarle tutte e sostituirle anche perché quelle le ho messe da 2W se non ricordo male, alla peggio sono da 1W.
Grazie mille per il tuo tempo

Sai vero che gli H11AA1 hanno due led, e quindi in uscita hai 100Hz e non 50, giusto ? ...

Comunque mi sembra strano che i cavi in ingresso agli opto ti possano causare interferenze del genere ... opterei piu per qualcosa lato transistor ... le basi dei transistor (pin 6 degli opto) sono ben isolate da tutto, pasta salda inclusa ?

Etemenanki:
Sai vero che gli H11AA1 hanno due led, e quindi in uscita hai 100Hz e non 50, giusto ? ...

Si, una vecchia discussione portò il cambio dell'opto da quello previsto in origine (non per AC) a questo, ma effettuando letture ogni 20ms anche con 100Hz dovrei (in teoria) intercettare almeno due letture consecutive con transistor in conduzione, o sbaglio?

Etemenanki:
Comunque mi sembra strano che i cavi in ingresso agli opto ti possano causare interferenze del genere ... opterei piu per qualcosa lato transistor ... le basi dei transistor (pin 6 degli opto) sono ben isolate da tutto, pasta salda inclusa ?

Il pin è saldato ad un pad non collegato a nulla e dovrebbe essere pulito (condizionale d'obbligo perché se non funziona...) ma seguendo quest'idea potrebbe essere che i disturbi derivino dal quadro che è di metallo? Per fissare la scheda ho messo dei dadi M3 standard (queli che si usano per le motherboard dei pc per intendersi) può essere che anche se a distanza di mezzo cm il pannello posteriore introduce il problma? Nel caso se lo collego a GND? Preciso che è un quadro dedicato solo alla parte bassissima tensione e oltre a quella (molto distante) ospita una ciabatta per alimentare alcuni alimentatori per gli switch ethernet.
Grazie per il tuo tempo

Difficile che sia quello, ma se sei sicuro che nessun pin ci arriva, puoi collegarlo a GND e fa un po da schermo ... pensavo alla pasta salda o flussante perche' non e' esattamente isolante e quelle sono pur sempre le basi di transistor, ma se hai gia lavato la schedina non e' neppure quello ... se mi viene in mente qualcos'altro te lo dico, per ora ho finito le idee decenti ...

EDIT: ed usare la base per ridurre la sensibilita' ai disturbi ? ... di solito si fa collegando un condensatorino da 100n fra base ed emettitore dell'opto ... e con una resistenza da 330K o valori simili in parallelo al condensatore e' ancora meglio ... a parte questo, per ora non ho altre idee ...

Non ci arriva nessun pin sicuro perché per sicurezza ho messo dell'isolante dietro la scheda, proverò comunque a rilavare la scheda e poi a mettere anche condensatore e resistenza come consigliato vediamo se in qualche modo ne vengo a capo, non avendo strumentazione devo andare a naso purtroppo. Grazie dei consigli e del tuo tempo.

Scusa fabpolli, ma, se ho ben capito dal tuo post iniziale, tu devi SOLO rilevare la presenta/assenza della tensione AC e basta ? ? ? O devi fare operazioni sul segnale sinusoidale (tipo trovare il passaggio per zero, la frequenza, gli sfasamenti tra uno e l'altro, ecc.) ? ? ?

Guglielmo

Già mi serve solo sapere se l'utenza associata è accesa o spenta, per il progetto partii da un scheda che usava un opto non AC, il prototipo è poi evoluto con l'opto per AC perché la scheda ABC da cui son partito indicava rilvare la presenza della tensione, se c'è un metodo migliore alla fine posso anche rivedere totalmente la parte HW, mi spiacerebbe un poco ma alla fine l'importante è raggiungere l'obiettivo

... beh ... com hai letto (spam) ... la soluzione più banale probabilmente sarebbe un semplice ponte a diodi per raddrizzare l'AC, un condensatorino per livellarla e, se proprio vuoi separare le cose isolandole otticamente (... sempre meglio), un semplice opto per accoppiare con gli ingressi digitali di Arduino dove leggereai direttamente LOW o HIGH in funzione della presenza o meno della AC :wink:

Magari Etem darà qualche indicazione più precisa ... :smiley:

Guglielmo

Si, gli opto e' meglio se ci sono per via anche del fatto che le utenze in AC non avranno certo un GND in comune con l'alimentazione di Arduino (essendo appunto AC), ma lato DC, dopo il ponte ... che e' la soluzione migliore in quel caso, non servendo il passaggio per lo zero ... poi ci metti un condensatorino da tipo 1uF o simile, solo per livellare (tanto l'unico carico e' il led dell'opto con la sua resistenza in serie), e sei a posto ...

Consiglio solo per prudenza di usare gli opto a 4 pin, quelli senza la base del transistor portata fuori ... oppure resistenza e condensatore fra base ed emettitore se devi per forza usare gli altri ...

Ok, detto che seguirò la strada suggerita e in attesa di maggiori dettagli metto qualche dettaglio, l'alimentatore AC è un BTicino 24v (che poi da sempre un po'di più).
Visto che ho sempre letto che occorre abbondare con gli opto per isolare gli ingressi e quindi sicuramente vorrei mantenere la separazione mi chiedo se mi conviene:

  • Ridisegnare il PCB per prevedere l'uso di un opto per cc, il ponte a diodi ed il condensatore
  • Sostituire gli opto con i corrispondenti per cc e creare delle schede d'interfaccia tra questi e il raddrizzatore
  • Mantenere gli opto attuali e creare delle schede d'interfaccia come al punto due

Edit: visto che Etem mi ha anticipato direi che la soluzione corretta è la uno.
Adesso non mi resta che studiarci un poco su, cercare i componenti e, se possibile, sottoporvi la cosa prima di fare un secondo Epic fail :slight_smile:

Stavo riguardando la strategia di lettura del primo post (credo ci sia un <1 errato).
In sostanza cerchi di trovare almeno due letture uguali per un massimo di cinque tentativi.
Però i delay di nSineWaveSemiperiodDurationDelay da quanto sono? 5ms? 10ms?
Secondo me, visto che l'inizio del procedimento è asincrono con la frequenza di rete, in qualche caso si corre il rischio di andare a "pestare" sempre sui picchi a 5V dello zerocrossing.

Se non ci si vuole agganciare fisicamente allo zerocrossing 100Hz per avere letture sicuramente sempre giuste, la strategia di lettura secondo me dovrebbe essere un po' diversa.

Leggo due volte a distanza di 4ms. Se sono due zeri AC presente, se sono due uni AC non presente.
Se invece sono diversi si fa una terza lettura distanziata di ulteriori 4ms, e ci si trova davanti a queste possibilità:

1 0 0 AC presente
1 0 1 errore
0 1 0 AC presente
0 1 1 errore

Be', con ponti e condensatori quel problema non si presenterebbe piu ... il condensatore eviterebbe i "passaggi per lo zero" del led dell'opto (che non spegnendosi mai completamente non darebbe in uscita impulsi ma stati fissi) ... ci sarebbe forse qualche millisecondo (o decina di millisecondi) di ritardo nello spegnimento, usando un condensatore troppo grande, ma da 1 a 4.7 micro non dovrebbero causare problemi particolarmente gravi ...

Ricordarsi solo di metterli da minimo 50V, se possibile anche di piu (100V sarebbe ottimo) ... perche' ponte piu condensatore, tensione di ingresso per 1.41, metti un po piu dei 24V che danno di solito, si fa presto a ritrovarsi 36V ed anche qualcosina in piu sull'uscita ... quindi calcolare le resistenze in serie ricordandosi di questo (e magari mettere anche un led in serie a quello dell'opto, cosi si ha anche un'indicazione visiva immediata del fatto che sia presente o meno tensione durante i controlli ... tanto se si deve rifare lo stampato ... :wink: )