Skip to content

Instantly share code, notes, and snippets.

@elliotwoods
Created November 11, 2011 17:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elliotwoods/1358604 to your computer and use it in GitHub Desktop.
Save elliotwoods/1358604 to your computer and use it in GitHub Desktop.
Threaded RS232
#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