Page 1 of 1

LCD

PostPosted: 09 Apr 2014, 07:58
by suibaf
Buongiorno,
leggendo il codice UID da un badge rfid e mi sembra che venga fatto correttamente, vorrei visualizzarlo su un display 4*20. Purtroppo però visualizzo delle cifre che cambiano velocemente. Mi spego facendo riferimento al codice sotto:
la sub Ceck_ric_reader_rfid , la richiamo nel loop principale, ma ho provato anche nell interrupt del timer0. Quando nella sub arrivo a fare Lcd "Numero: " ; Ar(8) ; Ar(9) ; Ar(10) ; Ar(11), sono sicuro che le variabili sono quelle che mi servono perchè ho fatto l'analisi dei byte che ricevo ed anche il cecksum con gli XOR. Non capisco però perchè visualizzo delle cifre che cambiano in continuazione. C'è da dire che se richiamo la sub nel timer0, a volte visualizzo il UID tutto a zero a volte leggo il codice corretto. Mi potete dare qualche ragguaglio?
Grazie

Code: Select all
Sub Ceck_ric_reader_rfid(ar() As Byte)
   Dim Mem_pres As Bit
   Dim Mem_ass As Bit

   If Avvenuto_timeout = 1 Then

      Avvenuto_timeout = 0
      Mem_pres = 0
      Mem_ass = 0

   End If


   If Ar(1) = &HDE And Ar(2) = &H13 And Ar(3) = &HED And Ar(4) = &H05 And Ar(5) = &H08 And Ar(6) = &H00 And Ar(7) = &H34 Then
      'Ricezione del UID della scheda
      'Controlliamo il RSP_EXT. Per esempio: 13 E2 0A 87 83 dove 83 è il cecksum di 13-E2-0A-87

      Dim Btempbyte As Byte

      Btempbyte = Ar(8) Xor Ar(9)
      Btempbyte = Ar(10) Xor Btempbyte
      Btempbyte = Ar(11) Xor Btempbyte
      Btempbyte = Btempbyte + 7

      If Btempbyte = Ar(12) Then

         If Mem_pres = 0 Then Cls

         Mem_pres = 1
         Mem_ass = 0
         Locate 1 , 3
         Lcd "Card Presente"
         Locate 2 , 1
         Lcd "Numero: " ; Ar(8) ; Ar(9) ; Ar(10) ; Ar(11)

      Else


         Goto Msg_error

      End If

   Else

      Goto Msg_error

   End If

   Goto Fine_ceck_ric_reader_rfif                           'salta alla fine senza ciclare l'errore
   Msg_error:

      If Mem_ass = 0 Then Cls

      Mem_ass = 1
      Mem_pres = 0
      Locate 1 , 4
      Lcd "Card Assente"
      Locate 2 , 2                                          'clear the LCD display
      Lcd "Avvicinare la card"
      Locate 3 , 5
      Lcd "al lettore"

   Fine_ceck_ric_reader_rfif:

End Sub

Re: LCD

PostPosted: 09 Apr 2014, 08:32
by pier
Dunque, credo che il problema derivi dalla possibile diversa lunghezza dei dati Ar(x) che vengono visualizzati.
Potresti provare a visualizzare una stringa vuota di 16 caratteri in seconda riga prima di inviare i dati al fine di cancellare quanto preesistente. Non userei il cls per non dover riscrivere anche il contenuto della prima riga e per ragioni di velocità

Re: LCD

PostPosted: 09 Apr 2014, 08:44
by deluca
@suibaf,
stai visualizzando i dati AR() in formato decimale e quindi il valore visualizzato potrebbe variare da un minimo di 0 ad un massimo di 255, quindi da 1 a 3 caratteri. Ti consiglio di utilizzare HEX per convertire il valore in esadecimale per avere sempre 2 caratteri per valore byte.
Poi non usare CLS per cancellare una riga,ma usa una stringa di n caratteri vuoti posizionandola con LOCATE.

Re: LCD

PostPosted: 09 Apr 2014, 08:54
by suibaf
Credo che Pier abbia piu' o meno detto la stessa cosa, ma io non ho capito. Il fatto che un byte sia lungo da 1 a tre caratteri perchè dovrebbe portarmi a quel comportamento? quando appoggio l'rfid sul reader i 4 byte sono costanti.
Chiedo scusa se faccio domande banali.
Grazie

Re: LCD

PostPosted: 09 Apr 2014, 09:01
by pier
Può essere che non tutti gli elementi dell'array siano aggiornati correttamente prima della loro visualizzazione?
Mi assicurerei di questo. Forse l'appoggio del badge comporta problemi in questo senso?

Re: LCD

PostPosted: 09 Apr 2014, 09:29
by pier
Altra ipotesi: qualora il range di valori che mandi all'LCD andasse oltre i caratteri visualizzabili non escluderei che il controller dello stesso li interpreti in modo poco prevedibile e possa anche andare in crisi.
Anche lo "sbinacamento" su una sola riga in questo caso potrebbe essere forse inefficace.
In questo senso l'ipotesi di usare la conversione in Hex, che comporterebbe qualche problema di lettura per l'utente che però comunque avrebbe gli stessi problemi in caso di caratteri non visualizzabili, risolverebbe il problema fermo restando la necessità di sbiancare i dati precedenti
Credo però che tutto questo sarebbe vero solo se il tuo array fosse di tipo stringa e comunque, a meno di un impazzimento del controller, difficilmente spiegherebbe una variabilità.

Re: LCD

PostPosted: 09 Apr 2014, 10:21
by suibaf
Altra ipotesi: qualora il range di valori che mandi all'LCD andasse oltre i caratteri visualizzabili non escluderei che il controller dello stesso li interpreti in modo poco prevedibile e possa anche andare in crisi.


Pier, vorrei visualizzare 4 byte. Qualora tutti e 4 i byte valessero 255 mi servirebbero 12 spazi e quindi il problema non sussiste, almeno in questo senso.

Io ho la sensazione che sia un problema di timing. Richiamando la routine dall'interrupt del timer0, la situazione migliora sensibilmente, ma non è stabile.

Re: LCD

PostPosted: 09 Apr 2014, 13:11
by pier
Beh, seguire il tuo codice scarsamente commentato mi risulta un po' arduo e dò quindi per scontati tutti i controlli che fai seppure rilevo che forse potresti usare solo una variabile per Mem_pres e Mem_ass ...
Verosimilmente il timeout ti è dato dal timer0 che prima d'ora non avevo mai visto citare. Il fatto che nel caso in cui la routine di visualizzazione funzioni meglio quando posta nell'ISR di Timer0 così mi dice un po' poco. Significa che aggiorni la visualizzazione ogni x tempo?
Questo effettivamente potrebbe far pensare ad un problema di timer dell'LCD (qualora il suo aggiornamento avvenisse in un loop veloce).
Potresti tentare di visualizzare solo se hai ricevuto gli n caratteri attesi usando il contatore di caratteri come facevi per spedirli al PC fatto salvo un possibile problema di sync sul primo carattere della serie ma per questo forse ti aiuta il timer...

Re: LCD

PostPosted: 09 Apr 2014, 14:22
by deluca
@suibaf,
controlli lo stato busy del LCD? cioè stai usando anche RW, o RW è connesso a massa.
Ogni quanto effettui l'aggiornamento dell LCD?

Re: LCD

PostPosted: 09 Apr 2014, 15:02
by suibaf
@Pier, (non ho capito perchè si mette la @ prima del nome)
si il timeout viene eseguito dal timer0. Incremento una variabile ad ogni sua chiamata. Tale variabile viene resettata nell 'ISR della seriale. Se non ricevo nulla la variabile arriva ad un valore per cui scatta l'allarme di timeout con il reader. La visualizzazione del codice UID la effettuo quando: arrivano dei byte sulla seriale, controllo che ce ne siano un certo numero, 7 nel mio caso, e chiamo la routine che ho postato prima e da li aggiorno l'lcd.

@deluca, RW è connesso a massa.

Re: LCD

PostPosted: 09 Apr 2014, 15:28
by pier
Dando un codice di input costante, puoi vedere se i caratteri sono esatti ma solo disposti in modo errato?
Per la frequenza di aggiornamento dovresti prevedere, a naso, dovresti prevedere qualche msec a carattere oppure usare l'RW per il controllo dello stato come dice Deluca.
Se invii invece dei caratteri ricevuti dei caratteri da te fissati (sovrasrivendo l'array con una serie a te nota) come va?

Re: LCD

PostPosted: 09 Apr 2014, 18:44
by suibaf
Risolto l'arcano. Vi posto il codice della routine già postata stamattina e potrete vedere la differenza. Era lo XOR tra i byte che mi stava fregando. Non ho verificato ancora il perchè! Quindi i Byte in arrivo li ho appoggiati su un secondo Array temporaneo e li ho lasciati intonsi! Comunque allego il nuovo codice e se lo volete lo commentiamo insieme per capire meglio. Magari c'è un sistema migliore per fare la stessa cosa. Grazie

Code: Select all
Sub Ceck_ric_reader_rfid(ar() As Byte)
   Dim Mem_pres As Bit
   Dim Mem_ass As Bit
   Dim Array_temp(30) As Byte

   If Avvenuto_timeout = 1 Then

      Avvenuto_timeout = 0
      Mem_pres = 0
      Mem_ass = 0

   End If

   If Ar(1) = &HDE And Ar(2) = &H13 And Ar(3) = &HED And Ar(4) = &H05 And Ar(5) = &H08 And Ar(6) = &H00 And Ar(7) = &H34 Then
      'Ricezione del UID della scheda
      'Controlliamo il RSP_EXT. Per esempio: 13 E2 0A 87 83 dove 83 è il cecksum di 13-E2-0A-87

      For I = 1 To 30

        Array_temp(i) = Ar(i)

      Next

      Dim Btempbyte As Byte

      Btempbyte = Ar(8) Xor Ar(9)
      Btempbyte = Ar(10) Xor Btempbyte
      Btempbyte = Ar(11) Xor Btempbyte
      Btempbyte = Btempbyte + 7

      If Btempbyte = Ar(12) Then

         If Mem_pres = 0 Then Cls

         Mem_pres = 1
         Mem_ass = 0
         Locate 1 , 3
         Lcd "Card Presente"
         Locate 2 , 1
         Waitms 250
         Lcd "                    "
         Locate 2 , 1
         Lcd "Numero: " ; Array_temp(8) ; Array_temp(9) ; Array_temp(10) ; Array_temp(11)

      Else

         Goto Msg_error

      End If

   Else

      Goto Msg_error

   End If

   Goto Fine_ceck_ric_reader_rfif                           'salta alla fine senza ciclare l'errore
   Msg_error:

      If Mem_ass = 0 Then Cls

      Mem_ass = 1
      Mem_pres = 0
      Locate 1 , 4
      Lcd "Card Assente"
      Locate 2 , 2                                          'clear the LCD display
      Lcd "Avvicinare la card"
      Locate 3 , 5
      Lcd "al lettore"

   Fine_ceck_ric_reader_rfif:

End Sub

Re: LCD

PostPosted: 09 Apr 2014, 19:24
by pier
Non mi addentro nel tuo calcolo del cheksum (che forse puoi calcolare più semplicemente con CRC8) ma non vedo come possa rappresentare la causa del problema e di conseguenza l'array provvisorio per questa ragione non mi pare utile.
- I 3 Dim nella sub non mi piacciono neppure un poco (tra l'altro azzererebbero comunque la variabili mem_pres e mem_ass indipendentemente da tutto)
- vedo che nella sub è comparso un ritardo di 250msec. Sicuro che non sia quel che gli fà bene (magari se fosse messo dopo "Card presente per evitare il breve scollamento nella visualizzazione)?
- insisto che forse mem_pres e mem_ass forse potrebbero diventare una sola variabile ma è un dettaglio

Resto curioso...

Re: LCD

PostPosted: 09 Apr 2014, 19:42
by suibaf
Nel frattempo i 250ms li ho tolti, non sono influenti.
La soluzione è stata appoggiare l'array in arrivo dalla seriale sull'array temporaneo prima dell'elaborazione.
Perchè i 3 dim non ti piacciono nella sub? Tra l'altro le variabili dichiarate lì non le posso utilizzare altrove. Mi sembra.
Come posso far diventare mem_ass e mem_pres una sola variabile?
Grazie

Re: LCD

PostPosted: 09 Apr 2014, 19:56
by deluca
@suibaf,
se vuoi dimensionare varibili dentro una sub ti consiglio usare LOCAL variabile as byte/integer ecc
inoltre per usare una variabile come insieme di flag ad un bit puoi usare la sintassi:

Code: Select all
const mem_err=0
const mem_pre=1
const mem_ass=2


poi:

Code: Select all
dim memoria as byte


puoi usare like type bit by bit:

Code: Select all
memoria.mem_err=1
memoria.mem_pre=0
memoria.mem_ass=1

Re: LCD

PostPosted: 09 Apr 2014, 20:31
by pier
Alcune risposte te le ha date Deluca.
E' assolutamente possibile che il tuo array dati venga modificato "in corsa" dalla seriale ed è quindi buona norma "fotografare" la situazione (quando hai i 7 dati utili) nella ISR di ricezione e settando subito dopo un flag che autorizza alla visualizzazione (resettato a visualizzazione avvenuta) prima di visualizzare il dato verosimilmente nel loop principale. Io prendo sempre questa precauzione quando sono in presenza di una situazione che può cambiare rapidamente. Questo quindi può essere stato veramente l'origine del problema.
Per quanto riguarda Mem_pres e Mem_ass non ho detto che DI CERTO POSSONO diventare 1 sola variabile ma ti invitavo a farci una pensatina. Ora mi sembra un po' macchinoso. Potresti asservire il tutto alla presenza o all'assenza di Mem_pres? ma non è poi così importante. Sulle variabili bit ricorda inoltre che puoi usare anche SET e RESET.

Forza che il traguardo è vicino!

Re: LCD

PostPosted: 09 Apr 2014, 20:47
by suibaf
Pier, se te la devo dire tutta io ho provato a fotografare l'array di ricezione ed è andata bene, ma in realtà non mi aspettavo che funzionasse. Ti spiego perchè. Quando il micro fà la richiesta dei dati, ho fatto in modo che aspetti la risposta, non fa altre richieste quindi non vedo come possano cambiare in corsa i contenuti dei byte di ricezione.
Ma evidentemente così è.
Grazie

Re: LCD

PostPosted: 09 Apr 2014, 20:58
by pier
Ma io non ho notato alcuna "richiesta dei dati" dal micro ma forse è una mia svista. Mi pareva ci fosse una seriale sempre aperta in ricezione e questo può aggiornare quando gli pare l'array ed era uno dei primi dubbi che mi erano sorti....

Re: LCD

PostPosted: 09 Apr 2014, 21:15
by suibaf
Hai ragione, nel Timer0 c'è:

Code: Select all
   Incr 200ms
   If 200ms >= 12 Then
      '200:16,384 = 12
      If Messaggio_inviato = 0 Then
         Messaggio_inviato = 1
         Printbin #2 , Ric_idcard(1) ; 7

      End If

      200ms = 0

   End If

Re: LCD

PostPosted: 09 Apr 2014, 22:09
by pier
Beh, da qui si vede solo che ogni tot tempo si invia il dato Ric_idcard(1) ed un 7(?) quindi non si capisce granchè senza commenti sull'aggiornamento dell'array della seriale in ricezione e questo mi resta poco chiaro ma se dici che funziona, ok. Solo controlla bene.