Gestione seriale in c#

venerdì 30 dicembre 2011 - 01.23
Tag Elenco Tags  C#  |  Windows 7  |  Visual Studio Express  |  Office 2010

82_marco Profilo | Junior Member

Ciao a tutti,
Sto imparando ad usare c# e tentando di progettare un interfaccia di comunicazione con una scheda IO mi sono bloccato in questo problema :-(

dati dei protocolli di lettura e scrittura devo gestire la porta com in modo che per tutta la durata di funzionamento del software esegua i protocolli in sequenza e gestisca i valori letti.
cioe' vorrei che il programma facesse:
1- calcolo del protocollo di scrittura in base al valore delle variabili
2- scrittura del protocollo nella seriale
3- lettura del protocollo di risposta
4- gestione del valore letto

avrei pensato di usare un thread in modo di non mandare l'applicazione in stallo visto che deve svolgere anche altre operazioni.

Voi cosa ne pensate?
potete darmi un aiuto nella progettazione del codice?

Grazie

Jeremy Profilo | Guru

Ciao marco.
>avrei pensato di usare un thread in modo di non mandare l'applicazione
>in stallo visto che deve svolgere anche altre operazioni.
>
>Voi cosa ne pensate?
Io penso sia la soluzione più logica.

>potete darmi un aiuto nella progettazione del codice?
Dipende dal tipo di aiuto che cerchi. . . .possiamo darti dei pareri positivi o negativi riguardo alle scelte, possiamo aiutarti ad individuare eventuali bug e consigliarti sulle tecnologie da utilizzare . . . . ma la progettazione vera e propria sta a te.
>
>Grazie
Facci sapere.
Ciao.

82_marco Profilo | Junior Member

Ciao, scusate il ritardo.

Avrei pensato di fare in questo modo:

class Collegamento
{
SerialPort sp;
String s_ricevi;

public Collegamento()
{
sp = new SerialPort("COM1", 2400, Parity.Even, 7, StopBits.Two);
sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
sp.Handshake = Handshake.XOnXOff;
sp.ReadTimeout = 500;

}

public void ApriConnessione()
{
sp.Open();

}
}
public void InviaStringa()
{

sp.Write(">eR3F!"); // Protocollo richiesta di lettura stato

}

void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
s_ricevi = sp.ReadLine().ToString();
}


La porta non la ho chiusa perche il programma deve operare continuamente sulla seriale per tutto il ciclo di funzionamento .
Voi cosa ne pensate? potrebbe funzionare questo thread come funzionamento continuo? (e' il primo che faccio)
Non lo ho provato perche' il mio pc e' a casa e potro' farl tra una settimana.
Se avete qualche suggerimento li accetto molto volentieri :-)

GRazie e buon anno a tutti

Jeremy Profilo | Guru

Ciao Marco.
Fai solo attenzione al fatto che così non stai utilizzando un thread separato. . . . O quantomeno non lo si capisce dal codice che hai postato.
Facci sapere. . . .
Ciao.

82_marco Profilo | Junior Member

Ciao visto che sarebbe il mio primo thread mi potreste dare un aiutino o qualche consiglio?

Jeremy Profilo | Guru

Ciao Marco.
Non ho detto che sia sbagliato(dipende dalla mole di dati) .... ma solo che non è quello che avevi dichiarato all'inizio di voler fare.
Ad ogni modo volendo processare la lettura dei dati in un thread separato da quello che gestisce anche la UI il codice dovrebbe essere più o meno così:
private SerialPort sp; private Thread NewThread; private string s_ricevi; private void Form1_Load(System.Object sender, System.EventArgs e) { sp = new SerialPort("COM1", 2400, Parity.Even, 7, StopBits.Two); sp.Handshake = Handshake.XOnXOff; sp.ReadTimeout = 500; sp.Open(); sp.Write(">eR3F!"); NewThread = new Thread(_Leggi); NewThread.Start(); } private void _Leggi() { do { if (sp.BytesToRead > 0) { s_ricevi = sp.ReadLine().ToString(); } Thread.Sleep(1); //Questo serve a non impegnare troppo il processore } while (true); }

Facci sapere.....
Ciao

82_marco Profilo | Junior Member

Ciao grazie del consiglio :-)

Ho provato il codice con un programma che fa il log della seriale perche ora non ho la scheda disponibile e mi risulta che non da il comando di scrittura.
Ti invio un pezzo del log:

02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS

c'e' qualcosa che m sfugge?

Jeremy Profilo | Guru

Ciao Marco.
>Ciao grazie del consiglio :-)
>
>Ho provato il codice con un programma che fa il log della seriale
>perche ora non ho la scheda disponibile e mi risulta che non
>da il comando di scrittura.
>Ti invio un pezzo del log:
>
>02:51:11 WindowsFormsAp IOCTL_SERIAL_GET_COMMSTATUS Serial0 SUCCESS
Dal pezzo di Log che hai postato si capisce solo che un comando ha avuto successo alle 02:51:11 . . . .
>c'e' qualcosa che m sfugge?
Non saprei. . . . provalo con la scheda e poi Facci sapere. . . .
Ciao

82_marco Profilo | Junior Member

Ciao a tutti,
Sono appena riuscito a provarlo con la scheda e questi sono i risultati: il codice comanda la scheda, la scheda attua il comando e risponde (il led tx della scheda si accende) il software non scrive il valore nella label.
ho notato anche che viene scritto solo una volta nella seriale (il led rx della scheda si accende una sola volta), forse perche' il software aspeta la risposta?

Grazie dell aiuto che mi date :-)

Jeremy Profilo | Guru

Ciao Marco
>Sono appena riuscito a provarlo con la scheda e questi sono i
>risultati: il codice comanda la scheda, la scheda attua il comando
>e risponde (il led tx della scheda si accende) il software non
>scrive il valore nella label.
Quale label, finora non abbiamo mai parlato di label ..... cosa vuol dire che non scrive nella label ..... la variabile s_ricevi si vaorizza correttamente?
Ricevi forse un eccezione di chrossthreading?

>ho notato anche che viene scritto solo una volta nella seriale
>(il led rx della scheda si accende una sola volta)
credo che sia esattamente il avoro che deve fare .... se vuoi creare un Loop continuo di lettura dei dati dala scheda, dovrai ogni volta inviargli la richiesta.

sp.Write("etc...")
Facci sapere....
Ciao

82_marco Profilo | Junior Member

Ciao per vedere il valore di s_ricevi ho inserito una label e la ho gestita con il comando Label1.Text = s_ricevi;
Per vedere se si valorizza correttamente potrei usare watch window giusto? non la ho mai usata, come devo fare per attivarla?


Mi servirbbe che il codice usasse continuamente la seriale perche' in teoria dovrei gestire 256 schede (come dire al software quante ce ne sono lo vedro' dopo, in tanto vorrei riuscire a fare funzionare la comunicazione) cambiando il protocollo che all interno contiene l'indirizzo della scheda.
Se una scheda non risponde dovrebbe andare avanti con la comunicazione e provare a riscrivere il giro dopo.


Grazie

Jeremy Profilo | Guru

Ciao Marco.
>Ciao per vedere il valore di s_ricevi ho inserito una label e
>la ho gestita con il comando Label1.Text = s_ricevi;
Dipende da dove hai inserito la riga di codice

>Per vedere se si valorizza correttamente potrei usare watch window
>giusto? non la ho mai usata, come devo fare per attivarla?
Basta inserire uno Stop o un punto di interruzione(F9) sulla riga successiva a s_ricevi = etc. . . e posizionare il puntatore del mouse sulla variabile s_ricevi.
>
>Mi servirbbe che il codice usasse continuamente la seriale perche'
>in teoria dovrei gestire 256 schede (come dire al software quante
>ce ne sono lo vedro' dopo, in tanto vorrei riuscire a fare funzionare
>la comunicazione) cambiando il protocollo che all interno contiene
>l'indirizzo della scheda.
>Se una scheda non risponde dovrebbe andare avanti con la comunicazione
>e provare a riscrivere il giro dopo.
Questo lo vedrai dopo . . . . comincia a far funzionare per bene una scheda singolarmente . . . . Il resto verrà di conseguenza.
>
>Grazie
Facci sapere. . . .
Ciao.

82_marco Profilo | Junior Member

eccomi :-)
Ho provato a vedere se s_ricevi assume un valore, ma rimane sempre su null.
la scheda funziona perche' provata con hyperterminal restituisce il protocollo di risposta.

non e' che bisogna gestire qualche evento sulla seriale?

mi viene segnalata anche un eccezione: timeout operazione su s_ricevi = sp.ReadLine().ToString();

82_marco Profilo | Junior Member

NIente, non riesco a leggere la risposta dalla seriale
puo' essere utile e vi posto il protocollo di risposta della scheda?

Jeremy Profilo | Guru

Ciao Marco.
Bisogna che mi dai il tempo di dargli un occhio con calma.
Sbagli sicuramente tu qualcosa ma, non avendo a disposizione la scheda, non so dirti esattamente cosa.
Stasera provo ad inventarmi qualcosa per dirti 2 o 3 possibili cause ed eventuali prove che puoi fare.

Ciao.

82_marco Profilo | Junior Member

Ciao, grazie
Sicuramente mi sfugge qualcosa, sono alle prime armi
in tanto faccio anche io delle prove e se ci capisco qualcosa ti informo

Jeremy Profilo | Guru

Ciao Marco.
prova a vedere cosa salta fuori in questo modo
private void _Leggi() { byte[] ByteLetti = new byte[1]; do { if (sp.BytesToRead > 0) { Array.Resize(ref ByteLetti, sp.BytesToRead); sp.Read(ByteLetti, 0, ByteLetti.Count); s_ricevi = System.Text.Encoding.ASCII.GetString(ByteLetti); } Thread.Sleep(1); //Questo serve a non impegnare troppo il processore } while (true); }

Se non dovesse funzionare ... cerca di prelevare più informazioni possibili, del tipo .... valore delle variabili, eventuali eccezioni, etc...
Per farlo, ti basta inserire dei punti di interruzione(con F9) ed eventualmente proseguire l'esecuzione del debug passo passo(F8).
E' importante anche sapere il valore della variabile "BytesToRead" dell'oggetto "sp".
Facci sapere ....
Ciao

82_marco Profilo | Junior Member

Ciao, ho provato il codice che mi hai postato, ma ci sono 2 errori:
Errore 1 La corrispondenza migliore del metodo di overload per 'System.IO.Ports.SerialPort.Read(byte[], int, int)' presenta alcuni argomenti non validi

Errore 2 Argomento 3: impossibile convertire da 'gruppo di metodi' a 'int'

Il protocollo di risposta che la scheda mi restituisce attraverso hyperterminal e': <ec04 + il carattere ascii 13

Jeremy Profilo | Guru

Si scusa, colpa mia.
Sostituisci questa riga
sp.Read(ByteLetti, 0, ByteLetti.Count);
con questa
sp.Read(ByteLetti, 0, ByteLetti.Length);


Facci sapere...
Ciao

82_marco Profilo | Junior Member

Ciao ho provato, gli errori non ci sono piu, mettendo un punto di interruzione sulla riga: while (true); al secondo step il valore di bytetoread e' 6, mentre il valore di s_ricevi e' il protocollo di risposta, pero' senza punti di interruzione s_ricevi vale null.....

Jeremy Profilo | Guru

Ciao Marco.
Eseguita la prima lettura(nel momento in cui s_ricevi è valorizzata correttamente), prova a vedere il valore di BytesToRead. Dovresti verificare che sia 0.
Facci sapere...
Ciao

82_marco Profilo | Junior Member

CIao, confermo... vale 0

Jeremy Profilo | Guru

Perfetto ..... vuol dire che per quanto riguarda la comunicazione seriale siamo a posto.
Dovrebbe funzionare tutto correttamente ..... se però, come dici, la variabile s_ricevi si valorizza correttamente per poi diventare ancora null...... prova a mettere un punto di interruzione sulla riga s_ricevi = sp.Read(etc..) e verificare che ci passi una sola volta da quel punto(solo quando BytesToRead è maggiore di 0).
Se così fosse, allora sbagli tu qualcosa in qualche altro punto del programma.....altrimenti, bisogna capire bene perchè ci passa più di una volta.
Facci sapere....
Ciao

82_marco Profilo | Junior Member

vale null quando non metto punti di interruzione, mentre mettendo un punto di interruzione e premendo F5 per andare avanti con gli step resta valorizzato. forse sbaglio io qualcosa.
Potrei provare a visualizzarne il valore in una label. dove potrei inserirne la gestione?

Jeremy Profilo | Guru

Ciao Marco
Prova a sostituire questo codice
private void _Leggi() { byte[] ByteLetti = new byte[1]; do { if (sp.BytesToRead > 0) { Array.Resize(ref ByteLetti, sp.BytesToRead); sp.Read(ByteLetti, 0, ByteLetti.Length); s_ricevi = System.Text.Encoding.ASCII.GetString(ByteLetti); } Thread.Sleep(1); //Questo serve a non impegnare troppo il processore } while (true); }
con questo
public delegate void Aggiorna(string argValue); private void _Leggi() { byte[] ByteLetti = new byte[1]; do { if (sp.BytesToRead > 0) { Array.Resize(ref ByteLetti, sp.BytesToRead); sp.Read(ByteLetti, 0, ByteLetti.Length); s_ricevi = System.Text.Encoding.ASCII.GetString(ByteLetti); this.Invoke(new Aggiorna(_Aggiorna), s_ricevi); } Thread.Sleep(1); //Questo serve a non impegnare troppo il processore } while (true); } private void _Aggiorna(string argValue) { label1.text = argValue; }
Ovviamente devi aggiungere una label al tuo Form.

Facci sapere...

82_marco Profilo | Junior Member

Ciao, funziona
adesso posso vedere come gestire i 4 e la gestione continua dela seriale
Se strovo dei problemi posso continuare su questo thread o ne apro un altro?

Jeremy Profilo | Guru

Ciao Marco.
Se mi rispondi "non viene visualizzato niente sulla Label" ..... io faccio fatica ad aiutarti ..... bisogna che fai qualche prova in Debug(gli strumenti li hai) e mi dici qualcosa in più.
Metti un punto di interruzione su
this.Invoke(new Aggiorna(_Aggiorna), s_ricevi);
ed un'altro qui
label1.text = argValue;
prova a valutare il valore di "argValue" al momento dell'interruzione .... e sopratutto se il runtime passa da quell'istruzione.

Facci sapere...
Ciao

82_marco Profilo | Junior Member

Ciao, avevo modificato il messaggio.
non si visualizzava niente per colpa mia

adesso devo provare ad implementare la gestione dei 4 protocolli e poi la gestione di piu periferiche

Se incontro problemi continuo a chiedere su questo thread o ne apro uno nuovo?

Jeremy Profilo | Guru

Ciao Marco.
>Se incontro problemi continuo a chiedere su questo thread o ne
>apro uno nuovo?
Visto il titolo e i vari post ...... penso si possa continuare su questo thread.
Ciao.

82_marco Profilo | Junior Member

Ciao per fare un comando infinito della seriale mi consigli di usare il comando goto o c''e qualcosa di piu appropriato?

Mi spiego meglio: in sostanza quasi tutto il software funziona in un ciclo ripetitivo (calcolo indirizzo della scheda da comandare, calcolo del protocollo di lettura, lettura risposta della scheda, calcolo del protocollo di scrittura delle schede in base allo stato precedente e alla risposta, ecc)
secondo voi va bene raggruppare tutto sotto un goto o e' meglio fare tanti threads e invocarli?

Jeremy Profilo | Guru

Ciao Marco.
>Ciao per fare un comando infinito della seriale mi consigli di
>usare il comando goto o c''e qualcosa di piu appropriato?
DO...LOOP

>secondo voi va bene raggruppare tutto sotto un goto o e' meglio
>fare tanti threads e invocarli?
Io creerei una List(of GestioneSeriale).
Ogni classe gestisce una scheda.
Nel costruttore della classe farei partire un thread che gestisce la trasmissione e ricezione dei dati.

Facci sapere....
Ciao

82_marco Profilo | Junior Member

Ciao, non penso di riuscire a creare una classe per ogni scheda perche' avrei intenzione di indicare al software quante chede ci sono e di che tipo sono attraverso una riga di un file txt che dovra' contenere tutti i parametri di personalizzazione (non ho ancora pensato a come farlo), da leggere appena avviato il programma.

avevo pensato di partire dall indirizzo della scheda 1, creare il suo protocollo attraverso una classe e inviarlo alla seriale usando il tread.
Fatto questo attraverso il loop incrementare l'indirizzo della scheda ed usare la stessa classe per creare il protocollo e inviare alla seriale.

Come ti sembra?

Jeremy Profilo | Guru

Ciao Marco.
>perche' avrei intenzione di indicare al software quante chede
>ci sono e di che tipo sono attraverso una riga di un file txt
>che dovra' contenere tutti i parametri di personalizzazione
Proprio per questo DEVI creare una lista di "GestioneSeriale"(intesa come classe) nel quale costruttore getirai l'accettazione di parametri che caratterizzeranno l'identità della scheda(e quindi della gestione seriale).
Se poi le schede cominciano a diventare tante ..... forse abbandonerei il discorso di creare un thread per ogni scheda, e lavorerei su di un unico thread gestendo una seriale per volta(dipende dalla necessità di real-time che hai).

Facci sapere...
Ciao

82_marco Profilo | Junior Member

Ciao le schede sono collegate ad un unica seriale, decido con quale interagire tramite il protocollo.

O avrei pensato di aggiungere al codice sopra i comandi if e goto per fare ritornare il software al punto dove scrive in seriale, ma non funziona, c'e' un altro comando da usare al posto del goto?
Vorrei usare if perche' voglio confrontare la risposta della seriale per poi trattarla se necessario

Jeremy Profilo | Guru

Ciao Marco.
>Ciao le schede sono collegate ad un unica seriale, decido con
>quale interagire tramite il protocollo.
Meglio .... un parametro in meno
>
>O avrei pensato di aggiungere al codice sopra i comandi if e
>goto per fare ritornare il software al punto dove scrive in seriale,
>ma non funziona, c'e' un altro comando da usare al posto del
>goto?
>Vorrei usare if perche' voglio confrontare la risposta della
>seriale per poi trattarla se necessario
Questa parte non l'ho capita ma ..... al posto di goto usa Do...Loop

Facci sapere...
Ciao

82_marco Profilo | Junior Member

Ciao se vuoi ti posso inviare un diagramma di flusso cosi vedi cosa mi piacerebbe fare

Jeremy Profilo | Guru

Ok ... allegalo al post ... così lo vedono tutti.

82_marco Profilo | Junior Member


844x1203 850Kb


eccolo... e' fatto a mano ma dovrebbe rendere l 'idea.
Il software oltre a gestire la seriale in questo modo poi dovra' fare altro, quindi non devo farlo andare in stallo

Jeremy Profilo | Guru

Prova a partire da una cosa del genere
using Microsoft.VisualBasic; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Threading; public class Form1 { private Thread NewThread; private List<Scheda> Schede; private void Form1_Load(System.Object sender, System.EventArgs e) { Schede = new List<Scheda>(); Schede.Add(new Scheda { Id = 0, StringaComando = "Protocollo1" }); Schede.Add(new Scheda { Id = 1, StringaComando = "Protocollo2" }); Schede.Add(new Scheda { Id = 2, StringaComando = "Protocollo3" }); Schede.Add(new Scheda { Id = 3, StringaComando = "Protocollo4" }); NewThread = new Thread(_NewThread); NewThread.Start(); } private void _NewThread() { do { foreach (Scheda Scheda in Schede) { //TODO: Gestione dell'invio del comando do { //TODO: Attesa della risposta string Risposta = null; //= Risposta dalla scheda Scheda.Risposte.Add(Risposta); } while ('Condizione di uscita); } } while (true); } } public class Scheda { public int Id { get; set; } public string StringaComando { get; set; } public List<string> Risposte { get; set; } public Scheda() { Risposte = new List<string>(); } }

E' solo un pò di codice buttato lì per darti uno spunto.
Non prenderlo come vangelo ...... io posso darti dei consigli discutibili o meno ma pur sempre solo consigli.

Facci sapere...
Ciao

82_marco Profilo | Junior Member

Per adesso mi basterebbe gestire anche una sola scheda, credevo bastase modificare questo codice che mi hai indicato all inizio della discussione aggiungendoci dei controlli

private void Form1_Load_1(object sender, EventArgs e)
{
label1.Text = s_ricevi;
sp = new SerialPort("COM2", 19200, Parity.None, 8, StopBits.One);
sp.Handshake = Handshake.XOnXOff;
sp.ReadTimeout = 500;
sp.Open();
sp.Write(">eR??!");
// sp.Write(">ewFF000055D0!");
NewThread = new Thread(_Leggi);
NewThread.Start();
}
public delegate void Aggiorna(string argValue);
private void _Leggi()
{
byte[] ByteLetti = new byte[1];
do
{
if (sp.BytesToRead > 0)
{
Array.Resize(ref ByteLetti, sp.BytesToRead);
sp.Read(ByteLetti, 0, ByteLetti.Length);
s_ricevi = System.Text.Encoding.ASCII.GetString(ByteLetti);
this.Invoke(new Aggiorna(_Aggiorna), s_ricevi);
}
Thread.Sleep(1);
//Questo serve a non impegnare troppo il processore
} while (true);
}

private void _Aggiorna(string argValue)
{
label1.Text = argValue;
}

tanto per cominciare se io volessi, dopo avere assegnato il valore a label1, chiamare un metodo che mi calcoli il nuovo protocollo da mettere su sp.Write(" "); e poi andare a scrivere ancora in seriale e ripetere il ciclo. potrebbe essere un inizio, no?

Jeremy Profilo | Guru

Come ti dicevo.....
Fai come meglio credi.
Noi ti possiamo dare dei consigli....ma la progettazione deve essere tua.

Facci sapere...
Ciao

82_marco Profilo | Junior Member

Scusa ma non ho capito il codice che mi hai consigliato, mi sa che mi sto mettendo in una cosa piu' grande di me

Jeremy Profilo | Guru

Ciao Marco.
Scusa ma mi sono accorto solo ora del messaggio
>Scusa ma non ho capito il codice che mi hai consigliato, mi sa
>che mi sto mettendo in una cosa piu' grande di me
No no .... sono io che probabilmente ti ho fatto correre troppo .... vai avanti in base alle tue attuali competenze e interpellaci per i problemi che incontri.
E' la strada migliore ... credimi.

Facci sapere...
Ciao

82_marco Profilo | Junior Member

Ciao,
sono riuscuto a fare leggere la seriale in continuo e poi finito la lettura ho lanciato un thread che mi tratta il protocollo letto :-)
ora Vorrei ora confrontare il protocollo trattato con un altro teorico per decidere cosa mandare in seriale la scrittura successiva...spero di riuscirci cosi avro il controllo completo di una scheda.....fatto questo devo vedere come gestirne fino a 256

82_marco Profilo | Junior Member

>Ciao Marco
>Prova a sostituire questo codice
>
>private void _Leggi()
>{
> byte[] ByteLetti = new byte[1];
> do {
> if (sp.BytesToRead > 0) {
> Array.Resize(ref ByteLetti, sp.BytesToRead);
> sp.Read(ByteLetti, 0, ByteLetti.Length);
>s_ricevi = System.Text.Encoding.ASCII.GetString(ByteLetti);
> }
> Thread.Sleep(1);
> //Questo serve a non impegnare troppo il processore
> } while (true);
>}
>
>con questo
>
>public delegate void Aggiorna(string argValue);
>private void _Leggi()
>{
> byte[] ByteLetti = new byte[1];
> do {
> if (sp.BytesToRead > 0) {
> Array.Resize(ref ByteLetti, sp.BytesToRead);
> sp.Read(ByteLetti, 0, ByteLetti.Length);
> s_ricevi = System.Text.Encoding.ASCII.GetString(ByteLetti);
> this.Invoke(new Aggiorna(_Aggiorna), s_ricevi);
> }
> Thread.Sleep(1);
> //Questo serve a non impegnare troppo il processore
> } while (true);
>}
>
>private void _Aggiorna(string argValue)
>{
> label1.text = argValue;
>}
>
>Ovviamente devi aggiungere una label al tuo Form.
>

Ciao mi e' capitato un problemino che non riescoa risolvere da solo

in caso di mancata risposta della scheda vorrei tenere vuota la label dove visualizzo la risposta della scheda per poi ripendere a scrivere quando la scheda ritorna a rispondere, al momento se scollego la scheda mi resta visualizzata l'ultima lettura.

ho provato a scaricare i buffer della seriale ma non e' cambito nulla, s_ricevi tiene memorizzato l' ultimo valore.

potete darmi un aiutino per favore?

Jeremy Profilo | Guru

Ciao
prova a sostituire questo codice
do { if (sp.BytesToRead > 0) { Array.Resize(ref ByteLetti, sp.BytesToRead);
con questo
do { if (sp.BytesToRead == 0) { s_ricevi = string.empty; } if (sp.BytesToRead > 0) { Array.Resize(ref ByteLetti, sp.BytesToRead);
Facci sapere...
Ciao

82_marco Profilo | Junior Member

Ciao, ho provato la modifica che mi hai proposto ma quando scollego la scheda s_ricevi mantiene l'ultimo valore letto.
hai qualche idea? non riesco a venirne fuori

82_marco Profilo | Junior Member

C'e' qualche altra soluzione? :-(

Jeremy Profilo | Guru

Si....in realtà manca un pezzo

do { if (sp.BytesToRead == 0) { s_ricevi = string.empty; this.Invoke(new Aggiorna(_Aggiorna), s_ricevi); } if (sp.BytesToRead > 0) { Array.Resize(ref ByteLetti, sp.BytesToRead);

Ciao

82_marco Profilo | Junior Member

Funziona,
Grazie infinite ;-)

palmaiw Profilo | Newbie

Buon giorno Jeremy e buon giorno a tutti,
ho letto tutti i post in merito alla discussione su come gestire la seriale.
Premesso che io sono nuovo all'ambiente visual C#, provengo dal vecchio ambiente C++, basic, pascal, fortran, nel quale il programma era sequenziale per cui ancora faccio difficoltà ad inquadrare il nuovo ambiente.
Vorrei fare un programma che riceve dei dati da seriale, invia dei comandi e gestisce poi i dati (analizza, eventualmente crea dei grafici e salva su disco i risultati).
Come primo passo ho creato un progetto con un form (form1) con un pulsante alcuni campi label e alcuni campi text, pertanto ho tre schede, form1.cs (con i metodi relativi al form1) form1.cs[progettazione] con la parte grafica del form1 ed una scheda program.cs nella quale vi è la funzione principame main(), la classe static class program ed altre comadi (using).
Domanda:
Il codice da te scritto nel post, in quale scheda deve essere inserito fra le due conteneti codice sopra citate? Forse è necessario creare una nuova scheda? Nel caso come si deve operare?
Grazie.

82_marco Profilo | Junior Member

Ciao, e' il codice relativo alla seconda...
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-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5