Vai al contenuto
PLC Forum


Ricerca Di Un Valore Dentro Un Vettore


robfa_1

Messaggi consigliati

Buongiorno a tutti,

Devo ricercare un valore(costante) all'interno di un vettore di X elementi. Per il momento , semplificando il problema, facciamo il caso che devo verificare che il valore intero "20" sia presente o no dentro il vettore v[20] , il quale è dichiarato dentro una DB, che chiameremo DB5. Ora, ho visto qualcosa sull'indirizzamento indiretto(LAR , ecc) e i puntatori, ma non riesco ad applicare queste informazioni al mio caso, avrei bisogno di qualche delucidazione in più se possibile.

N.B Avrei fatto una funzione in SCL per risolvere questo tipo di problema, ma il mio "superiore" mi ha detto, "ah non iniziamo ad usare l'SCL sennò viene un casino, no per carità". Credo che non sappia dove mettersi le mani con questo linguaggio, mah, comunque lasciamo stare. Meglio che impari ad usare l'indirizzamento indiretto.

Grazie a tutti

Link al commento
Condividi su altri siti


Se il tuo capo è così audace mi viene voglia di suggerirti di cambiare azienda ......

L 1

T MD 100

AUF DB5

L DBB[MD100]

L 20

==I

S M 0.0 // almeno 1 byte è uguale

beb

CONT: L MD100

L 1

+I

T MD100

L 20

>I

BEB

SPA CONT

buttata giù così senza possibitlità di provare

Link al commento
Condividi su altri siti

Quindi vediamo se ho capito bene: Inizializzi MD100 a 1, apri la dbX(5 come dicevo nel primo post) e confronti (tipo intero) con il valore 20. se il confronto ha "successo" setti la memoria m0.0 ed interrompe il ciclo con beb(vista ora sulla guida). Altrimenti avanzi al valore successivo del vettore. Quel poco che ho capito è questo. ora vado allo step successivo per il problema "reale" che ho. il vettore di interi si ripete ogni 174 byte a cominciare dal byte 174 della db5 per venti volte, perchè ho 20 venti modelli in quella db. Come devo ragionare in questo caso?

Link al commento
Condividi su altri siti

Occhio che per passare al byte successivo si deve incrementare l'idirizzo (MD100) di 8, e non di 1.

Anzi, inizializzare MD100 con valore 1 è un errore, perché l'indirizzo deve esser un multiplo di 8.

Io utilizzerei l'istruzione LOOP, con un salto per uscire se si è trovata una corrispondenza.

Link al commento
Condividi su altri siti

Scusa Batta, lo so che sei un virtuoso del codice, ma io mi ricordo che questo è un puntatore semplice e non un registro AR1.

Sei sicuro della moltiplicazione per 8 ?

(io non posso provare .....)

Ciao.

Link al commento
Condividi su altri siti

Sì, sicurissimo.

Il funzionamento del puntatore è identico.

E va bene così, perché puoi usare lo stesso sistema per puntare al bit.

Per esempio, potresti scrivere:

U M [MD100]

oppure:

U DBX [MD100]

Codice esempio:

FUNCTION FC 7 : VOID
TITLE =Cerca valore all'interno di un array
VERSION : 0.1


VAR_INPUT
  NrDB : BLOCK_DB ;	
  NrPrimaVar : INT ;	
  NrVar : INT ;	
  Valore : INT ;	
END_VAR
VAR_OUTPUT
  Trovato : BOOL ;	
END_VAR
VAR_TEMP
  adr : DINT ;	
  loopId : INT ;	
END_VAR
BEGIN
NETWORK
TITLE =

//Inizializza "valore trovato" = FALSE
      SET   ; 
      R     #Trovato; 

//Calcola indirizzo prima variabile (1 = prima variabile del DB)
      L     #NrPrimaVar; 
      +     -1; 
      SLD   4; 
      T     #adr; 

//Apri DB
      AUF   #NrDB; 

//Inizio loop
      L     #NrVar; 
NEXT: T     #loopId; 

//Se il valore è stato trovato, impostare flag "valore trovato"
//e uscire dasl loop
      L     DBW [#adr]; 
      L     #Valore; 
      ==I   ; 
      S     #Trovato; 
      SPB   EXIT; 

//altrimenti incrementare indirizzo di una word (16 bit)
      L     #adr; 
      +     L#16; 
      T     #adr; 

      L     #loopId; 
      LOOP  NEXT; 

EXIT: NOP   0; 

END_FUNCTION

Link al commento
Condividi su altri siti

Un grazie entrambi per la disponibilità e la schiettezza con cui spiegate gli aspetti principali di ogni problema che viene posto. Purtroppo alla fine il mio "superiore" ha chiamato il cliente ed ha aggirato il problema, comunque sia questa funzione (quella di batta) la guardo bene e la studio a fondo. [at]Pigroplc la tua risposta riguardo al mio superiore è giusta e il tuo pensiero condivisibilissimo. Io infatti cerco di imparare i metodi giusti dalle persone giuste, non aggirando il problema o chiamando il cliente per cambiare le carte in tavola e farmi "portare" il problema. All'università non sono stato abituato a ragionare così. Comunque non vado oltre sennò diventa una discussione OT.

Grazie ancora ad entrambi

Modificato: da robfa_1
Link al commento
Condividi su altri siti

  • 2 weeks later...

Ciao Batta, mi sono permesso di modificare il tuo codice inserendo l'indirizzamento mediante puntatore AR1, così tanto per far vedere che la differenza è minima (personalmente mi trovo meglio con AR1).

Alla fine ho aggiunto un parametro che indica dove ha trovato il valore.

ciao a tutti

FUNCTION FC 7 : VOID
TITLE =Cerca valore all'interno di un array
VERSION : 0.1


VAR_INPUT
  NrDB : BLOCK_DB ;	
  NrPrimaVar : INT ;	
  NrVar : INT ;	
  Valore : INT ;	
END_VAR
VAR_OUTPUT
  Trovato : BOOL ;	
  Where : INT ;	
END_VAR
VAR_TEMP
  adr : DINT ;	
  loopId : INT ;	
END_VAR
BEGIN
NETWORK
TITLE =
//Inizializza "valore trovato" = FALSE
      SET   ; 
      R     #Trovato; 

//Calcola indirizzo prima variabile (1 = prima variabile del DB)
      L     #NrPrimaVar; 
      +     -1; 
      SLD   4; 
      LAR1  ; 

//Apri DB
      AUF   #NrDB; 

//Inizio loop
      L     #NrVar; 
NEXT: T     #loopId; 

//Se il valore è stato trovato, impostare flag "valore trovato"
//e uscire dasl loop
      L     DBW [AR1,P#0.0]; 
      L     #Valore; 
      ==I   ; 
      S     #Trovato; 
      SPB   EXIT; 

//altrimenti incrementare indirizzo di 2 bytes
      +AR1  P#2.0; 

      L     #loopId; 
      LOOP  NEXT; 
      L     0; 
      SPA   END; 

EXIT: L     #NrVar; 
      L     #loopId; 
      -I    ; 
      +     1; 
END:  T     #Where; 


END_FUNCTION


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