Lettura penna ottica

giovedì 20 novembre 2008 - 16.39

pigi78 Profilo | Newbie

Salve a tutti.

Ho un problema che non riesco a risolvere.
In un programma abbastanza semplice, ho una textbox in cui chiedo il codice (id) di una tabella e quando premo invio carico tutti i dati necessari.
Grosso modo l'intento è quello di avere un programma "alla cassa" in cui l'utente legge il codice a barre e vede i dati del prodotto (fornitore, locazione a magazzino,...)

La penna ottica in questione è un po' particolare: ha una interfaccia "seriale" (rs-232) che viene rimappata come emulazione tastiera mediante un software chiamato ComToKey.

Il problema è che se leggo molto velocemente i codici, a volte si perdono dei caratteri.
Alla fine, facendo un po' di prove, ho scoperto che se tolgo l'accesso al database, i caratteri non li perdo più. Ovviamente l'accesso al DB è una operazione onerosa e quindi ci può stare che crei problemi (anche se nella realtà ci mette qualcosa come 60 millisecondi a fare tutto, compreso il refresh video).

Per ora sto gestendo il tutto nel seguente modo:

1) Intercetto l'evento "KeyDown" della form (non del controllo poichè se ho il focus in altri controlli e leggo con la penna, devo spostarmi in automatico nella casella di lettura)

2) Se premo enter, accedo al DB, eseguo le letture, aggiorno la videata e torno a chiedere nuovi valori (azzero la textBox e le reimposto il focus)

3) Se premo altri tasti, non faccio nulla


Qualcuno ha qualche idea su cosa posso provare a fare?

Ah, dimenticavo: sto usando WPF e C# Express

llamanna Profilo | Junior Member

Prova a lavorare con il db in maniera disconnessa, ovvero utilizzando i dataset. In questo modo i dati sono già in memoria e non c'è più la latenza dovuta all'accesso al db. Questo innesca, come tutti gli scenari nei quali viene utilizzata una cache dei dati, il problema del refresh. Pertanto se inserisci o elimini dati devi ricordarti di effettuare un refresh della cache.
Laura.
http://lauralamanna.blogspot.com/

Teech Profilo | Expert

Secondo il mio punto di vista non devi usare l'evento keydown su tutti i controlli ma l'utente deve essere posizionato nella TextBox per scrivere il codice ed eventualmente effettuare l'accesso al DB nell'evento Validating (validando così la stringa inserita, metti che inseriscano una stringa non contenuta nel DB)... Se sei in emulazione di tastiera devi comportarti come se stessi usando una tastiera e quindi essere nella textbox.

Altra cosa che non mi convince: dici di leggere i dati nella keydown dei controlli e solo alla pressione del tasto Invio fai l'accesso al DB... Essendo l'accesso al DB successivo alla lettura del codice a barre come può interagire con la lettura stessa facendoti perdere i dati (caratteri in lettura nel tuo caso)?

Ciao!!!
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

pigi78 Profilo | Newbie

Grazie per i consigli, provo a chiarire i vostri dubbi (così magari riuscite ad aiutarmi meglio).

-) L'applicazione gira su dei muletti collegati in wireless. Per cui, quando arriva un prodotto, l'operatore deve leggerne il codice e vedere dove portarlo a magazzino. Oppure, qualora debba andarlo a prelevare, dovrà vedere dove si trova.

Siccome la locazione in cui posizionare il prodotto varia al variare della posizione degli altri prodotti, ho bisogno di avere i dati "in tempo reale". Per cui, anche avendo un DataSet sul muletto, dovrei comunque aggiornare tutto il DataSet ogni volta che leggo un codice (perchè devo caricare i dati "attuali" del db, compresi eventuali spostamenti fatti dagli altri).

Questo è il motivo per cui non uso il DataSet (modalità disconnessa).


-) Per le letture, invece, il problema non è sulla lettura "appena fatta", bensì su quella successiva. Supponiamo che arrivi un camion con due prodotti e li debba mettere entrambi a magazzino. Col muletto inforco entrambi i bancali e leggo i due codici a barre sopra riportati. Essendo entrambi sul muletto, riesco a leggerli abbastanza velocemente.

Pertanto leggo il codice 111111 (6 uno di fila) e il codice 222222 (6 due di fila).

Quando leggo il primo codice, tutto funziona bene. Però per reperire le informazioni relative al prodotto 111111 passano circa 80 millisecondi. Questo fa in modo che la procedura perda i primi 2 caratteri del secondo codice a barre. Pertanto, anzichè avere 6 volte il valore 2, me lo ritrovo solo 4 volte (per cui la lettura non va a buon fine).


-) Intercetto l'evento "keyDown" del form e non il "validate" del controllo, poichè ho altri controlli a video (per esempio un tab control). Pertanto se l'operatore si sposta sul tab control mediante touch-screen, il focus è sul tab control... Per cui se leggo un codice non viene interpretato. Intercettando il KeyDown del Form, invece, quando si preme un pulsante (o si legge un codice a barre), passo in automatico il focus al campo corretto.



Facendo un po' di test (perchè è una cosa per me un po' urgente), ho visto che il problema si ripete anche a distanza di 50 millisecondi.
Una cosa importantissima che pensavo "non importante" ma che dai test sembra essere fondamentale: la penna ottica NON E' COLLEGATA COME TASTIERA, bensì è in seriale (rs232) e c'è un programmino che converte la lettura "seriale" in lettura "tastiera".

Per me, a questo punto, il problema è che il software che converte la seriale in tastiera "manda" i dati anche se la mia applicazione non sta ascoltando (cosa che non accade con la tastiera). Pertanto, se il mio form è attivo, allora i caratteri arrivano, viceversa vengono persi.

Qualcuno mi sa dire come posso fare per provare ad aggirare il problema usando dei thread?
Perchè ho provato a farlo, però poi non riesco ad aggiornare l'interfaccia grafica poichè non posso passargli i dati di un altro thread (mi esce con exception).Qualcuno mi sa fare un esempio?

Che ne so, magari un frame con due controlli: un textbox + una listbox. Quando leggo dal textbox, questo genera un thread passandogli la lettura fatta. Il thread la converte in maiuscolo ed aggiunge la lettura alla list-box.
In questo modo posso vedere come funziona... Adatterò poi io le cose alla mia applicazione (non passerò delle stringhe ma altri tipi di oggetto).


Grazie mille!

Teech Profilo | Expert

Ora è chiaro... Avevo postato un problema "simile" (molto alla lontana lo ammetto) alcune settimane fa... La soluzione che mi hanno proposto è l'utilizzo del "Hook di tastiera". La soluzione dell'Hook non è proprio la più semplice (almeno per me) ma credo che la soluzione sia questa.
Prova a vedere se questo link può esserti di aiuto:
http://msdn.microsoft.com/it-it/magazine/cc188966(en-us).aspx

In bocca al lupo
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

pigi78 Profilo | Newbie

Grazie, però è un po' complicata come cosa...


Ora ho trovato un modo un po' più semplice: Le letture vengono memorizzate in file di testo. Poi ho un FileSystemWhatcher che monitorizza la directory e genera eventi ogni volta che viene creato un file. Quando il file viene creato, leggo il contenuto e il gioco è fatto.

Ho solo un problema: nelle WinForm, posso associare il FileSystemWhatcher con un controllo WinForm con la proprietà "SyncronizingObject". Assegnando a quella proprietà il form "padre", gli eventi del whatcher vengono eseguiti nello stesso thread grafico (così posso aggiornare i controlli senza errori).

Però sembra non funzionare con le window WPF... Infatti non posso associare la proprietà "SyncronizingObject" a nessun controllo...

Sapete come posso fare?
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5