You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
4.0 KiB
144 lines
4.0 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.ComponentModel; |
|
using System.IO.Ports; |
|
using System.Text; |
|
|
|
namespace ArducopterConfigurator |
|
{ |
|
public interface IComms |
|
{ |
|
event Action<string> LineOfDataReceived; |
|
string CommPort { get; set; } |
|
bool IsConnected { get; } |
|
int BaudRate { get; set; } |
|
IEnumerable<string> ListCommPorts(); |
|
void Send(string send); |
|
bool Connect(); |
|
bool DisConnect(); |
|
} |
|
|
|
/// <summary> |
|
/// Represents a session of communication with the Arducopter |
|
/// </summary> |
|
/// <remarks> |
|
/// Looks after connection state etc |
|
/// </remarks> |
|
public class CommsSession : IComms |
|
{ |
|
private readonly SerialPort _sp; |
|
private BackgroundWorker _bgWorker; |
|
|
|
public event Action<string> LineOfDataReceived; |
|
|
|
public CommsSession() |
|
{ |
|
_sp = new SerialPort(); |
|
} |
|
|
|
public string CommPort { get; set; } |
|
|
|
public int BaudRate { get; set; } |
|
|
|
public bool Connect() |
|
{ |
|
_sp.BaudRate = BaudRate; |
|
_sp.PortName = CommPort; |
|
_sp.NewLine = "\n"; |
|
_sp.Handshake = Handshake.None; |
|
|
|
try |
|
{ |
|
_sp.Open(); |
|
_sp.ReadTimeout = 50000; |
|
|
|
|
|
// start the reading BG thread |
|
_bgWorker = new BackgroundWorker(); |
|
_bgWorker.DoWork += bgWorker_DoWork; |
|
_bgWorker.WorkerReportsProgress = true; |
|
_bgWorker.WorkerSupportsCancellation = true; |
|
_bgWorker.ProgressChanged += bgWorker_ProgressChanged; |
|
_bgWorker.RunWorkerAsync(); |
|
} |
|
catch (Exception ex) |
|
{ |
|
Error = ex.Message; |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
|
|
|
|
public bool DisConnect() |
|
{ |
|
_bgWorker.CancelAsync(); |
|
|
|
_sp.Close(); |
|
return true; |
|
} |
|
|
|
void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) |
|
{ |
|
// Thanks to BG worker, this should be raised on the UI thread |
|
var lineReceived = e.UserState as string; |
|
|
|
// TODO: POSSIBLE MONO ISSUE |
|
// Weird thing happening with the serial port on mono; sometimes the first |
|
// char is nulled. Work around for now is to drop it, and just send the remaining |
|
// chars up the stack. This is of course exteremely bogus |
|
if (lineReceived[0] == 0) |
|
{ |
|
Console.WriteLine("Warning - received null first character. Dropping."); |
|
lineReceived = lineReceived.Substring(1); |
|
} |
|
|
|
//Console.WriteLine("Processing Update: " + lineReceived); |
|
|
|
if (LineOfDataReceived != null) |
|
LineOfDataReceived(lineReceived); |
|
} |
|
|
|
void bgWorker_DoWork(object sender, DoWorkEventArgs e) |
|
{ |
|
while (!_bgWorker.CancellationPending) |
|
{ |
|
try |
|
{ |
|
var line = _sp.ReadLine(); |
|
_bgWorker.ReportProgress(0, line); |
|
} |
|
catch(TimeoutException) |
|
{ |
|
// continue |
|
} |
|
catch(System.IO.IOException) // when the port gets killed |
|
{} |
|
catch(ObjectDisposedException) |
|
{} |
|
} |
|
} |
|
|
|
private string Error { get; set;} |
|
|
|
|
|
public bool IsConnected |
|
{ |
|
get { return _sp.IsOpen; } |
|
} |
|
|
|
|
|
|
|
public IEnumerable<string> ListCommPorts() |
|
{ |
|
return SerialPort.GetPortNames(); |
|
} |
|
|
|
public void Send(string send) |
|
{ |
|
if (_sp.IsOpen) |
|
_sp.Write(send); |
|
} |
|
} |
|
}
|
|
|