Vai al contenuto
PLC Forum


Valore Massimo In Asincrono


busanela

Messaggi consigliati

Salve,

sto lavorando ad un'idea su una parte d'impianto dell' azienda presso cui lavoro:

con una cpu 226 devo confrontare un numero binario di 8 bit che mi definisce il numero del carrello (sono più di 100) con un numero impostato in un supervisore e trasferire il risultato del confronto ad un'altra postazione.

Ora, la velocità di traino dei carrelli non è costante: può variare da 0,5 a 3,0 m/sec. Di conseguenza, la lettura del numero di 8 bit può variare in funzione del tempo in cui la stazione di lettura ha di fronte il carrello; per es. a 3 m/sec ho 200 msec per leggere il numero di 8 bit, invece a 0,5 m/sec ho 1,2 secondi.

Ne segue che, posso avere delle letture del numero falsate dal tempo in cui il carrello è posto davanti ai sensori.

L'ostacolo in cui mi sono imbattuto è che, nel ricavare il valore massimo del numero in bit, non ho trovato un'idea per farlo in maniera ASINCRONA, cioè senza utilizzare un tempo per effettuare i calcoli:

TITLE=COMMENTI SUL PROGRAMMA
Network 1 
// Attiva temporizzatore di scansione di 1 ms per la lettura ciclica del byte d'ingresso.
LDB>   EB0, 0
TONR   T0, 1
Network 2 
// Reset del temporizzatore per la lettura del byte d'ingresso ogni 10 ms o quando il byte d'ingresso è assente.
LDW>=  T0, 10
OB=    EB0, 0
R      T0, 1
Network 3 // Titolo del segmento
// Per 10 ms  trasferisci il valore del byte d'ingresso in vb1000.
LD     T0
UB>    EB0, 0
MOVB   EB0, VB1000
Network 4 
// Se il valore di VB1100 è maggiore di VB1000, non ci sono possibilità di errore, quindi acquisisci VB1100 come byte corretto.
LDB>   VB0, VB1000
S      M3.0, 1
Network 5 
// Assieme al segmento precedente, verifica ogni 1 ms che VB1100 sia maggiore di VB1000: se vero, non elaborare più confronti ed accetta VB1100 come valore massimo acquisito dal byte d'ingresso.
LDN    T0
UN     M3.0
MOVB   VB1000, VB0

Secondo voi, esiste una maniera per svincolarsi dal sistema SINCRONO?

Ogni dritta è ben accetta. ;)

Link al commento
Condividi su altri siti


Ciao Livio,

il lettore è composto da 8 sensori induttivi messi in verticale (in postazione fissa, ancorata a terra) che leggono altrettanti pioli metallici anch'essi posti in verticale sul lato del carrello; il diam. del sensore è di 12 mm, da cui i tempi dell'esempio del mio post precedente(a 3 m/sec, attraverso 1 cm in 0.5sec, a 0,5 m/sec lo attraverso in 1.2 sec.) .

Il problema è che il "lettore" è perfettamente in verticale, mentre i pioli fissati sui carrelli, a causa delle tolleranze meccaniche del trasporto, possono arrivare non perfettamente in "bolla". Da quì l'esigenza di dover prendere solo il valore massimo del byte in transito: il picco in forma di byte è senz'altro il numero del carrello.

Sperando d'essere stato più chiaro ...

Modificato: da busanela
Link al commento
Condividi su altri siti

La soluzione più sicura è collegare gli 8 sensori, oltre che ad 8 ingressi, in OR tra loro come ingresso veloce. Ovviamente bisognerebbe sdoppiare le 8 uscite degli 8 sensori. Un'uscita direttamente agli ingressi come ora, l'altra messa in OR ed inviata ad un ingresso veloce che causa un interrupt.

In alternativa, per semplificare, potresti mettere un nono sensore, più un nono un piolo su tutti i carello; questo piolo è in posizione leggermente anticipata rispetto agli altri, quindi verrà lette sicuramente prima (puoi anche anticipare la posizione del sensore). Questo sensore lo mandi ad un ingresso veloce ad interrupt, nel 200 sono quelli legati anche ai contatori.

Quando riconosci l'interrupt cominci a leggere direttamente (non leggendo il byte meorizzato nel registro immagine) il byte d'ingresso; fai una lettura ogno 20 ms usando l'interrupt a tempo del timer di sistema. Memorizzi la lettura. Alla successiva fai il confronto: se il valore è maggiore memorizzi il nuovo valore, altrimenti lo scarti. Continui sini a che leggi valore zero, che corrisponderà all'uscita di tutti i pioli dall'area dei sensori. Il valore che hai in memoria è il vero valore corrispondente al codice del carello.

Più semplice a farsi che a descriversi :)

Modificato: da Livio Orsini
Link al commento
Condividi su altri siti

FattoreDiPotenza

Ciao Busanela.

Forse non ho capito bene il sistema di codifica , e se quello che scrivo adesso sono cavolate correggimi pure.

Allora , ci sono su un carrello dei pioli in fila , diposti parallelamente ed equidistanti lungo di una retta diciamo 4 pioli, ogni piolo ha un peso binario.

Si muovono approssimandosi a quattro sensori disposti in linea retta equidistanti tra loro esattamente come i pioli.

Ora il problema è se sti benedetti pioli arrivino in modo disordinato ciascuno sotto il proprio rispettivo sensore.

Vuoi un metodo per interpretare il codice anche se l'immagine del BYTE di lettura subisce variazioni veloci per la disordinatezza dei pioli?

Modificato: da FattoreDiPotenza
Link al commento
Condividi su altri siti

Rispondo a FattoreDiPotenza:

ciò che hai capito è corretto. A causa della non perfetta verticalità della linea dei pioli rispetto alla verticale dei sensori (ed ogni carrello può avere la linea dei pioli inclinata in avanti o indietro rispetto la linea di marcia)e a causa del breve tempo in cui i sensori "vedono" il peso binario dei pioli, ho bisogno di rilevare, nel breve istante in cui questi attraversano i sensori, il valore massimo del peso binario letto.

Inizialmente ho agito quasi come descritto da Livio (vedi codice del post#1):

fai una lettura ogno 20 ms usando l'interrupt a tempo del timer di sistema. Memorizzi la lettura. Alla successiva fai il confronto: se il valore è maggiore memorizzi il nuovo valore, altrimenti lo scarti. Continui sini a che leggi valore zero, che corrisponderà all'uscita di tutti i pioli dall'area dei sensori. Il valore che hai in memoria è il vero valore corrispondente al codice del carello.

eccezione fatta per l'interrupt (proprio non avevo pensato al nono sensore!).

In effetti funziona, il dispositivo legge correttamente il numero del carrello, ma per maggiore sicurezza dato che le velocità della linea può variare improvvisamente tra il massimo ed il minimo, non mi fido di una scansione a tempo, anche se di pochi millisecondi, e volevo calcolare questo fantomatico valore massimo solo all'interno del momento in cui il byte cambia di valore (da 0 passa a X) e terminare il calcolo quando questo torna a 0.

Insomma, in soldoni, esiste una frazione di tempo in cui il byte ha un valore maggiore rispetto ad altri istanti ed io devo discriminare questo valore senza relazioni temporali. Facendo un esempio, se il carrello ha il n. 116, il byte sarà 011100100; passando davanti ai sensori potrei leggere anche se per brevi istanti 01000000 (64), 01100000(96), 011100000(112), 011100100(116). il valore inequivocabile del numero "vero" del carrello è solo l'ultimo, cioè quello con peso maggiore. Tutto ciò lo vorrei calcolare da quando il valore è passato da 0 a 64, (il primo valore letto) a quando passa da 116 a 0. :blink:

Link al commento
Condividi su altri siti

Ma questo valore ti serve nell'istante in cui il carrello è davanti ai sensori o ti basta saperlo una volta che i sensori sono tornati a zero?

Nel secondo caso è sufficiente associare ogni sensore ad un singolo merker all'interno dello stesso byte

U sensore_0

S merker_0

U sensore_1

S merker_1

....

U sensore_7

S merker_7

e quando i sensori tornano tutti a zero nel merker byte ti rimane il numero massimo letto (è talmente semplice che mi sembra strano non l'abbia suggerito nessuno ... boh)

un'altra cosa che non quadra è questa

a 3 m/sec, attraverso 1 cm in 0.5sec, a 0,5 m/sec lo attraverso in 1.2 sec.

a 3 m/sec 1 cm si attraversa in 3,3 ms !!!

ciao

Link al commento
Condividi su altri siti

FattoreDiPotenza

Secondo quanto viene enunciato nel teorema dei segnali di Nyquist-Shannon , la frequenza di campionamento di un segnale , per non indurre in errori di campionamento deve essere sempre almeno il doppio dela massima frequenza del segnale campionato.

Ne deduci che il tempo totale del ciclo di scansione della CPU deve almeno essere la metà della durata dell'impulso da campionare.

Se parliamo di 3,3 ms , la vedo dura , de vi avere un PLC scan time massimo 1,5 ms!

Ma siamo sicuri delle velocità in gioco? , 3 mt. al secondo mi sembra più la velocità di una ruota fonica che di un carrello.

Credo che di fronte ad un evento del genere ti si renda necessario solo ed esclusivamante l'impiego di un interrupt ciclico a tempo vincolatoa a 1 o 1,5 ms di esecuzione ciclica.

Per quello che riguarda la "disordinatezza" dei segnali, dovresti operare in questo modo , nel tuo SBR di interrupt:

Crea un flag di inizio decodifica , che si setta sulla provenienza di un segnale qualsiasi della decodifica , chiamiamolo " carrello presente".

Questo flag si resettarà a tempo con un temporizzatore che avrà una durata pari al tempo minore che si ha tra il transito di un carrello e l'altro alla massima velocità 3mt/sec.

Leggi i bit di codifica e sommi il valore letto sul fronte di salita del segnale.

Ti riporto il codice che scriverei nel INT0 (richiamato ogni 1,5 millisecondi).

LDNI   I0.0                        // 15microsec. per IN locali , 21 microsec. per mod. ampliamento.
ANI    I0.1
ANI    I0.2
ANI    I0.3
NOT
S      M10.0, 1                    //flag di inizio decodifica al raggiungimento di un qualsiasi ingresso


LDI    I0.0                        //input peso 1
EU                                 //fronte di salita
+I     1, VW100                    //somma +1 al raggiungimento di i0.0 nella word di codifica

LDI    I0.1                        //input peso 2
EU                                 //fronte di salita
+I     2, VW100                    //somma +2 al raggiungimento di i0.1 nella word di codifica

LDI    I0.2                        //input peso 4
EU                                 //fronte di salita
+I     4, VW100                    //somma +4 al raggiungimento di i0.0 nella word di codifica

LDI    I0.3                        //input peso 8
EU                                 //fronte di salita
+I     8, VW100                    //somma +8 al raggiungimento di i0.0 nella word di codifica

LD     M10.0
TON    T32, 50                     //durata del ciclo di codifica

LD     T32                         //a fine codifica 
MOVW   VW100, VW102                //sposta il valore letto in una word di memorizzazione
MOVW   0, VW100                    //azzera la word di lettura per la codifica seguente
R      M10.0, 1                    //resetta il flag del ciclo

La durata massima di scansione di questo codice dovrebbe aggirarsi tra i 348 e 410 microsecondi , nel peggiore dei casi , vale a dire se gli ingressi usati sono di moduli addizionali e non della CPU.

Ho usato gli ingressi di tipo "immediato" che rinfrescano il loro stato durante l'interrogazione , indipendentemente dall'immagine processi.

Alla fine del ciclo di lettura avrai il codice letto per ultimo nella word VW102.

Link al commento
Condividi su altri siti

Ma siamo sicuri delle velocità in gioco?

Ragazzi, chiedo scusa a tutti!!

Ho scritto la velocità indicando metri/secondo, ma volevo dire metri/minuto! :rolleyes:

Quindi, ricapitolando, 3 m/min=300 cm/min=300/60 cm/sec=5 cm/sec da cui 1/5sec=1 cm, percorro 1 cm in 0,2 sec=200msec.

L'idea di cisio l'avevo già valutata in fase iniziale del progetto (e sono sicuro che ad altri sarà venuta in mente), ma l'ho scartata per avere maggiore comodità a lavorare con un unico byte d'ingresso, anzichè con tanti bit: i confronti con le costanti da contemplare (numeri da associare ai carrelli, valori da trasferire al resto dell'impianto in relazione al numero di carrello, ...) sono molto più semplici. Avevo valutato l'ipotesi di settare i bit shiftando il byte, ma si allunga il discorso a svantaggio della velocità di lettura.

Alla luce della correzione (mi cospargo il capo di cenere!), non riterrei indispensabile l'ottimo esempio di FattoreDiPotenza di utilizzare un'interrupt.

Link al commento
Condividi su altri siti

FattoreDiPotenza

Non ti scusare non importa.

Nel caso rimanga il problema del disallineamento dei pioli , puoi ugualmente usare il sistema della somma dei singoli bit.

Scaduto il tempo il risultato della somma restituisce il codice letto anche se i piolo sono arrivati alla "spicciolata".

Modificato: da FattoreDiPotenza
Link al commento
Condividi su altri siti

Già, hai ragione: visto come parte a se stante, la somma dei pesi come idea non è proprio male! :)

... Però ci sono sempre quei millisecondi del tempo di inizio/fine codifica che non riesco a farmi piacere!

Forse si può provare senza, visto che si usano i fronti.

Modificato: da busanela
Link al commento
Condividi su altri siti

FattoreDiPotenza

Rimane la seguente questione , come e chi dice al programma che non vi sono più pioli da leggere? Qundi come definisce il programma che il risultato della somma sia il numero esatto di cui tenere conto?

Il tempo di limitazione del ciclo io lo lascerei solo per quello , se si verificano errori aumenti il tempo ciclo per premettere la cattura anche dei pioli più ritardatari.

I fronti invece hanno solo lo scopo di limitare la somma al raggiungimento del piolo e non che sia ciclica per tutta la durata della permanenza TRUE dell'ingresso.

Altrimenti devi avere almeno un piolo dedicato (secondo il consiglio di Livio) che ti dia una sorta di STROBE lettura.

O tiri a indovinare? :lol:

Modificato: da FattoreDiPotenza
Link al commento
Condividi su altri siti

chi dice al programma che non vi sono più pioli da leggere?
tiri a indovinare?

No, ovviamente.

Da come il sistema è costruito meccanicamente, ci sarà un'istante in cui il byte d'ingresso che tra un carrello e l'altro vale 0, passerà ad un valore >0 perchè un carrello è davanti al lettore; poi ci sarà un momento in cui leggerà dei "numeri" ed infine passerà da un valore letto a 0, quando il carrello uscirà dal lettore.

E' all'interno di questa condizione (0<byte>0) che io vorrei discriminare il valore massimo che sarà senz'altro quello corretto: dove non ho pioli, il sensore non può andare a "1", quindi non può scrivere lo stato alto all'interno del byte.

La tua idea di lavorare con i pesi è buona, ma io la condizionerei in questo modo:

LDB>   EB0, 0                      // Quando il byte d'ingresso è maggiore di 0, il lettore ha un carrello davanti

S      M10.0, 1                    //flag di inizio decodifica al raggiungimento di un qualsiasi ingresso


LDI    E0.0                        //input peso 1
EU                                 //fronte di salita
+I     1, VW100                    //somma +1 al raggiungimento di i0.0 nella word di codifica

LDI    E0.1                        //input peso 2
EU                                 //fronte di salita
+I     2, VW100                    //somma +2 al raggiungimento di i0.1 nella word di codifica

LDI    E0.2                        //input peso 4
EU                                 //fronte di salita
+I     4, VW100                    //somma +4 al raggiungimento di i0.0 nella word di codifica

LDI    E0.3                        //input peso 8
EU                                 //fronte di salita
+I     8, VW100                    //somma +8 al raggiungimento di i0.0 nella word di codifica


MOVW   VW100, VW102                //sposta il valore letto in una word di memorizzazione
MOVW   0, VW100                    //azzera la word di lettura per la codifica seguente

LDB<   EB0, 0                      // quando il byte ritorna a 0, il lettore non ha più carrelli davanti
R      M10.0, 1                    //resetta il flag del ciclo

Proverò a lavorare su questo! ;)

Link al commento
Condividi su altri siti

FattoreDiPotenza

Solo qualche nota:

Può darsi che vi sia un disallineamento tale da creare una situazione in cui un piolo è talmente ritrdato dal suo asse che si trova a più della metà del suo diametro rispetto all'asse degli altri? In questo caso verrebbe soddifatta la condizione presente nell'ultima istruzione, facendo memorizzare un numero in assenza dell'ultimo piolo, ed addirittura l'ultimo piolo diventare un codice carrello a sè , questo inconveniente sarà maggiore tanto minore sarà a vlocità del carrello.

Seconda cosa , ma è solo squisitamente di forma.

Hai usato per il senttaggio del bit di inizio cilco l'interrogazione a byte.

Ecco non ne sono sicuro se nel S7-200 si segua la politica del 300 dove le interrogazioni a byte della periferia hanno una sorta di priorità sull'aggiornamento IPI.

Se non fosse così creeresti un lasso temporale che potrebbe essere pericoloso in caso di letture estrememante veloci ed imprecise tra l'abilitazione del flag di inizio lettura ed gli ingressi che usi poi di tipo "veloce".

Tutto qui .

Link al commento
Condividi su altri siti

Ritornando all'argometo iniziale ritengo che una lettura con periodo di 20 ms o, se ci sente pessimisti, 10 ms sia più che adeguato a rilevare tutte le eventuali variazioni che avvengono durante il passaggio della zona "piolata"; ovviamente con il segnale Hw che anticipa il codice e attiva la funzione.

Questo in funzione di tempi e delle velocità dichiarate.

Se il disallineamento della meccanica è così grave da non assicurare neanche una posisbilitè di lettura in contemporanea di tutte le camme allora si può procedere nel seguente modo, un poco più pesante.

Alla massima velocità occorrono 200ms per attraversare l'area del sensore, però la camma avrà una sua larghezza pertanto il tempo sarà anche maggiore.

In teoria si potrebbe campionare con periodo di 100 ms ed avere la certezza di "prendere" la camma. Con periodo di 50 ms la sicurezza aumenta.

Se non si vuole agiungere un sensore di start misura, è sufficiente impostare un interupt temporizzato a 50 ms con cui andare a leggere direttamente gli ingressi interessati.

La prima lettura che contenga almeno un "1" da inizio alla memorizzazione.

Ad ogni misura si memorizzano gli "1"; in pratica si memorizza la prima lettura e si esegue l' OR con le successive letture mettendo in memoria il risultato. In questo modo si forzano tutti gli "1" letti in memeoria. Dopo quattro letture consecutive senza "1" si considera terminata la misura. In memeoria si avrà il codice del carro. Ovviamente non si può usare il codice "0"

Questo metodo funziona con assoluta sicurezza ed è piuttosto semplice da implememtarsi

Io comunque avrei agito in altro modo. Avrei allungato meccanicamente le camme di quel tanto che basta per avere la sicurezza di una ricopertura, ed avrei messo una camma più lunga con anche funzione di start della misura, se bastano 127 codici, altrimenti avrei aggiunto una camma per lo strat.

Modificato: da Livio Orsini
Link al commento
Condividi su altri siti

Può darsi che vi sia un disallineamento tale da creare una situazione in cui un piolo è talmente ritrdato dal suo asse che si trova a più della metà del suo diametro rispetto all'asse degli altri?
Se il disallineamento della meccanica è così grave da non assicurare neanche una posisbilitè di lettura in contemporanea di tutte le camme

Per fortuna le tolleranze meccaniche non sono così elevate. Come ho anticipato in un mio post precedente, attualmente il sistema sta lavorando, con grande soddisfazione del mio direttore, con una scansione di 10 msec fra le letture per il rilievo del valore massimo del byte in ingresso, e mi conforta anche l'opinione positiva in tal senso di Livio:

ritengo che una lettura con periodo di 20 ms o, se ci sente pessimisti, 10 ms sia più che adeguato a rilevare tutte le eventuali variazioni che avvengono durante il passaggio della zona "piolata";

Sicuramente un sistema con camme più lunghe di un semplice piolo avrebbe agevolato non poco il mio compito, ma vaglielo a dire al MegaDirettoreGalattico che sarebbe meglio, anche se il sistema funziona, spendere altri soldi per modificare la lettura: mi pare di sentire già la risposta! <_<

Mi sembrano ottime le soluzioni di FattoreDiPotenza e di Livio, e le proverò appena potrò. ;)

Link al commento
Condividi su altri siti

Come ho anticipato in un mio post precedente, attualmente il sistema sta lavorando, con grande soddisfazione del mio direttore

e allora dove sta il problema? :) mi ricordi un mio collega, che anche quando le cose sono semplici e funzionanti deve sempre trovare il modo di renderle più complicate

L'idea di cisio l'avevo già valutata in fase iniziale del progetto (e sono sicuro che ad altri sarà venuta in mente), ma l'ho scartata per avere maggiore comodità a lavorare con un unico byte d'ingresso, anzichè con tanti bit

i bit di merker li devi mettere tutti nello stesso byte, ognuno con il suo peso giusto, e non devi fare nemmeno la fatica di assemblarli in un secondo momento.

dammi retta: semplifica tutto

ciao

Link al commento
Condividi su altri siti

Io non avrei fatto letture campionate, avrei usato il sistema di cisio, con una aggiunta:

Ogni piolo setta un bit di una MBx

(8 fronti di discesa degli ingressi dei pioli in parallelo) --NOT-----(Timer1)

Il Timer1 serve per evitare di mettere un altro finecorsa di strobe e va tarato in modo da essere sicuri di aver superato tutti i pioli col carrello più lento

Sul fronte di salita del timer faccio una Move della MBx in un altra e azzero la MBx

Aggiungo che devi avere un ciclo leggerissimo per riuscire a leggere 8 pioli di 1cm a 3m/s (ma hai provato a questa velocità?)

Modificato: da JumpMan
Link al commento
Condividi su altri siti

e allora dove sta il problema?

Nell'affidabilità del sistema. Capita, a volte, che nella visualizzazione del numero del carrello sul supervisore si vedano numeri variare (anche se per brevi istanti) prima di stabilizzarsi sul reale numero letto.

La mia intenzione non è quella di complicare le cose come vorrebbe il collega di cisio; voglio solo evitare, rendendo il sistema sicuro, che mi chiamino a casa, magari alle 3,30 del mattino perchè è stata sbagliata una lettura! <_<

Io non avrei fatto letture campionate

E' proprio quello che anche io voglio evitare! Come ho detto dall'inizio, la mia idea per migliorare e rendere sicura la lettura, è quella di svincolarla dalla relazione temporale, renderla ciè ASINCRONA (vedi titolo del topic).

Per il resto della risposta di Jumpman, in effetti è più o meno ciò che esegue il codice postato nel mio primo messaggio.

Ho provato sia alla velocità minima della linea, sia alla massima: non ci sono differenze sostanziali di comportamento sulla lettura, a volte si vedono dei valori intermedi prima del numero reale del carrello.

Mi piace un sacco l'idea di Fattore DiPotenza, la somma dei pesi e credo che proverò a fare un mix di tutte le ottime idee avute da voi, cioè somme dei pesi, settaggio dei bit ed OR delle letture: dopo questa BRAINS STORM, sono sicuro che l'affidabilità del sistema potrà farmi dormire sonni tranquilli! ;)

Modificato: da busanela
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...