Pages: [1]   Go Down
Author Topic: Programma C# in continuo ascolto su seriale  (Read 1891 times)
0 Members and 1 Guest are viewing this topic.
Montalbano Jonico
Offline Offline
Sr. Member
****
Karma: 1
Posts: 287
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao a tutti, premetto che ho girando un bel po su forum ma non avendo conoscenze solide mi viene difficile anche cercare su questo argomento.
Vi spiego, ho preparato un piccolo tool in C# che legge i dati seriali che vengono mandati da arduino. In particolare, ho arduino con un pulsante ed un led, in questo momento il programma ha un pulsante che, alla pressione, controlla lo stato del LED ed esegue un'azione. Per comodità posto il codice
Code:
public partial class MainForm : Form
{
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();

//configuring the serial port
serialPort1.PortName="COM3";
serialPort1.BaudRate=9600;
serialPort1.DataBits=8;
serialPort1.Parity=Parity.None;
serialPort1.StopBits= StopBits.One;

//opening the serial port
serialPort1.Open();
serialPort1.DiscardInBuffer();
//lettura = serialPort1.Read
}




void Button1Click(object sender, EventArgs e)
{

{

string comando = serialPort1.ReadLine();
string control = comando.Substring(0,6);



if (String.Equals(control, "SPENTO"))

{

Process.Start("IExplore.exe");
}


if (String.Equals(control, "ACCESO"))

{
Process.Start("notepad.exe");
}


}
}

Come vedete io premo il pulsante su arduino, il led si accende, ed invia una stringa.
Lato software io premo il pulsante, controllo la stringa (quindi lo stato) ed eseguo un'azione. In questo caso ho messo ad esempio il lancio di iexplorer.exe oppure notepad.exe.

Quello che io vorrei ora è che, il programma stesse sempre in ascolto! Cioè non devo eseguire ogni volta il check con il pulsante per vedere lo stato.

Quinid il programma sta in esecuzione, io premo il pulsante di arduino ed automaticamente mi si avvia il programma sul PC.

Come potrei risolvere?
Grazie mille!
Logged

Parma
Offline Offline
Edison Member
*
Karma: 21
Posts: 2387
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Se il programma non ha interfaccia grafica che deve aggiornarsi puoi fare un semplice ciclo infinito, l'applicazione sembrerà bloccata ma funzionerà.
In alternativa devi creare un Thread secondario, puoi usare il controllo backgroundworker per semplificarti la vita

Ciao
Logged

Montalbano Jonico
Offline Offline
Sr. Member
****
Karma: 1
Posts: 287
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Se il programma non ha interfaccia grafica che deve aggiornarsi puoi fare un semplice ciclo infinito, l'applicazione sembrerà bloccata ma funzionerà.
In alternativa devi creare un Thread secondario, puoi usare il controllo backgroundworker per semplificarti la vita

Ciao

No il programma dovrebbe avere una minima interaccia grafica.. Almeno per quanto riguarda il settaggio della porta COM.. quindi l'interfaccia deve esserci. Per quanto riguarda quinid il backgroundworker stavo leggendo ora e sembra l'ideale, una cosa però? come dovrebbe avvenire il controllo sulla seriale? Una cosa del genere:
Code:
while serialport1.isopen..
{
if e condizioni varie..
}

potrebbe andare o sono fuori strada?! xD
Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 129
Posts: 9447
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No il programma dovrebbe avere una minima interaccia grafica.. Almeno per quanto riguarda il settaggio della porta COM.. quindi l'interfaccia deve esserci.

In C#, ma anche in C++, la seriale è un oggetto pertanto ha metodi, proprietà ed eventi, tra gli eventi devi avere qualcosa del tipo OnRxChar, o OnRxBuf, che puoi collegare ad una funzione, ovvero ogni volta che viene ricevuto un carattere viene richiamata la funzione collegata a questo evento.
In pratica ogni volta che arriva un carattere, o il buffer è pieno, sulla seriale la funzione che deve gestire la cosa viene richiamata automaticamente senza necessità di fare nessun polling, va da se che nel main loop dovrai comunque controllare dei flag, settati dalla funzione che gestisce la seriale, che ti indicano quale operazione eseguire.
Come va gestita la cosa in dettaglio dipende da quale compilatore ed eventuali librerie accessorie utilizzi, però il concetto generale che ti ho illustrato è valido per tutti i compilatori e sistemi operativi.
Logged

Bergamo
Offline Offline
God Member
*****
Karma: 1
Posts: 663
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao

in c# (o meglio in .Net Framework) la seriale ha una gestione "thread" interna, ovvero automaticamente viene generato un thread dedicato alla ricezione per non risultare bloccante.

Quello che tu devi fare è scrivere un tuo oggetto SerialDataReceivedEventHandler e aggiungerlo agli handlers dell'evento DataReceived:
http://msdn.microsoft.com/it-it/library/system.io.ports.serialport.datareceived.aspx

Molto importante se scrivi un programma con la GUI è l'utilizzo dei metodi delegate per aggiornare elementi dell'interfaccia grafica: se infatti provassi ad aggiornarli direttamente nel tuo handler, essendo questo eseguito in un thread separato, otterresti una exception (un po' come in java non puoi da un thread aggiornare componenti Swing ma devi sempre passare per lo SwingUtilities.invokeLater()).

Se vuoi un esempio completo guarda il mio progetto AnalogDemo:
https://github.com/lucadentella/AnalogDemo

bye
Logged

lucadentella.it

Parma
Offline Offline
Edison Member
*
Karma: 21
Posts: 2387
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In genere per risolvere queste situazioni devi usare un thread secondario e inserire il codice come quello che hai scritto bene o male.
Nel caso specifico del controllo SerialPort ti puoi semplificare la vita utilizzando gli eventi offerti dal controllo, ricordati di usare il metodo Invoke su un oggetto dell'interfaccia grafica per aggiornarlo.

Ciao
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 43
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Potresti anche utilizzare un semplicissimo timer, che ad ogni giro, elabora i dati provenienti da seriali, con il vantaggio che l'applicazione non si blocca.
Logged

Bergamo
Offline Offline
God Member
*****
Karma: 1
Posts: 663
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao

non serve inventarsi Timers... gli handlers sulla ricezione seriale girano già in un altro thread e quindi non sono bloccanti
Logged

lucadentella.it

0
Offline Offline
Newbie
*
Karma: 0
Posts: 43
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dipende dalle applicazioni, anche perche con gli handler non puoi impostare un intervallo di lettura, invece impostando l'intervallo del timer a 1000 per esempio, nell'evento timer.tick, verrà eseguito un controllo sulla seriale ogni secondo, invece con gli handler, non si attiva ogni volta che riceve un dato?

Magari sbaglio io.
Logged

Pages: [1]   Go Up
Jump to: