Created
November 11, 2011 17:23
-
-
Save elliotwoods/1358604 to your computer and use it in GitHub Desktop.
Threaded RS232
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region usings | |
using System; | |
using System.ComponentModel.Composition; | |
using System.IO.Ports; | |
using System.Threading; | |
using VVVV.PluginInterfaces.V1; | |
using VVVV.PluginInterfaces.V2; | |
using VVVV.Utils.VColor; | |
using VVVV.Utils.VMath; | |
using VVVV.Core.Logging; | |
#endregion usings | |
namespace VVVV.Nodes | |
{ | |
class SerialInstance : IDisposable | |
{ | |
bool FNeedsSend = true; | |
string FMessageTx = ""; | |
bool FNewReceive = true; | |
string FMessageRx = ""; | |
string FStatus = ""; | |
bool FRunning = false; | |
Thread FThread = null; | |
SerialPort FSerialPort = null; | |
//settings | |
string FPort = ""; | |
int FBaud = 0; | |
public void Dispose() | |
{ | |
Close(); | |
} | |
public void Initialise(string port, int baud) | |
{ | |
if (FPort == port && FBaud == baud) | |
return; | |
Close(); | |
FPort = port; | |
FBaud = baud; | |
Open(); | |
} | |
public void Open() | |
{ | |
try | |
{ | |
FSerialPort = new SerialPort(FPort, FBaud, Parity.None, 8, StopBits.One); | |
FSerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceived); | |
FSerialPort.Open(); | |
FStatus = "Port opened"; | |
} | |
catch | |
{ | |
Close(); | |
FStatus = "Port open failed"; | |
return; | |
} | |
FRunning = true; | |
FThread = new Thread(fnThread); | |
FThread.Start(); | |
} | |
public void Send(string message) | |
{ | |
FMessageTx = message; | |
FNeedsSend = true; | |
} | |
public string Receive() | |
{ | |
if (FNewReceive) | |
{ | |
FNewReceive = false; | |
return FMessageRx; | |
} else | |
return ""; | |
} | |
public bool IsOpen | |
{ | |
get | |
{ | |
return FSerialPort.IsOpen && FRunning; | |
} | |
} | |
public string Status | |
{ | |
get | |
{ | |
return FStatus; | |
} | |
} | |
private void DataReceived(object sender, SerialDataReceivedEventArgs e) | |
{ | |
FStatus = "Data received"; | |
SerialPort sp = (SerialPort)sender; | |
if (!FNewReceive) | |
FMessageRx = sp.ReadExisting(); | |
else | |
FMessageRx = FMessageRx + sp.ReadExisting(); | |
} | |
private void fnThread() | |
{ | |
while (FRunning) | |
{ | |
if (FNeedsSend) | |
{ | |
FSerialPort.Write(FMessageTx); | |
FNeedsSend = false; | |
} | |
Thread.Sleep(1); | |
} | |
} | |
void Close() | |
{ | |
if (!FRunning) | |
return; | |
FRunning = false; | |
FThread.Join(100); | |
FSerialPort.Close(); | |
FSerialPort.Dispose(); | |
} | |
} | |
#region PluginInfo | |
[PluginInfo(Name = "SerialPort", Category = "Devices", Version = "Threaded", Help = "Send and receive data over the serial port in a seperate thread per port", Tags = "")] | |
#endregion PluginInfo | |
public class ThreadedDevicesRS232Node : IPluginEvaluate, IDisposable | |
{ | |
#region fields & pins | |
[Input("Input", DefaultString = "hello c#")] | |
ISpread<string> FInput; | |
[Input("Port", DefaultString = "COM1")] | |
ISpread<string> FPort; | |
[Input("Baud", DefaultValue = 115200)] | |
ISpread<int> FBaud; | |
[Input("Send", IsBang = true)] | |
ISpread<bool> FSend; | |
[Output("Output")] | |
ISpread<string> FOutput; | |
[Output("Open")] | |
ISpread<bool> FOpen; | |
[Output("Status")] | |
ISpread<string> FStatus; | |
[Import()] | |
ILogger FLogger; | |
Spread<SerialInstance> FInstances = new Spread<SerialInstance>(0); | |
#endregion fields & pins | |
public void Dispose() | |
{ | |
FLogger.Log(LogType.Debug, "Disposing SerialPort node"); | |
for (int i=0; i<FInstances.SliceCount; i++) | |
{ | |
FInstances[i].Dispose(); | |
} | |
} | |
//called when data for any output pin is requested | |
public void Evaluate(int SpreadMax) | |
{ | |
FOutput.SliceCount = SpreadMax; | |
FOpen.SliceCount = SpreadMax; | |
FStatus.SliceCount = SpreadMax; | |
Resize(SpreadMax); | |
for (int i=0; i<SpreadMax; i++) | |
{ | |
if (FSend[i]) | |
{ | |
if (!FInstances[i].IsOpen) | |
FInstances[i].Open(); | |
FInstances[i].Send(FInput[i]); | |
} | |
FOutput[i] = FInstances[i].Receive(); | |
FOpen[i] = FInstances[i].IsOpen; | |
FStatus[i] = FInstances[i].Status; | |
} | |
//FLogger.Log(LogType.Debug, "Logging to Renderer (TTY)"); | |
} | |
private void Resize(int count) | |
{ | |
FInstances.SliceCount = count; | |
for (int i=0; i<count; i++) | |
{ | |
if (FInstances[i] == null) | |
FInstances[i] = new SerialInstance(); | |
FInstances[i].Initialise(FPort[i], FBaud[i]); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment