|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Jul 2006
Messaggi: 64
|
[c++] Lettura Dati Seriale
Buongiorno a tutti,
vi spiego subito quale è il mio problema: praticamente devo raccogliere dei dati da uno scanner laser industriale di sicurezza, il quale è impostato sull'emmissione continua di dati, che vengono mandati sulla seriale. Da pc io vorrei leggere questi dati (sono in forma di telegrammi), e quindi ho utilizzato le Api, con ReadFile. Il buffer che metto nella lettura è di tip LPVOID, grazie al quale riesco effettivamente ad estrarre dei dati utili. Ci sono però due problemi abbastanza importanti. 1) Non riesco a capire cosa sia effettivamente LPVOID, ma è l'unico con il quale riesco ad estrarre dati. Il problema è che per la loro elaborazione sono molto più comodo con oggetti string (non char). Non sapendo come eseguire la trasformazione da LPVOID->string per ora scrivo ogni volta un file di testo e lo rileggo immediatamente come string.... non il massimo dell'efficienza. 2) Le informazioni che ho sul laser sono veramente poche, c'è un modo per capire come vengono spediti i dati da questo (ovvero se sono caratteri ascii o che), con hyperterminal ottengo l'emissione continua di caratteri "speciali", non so se questo può esservi d'aiuto... Vi ringrazio anticipatamente per il vostro aiuto !!!! link al pdf dei telegrammi: Codice HTML:
https://mysick.com/saqqara/pdf.aspx?id=im0022892 |
![]() |
![]() |
![]() |
#2 | ||
Member
Iscritto dal: May 2009
Messaggi: 186
|
Quote:
Quote:
HTH, |
||
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
LPVOID vuol dire semplicemente puntatore a void, é una typedef definita come void*
per ottenere la stringa di caratteri basta che fai un cast esplicito a LPCSTR, che sarebbe puntatore a const CHAR (dove CHAR sarebbe banalmente char), ma come ti ha detto ESSE-EFFE puoi anche passare un puntatore a CHAR fin dall'inizio sfruttando quindi il polimorfismo. |
![]() |
![]() |
![]() |
#4 |
Member
Iscritto dal: Jul 2006
Messaggi: 64
|
ok, grazie mille!
Adesso vedo di dedicarmici un pò più approfonditamente dopo questi suggerimenti, il problema è che non sono propriamente un esperto, e quindi anche le piccole difficoltà mi mettono in crisi ![]() ![]() |
![]() |
![]() |
![]() |
#5 |
Member
Iscritto dal: Jul 2006
Messaggi: 64
|
Scusate ma proprio non riesco.....
se metto un puntatpre a char il programma salta, così come con LPCSTR, l'unico con cui funziona è ancora LPVOID.... Il problema è allora trasformare LPVOID in stringa, per ora lo faccio con il file di testo, un metodo alternativo è quello con puntatore, ma non riesco poi a metterci mano Codice:
int LetturaSeriale( HANDLE PortaSeriale ) { //Definizione dell'evento relativo all'arrivo di dati in ricezione DWORD dwEventMask = EV_RXCHAR; //Dichiarazione della variabile relativa al numero di Byte letti dalla seriale DWORD NumberOfBytesRead; //Settaggio della funzione di attesa di un evento bool DatiSuSeriale = SetCommMask( PortaSeriale , EV_RXCHAR); //Variabile relativa al salvataggio del buffer di lettura LPVOID BufferRxDati; //Funzione di sincronizzazione dell'acquisizione con lo scanner laser: //si attende l'arrivo di dati sulla seriale per la loro lettura WaitCommEvent(PortaSeriale , &dwEventMask, 0); //Lettura dei dati sulla seriale, e salvataggio dei 4 byte letti nella variabile Buffer bool LetturaOk = ReadFile( PortaSeriale , &BufferRxDati , 4, &NumberOfBytesRead , NULL ); //Messaggio di errore nella lettura del buffer if ( !LetturaOk ) { cout<<"Problema nella lettura della seriale"<<endl; system("Pause"); } //Copia della lettura nella stringa del buffer (CON SCRITTURA DI TESTO) ofstream outfile2; outfile2.open ("temp.txt",ofstream::out | ofstream::trunc); outfile2<<BufferRxDati; outfile2.close(); //Vettore contenitore dei dati in ingresso, di tipo double vector<string> DatiIngresso; //Componenti del vettore string Dato; ifstream in ("temp.txt"); //Riempimento del vettore while(in >> Dato) { DatiIngresso.push_back(Dato); } BufferRx = DatiIngresso[0]; //Copia LPVOID in stringa string* vp = (string*) BufferRxDati; } |
![]() |
![]() |
![]() |
#6 | |
Member
Iscritto dal: May 2009
Messaggi: 186
|
Quote:
Codice:
//Variabile relativa al salvataggio del buffer di lettura char BufferRxDati[4]; Tra l'altro la WaitCommEvent messa così non credo abbia molto senso perchè poi vai a leggere 4 byte dalla seriale (senza neanche controllare se effettivamente li hai letti). Insomma poi controllalo bene quel codice... HTH, |
|
![]() |
![]() |
![]() |
#7 |
Member
Iscritto dal: Jul 2006
Messaggi: 64
|
Infatti visto così il codice anche a me non sembra ok, a mia discolpa però c'è da dire che non ho avuto possibilità di frequentare un corso di c++, e così mi arrangio....
![]() ![]() Visto che ci sono volevo chiederti se potresti indirizzarmi su qualche lettura che meglio potrebbe aiutarmi nel campo della seriale, grazie ancora ![]() ![]() |
![]() |
![]() |
![]() |
#8 | ||
Member
Iscritto dal: May 2009
Messaggi: 186
|
Quote:
Quote:
Però dovresti dirci se ora, allocando correttamente il buffer, la lettura funziona... |
||
![]() |
![]() |
![]() |
#9 |
Member
Iscritto dal: Jul 2006
Messaggi: 64
|
Ci ho provato ma non funziona... Il vero problema è che sto andando avanti a fari spenti, pensavo che la soluzione fosse solo quella di trasformare LPVOID in string, ma dopo quello che hai scritto mi sono reso conto che prima è meglio che mi informi parecchio sulla comunicazione seriale e sopratutto su c\c++, dove ho notevoli problemi....
|
![]() |
![]() |
![]() |
#10 | |
Member
Iscritto dal: May 2009
Messaggi: 186
|
Quote:
Ah, nel caso il problema fosse questo, ovviamente allocando il buffer come char[] lo devi passare alla ReadFile direttamente come BufferRxDati e non come &BufferRxDati. Ultima modifica di ESSE-EFFE : 01-07-2009 alle 16:39. |
|
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Codice:
//Variabile relativa al salvataggio del buffer di lettura char BufferRxDati[5]; //Funzione di sincronizzazione dell'acquisizione con lo scanner laser: //si attende l'arrivo di dati sulla seriale per la loro lettura WaitCommEvent(PortaSeriale , &dwEventMask, 0); //Lettura dei dati sulla seriale, e salvataggio dei 4 byte letti nella variabile Buffer bool LetturaOk = ReadFile( PortaSeriale , (LPVOID)BufferRxDati , 4, &NumberOfBytesRead , NULL ); //Messaggio di errore nella lettura del buffer if ( !LetturaOk ) { cout<<"Problema nella lettura della seriale"<<endl; system("Pause"); } BufferRxDati[4] = '/0'; |
![]() |
![]() |
![]() |
#12 |
Member
Iscritto dal: Jul 2006
Messaggi: 64
|
Ho provato con il char ed effettivamente funziona !!!
![]() ![]() Ora però ho un problema secondario, che succedeva anche con Labview, ovvero i caratteri non sono scritti in codice esadecimale, ma in strani disegnetti (come vedevo nell'hyperterminal)... Non avete qualche altro suggerimento (spero di non mettere a dura prova la vostra pazienza...) nel zip vi è la bozza del file ed un txt con le letture. Vi ringrazio ancora!! |
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Evidentemente la porta seriale non è settata al meglio... Prova a lavorare su bit dis top e bit di parità.
|
![]() |
![]() |
![]() |
#14 |
Member
Iscritto dal: Feb 2006
Messaggi: 134
|
Il dispositivo ti invia dei pacchetti di dati fatti di TOT byte e sei tu che devi interpretarli. Se, ad esempio, il protocollo prevede un pacchetto tipo
00 1A 32 56 7B 3C (inventato) non è che ti arrivano i caratteri 0, 0, 1, A, 3, 2, ecc... Ti arrivano i valori esadecimali 0, 1a, 32, ecc... |
![]() |
![]() |
![]() |
#15 | |||
Member
Iscritto dal: May 2009
Messaggi: 186
|
Quote:
Quote:
Quote:
|
|||
![]() |
![]() |
![]() |
#16 |
Member
Iscritto dal: Jul 2006
Messaggi: 64
|
scusate, ma pensavo di aver risposto verso le 11....
il fatto è che il laser emette dati in pacchetti esadecimali (si dice così?): con lpvoid riuscivo a leggere il numero esadecimale, es 0x0011bbaa, mentre ora penso che sto leggendo una codifica di questo valore. Con labview si ha lo stesso problema, solamente che nel display basta mettere l'opzione "Hex Dispaly". Mi chiedevo allora in che codifica possano essere i dati forniti dal char, per eventualmente eseguire una loro "codifica". Dato che ci sono, volevo gentilmente chiedervi se, poteste rispondermi ad un'altra domanda. In questo momento sto leggendo 4 byte dal buffer, ma su questo possono essercene di più? E se sono di più, prendo solo 4 byte e gli altri rimangono o cancello anche quelli non letti? Ancora una volta grazie mille!! |
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Guarda che char è solo un buffer. Puoi anche stampare ogni char in esadecimale.
|
![]() |
![]() |
![]() |
#18 | |||||
Member
Iscritto dal: May 2009
Messaggi: 186
|
Quote:
Quote:
Quote:
Quote:
Quote:
|
|||||
![]() |
![]() |
![]() |
#19 |
Member
Iscritto dal: Jul 2006
Messaggi: 64
|
mmm le cose si fanno difficili, anche perchè le mie conoscenza in questo campo rasentano lo zero....
Sul fatto del numero di byte sulla seriale, c'è modo di conoscere quanti effettivamente sono? Non vorrei dire una stupidaggine, ma il massimo valore è di 8 byte (quello impostato nel DCB.ByteSize)? Dopodichè, una volta che ho la stringa di caratteri, che codifica devo eseguire per potermeli trovare in formato esadecimale (che è effettivamente quello che mi serve per estrarre la scansione)? Grazie ancora (non so che altro dire, avete una pazienza immensa ![]() |
![]() |
![]() |
![]() |
#20 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Fai così, leggi un carattere alla volta e stampalo in esdecimale. La ReadFile dovrebbe essere bloccante se non ci sono byte disponibili.
Codice:
//Variabile relativa al salvataggio del buffer di lettura char BufferRxDati; //Funzione di sincronizzazione dell'acquisizione con lo scanner laser: //si attende l'arrivo di dati sulla seriale per la loro lettura WaitCommEvent(PortaSeriale , &dwEventMask, 0); //Lettura dei dati sulla seriale, e salvataggio dei 4 byte letti nella variabile Buffer bool LetturaOk = ReadFile( PortaSeriale , (LPVOID)&BufferRxDati , 1, &NumberOfBytesRead , NULL ); //Messaggio di errore nella lettura del buffer if ( !LetturaOk ) { cout<<"Problema nella lettura della seriale"<<endl; system("Pause"); } cout << hex << (int)BufferRxDati << endl; |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 04:16.