with new datatype raw coming in i started to work on a new rs232 node once, as the native one is not spreadable and the one in the addonpack deals with strings. had a quick look at the code which was lying around and added those flags you requested. tell me if it works.
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Diagnostics;
using System.IO;
using System.ComponentModel.Composition;
using System.Linq;
using VVVV.PluginInterfaces.V1;
using VVVV.PluginInterfaces.V2;
namespace VVVV.Nodes
{
[PluginInfo(Name = "RS232", Category = "Devices", Version = "Temporary", AutoEvaluate = true)](PluginInfo(Name = "RS232", Category = "Devices", Version = "Temporary", AutoEvaluate = true))
public class Rs232Node : IDisposable, IPluginEvaluate, IPartImportsSatisfiedNotification
{
const string COM_PORT_ENUM_NAME = "Rs232Node.ComPort";
[Input("Input")](Input("Input"))
public ISpread<Stream> DataIn;
[Input("Do Send", IsBang = true)](Input("Do Send", IsBang = true))
public ISpread<bool> DoSendIn;
[Input("Baudrate", MinValue = 9600, MaxValue = int.MaxValue, DefaultValue = 9600)](Input("Baudrate", MinValue = 9600, MaxValue = int.MaxValue, DefaultValue = 9600))
public ISpread<int> BaudRateIn;
[Input("Data Bits", MinValue = 5, MaxValue = 8, DefaultValue = 8)](Input("Data Bits", MinValue = 5, MaxValue = 8, DefaultValue = 8))
public ISpread<int> DataBitsIn;
[Input("Stop Bits", DefaultEnumEntry = "One")](Input("Stop Bits", DefaultEnumEntry = "One"))
public ISpread<StopBits> StopBitsIn;
[Input("Parity")](Input("Parity"))
public ISpread<Parity> ParityIn;
[Input("Handshake")](Input("Handshake"))
public ISpread<Handshake> HandshakeIn;
[Input("DTR Enable")](Input("DTR Enable"))
public ISpread<bool> DtrEnableIn;
[Input("RTS Enable")](Input("RTS Enable"))
public ISpread<bool> RtsEnableIn;
[Input("Break State")](Input("Break State"))
public ISpread<bool> BreakStateIn;
[Input("Enabled")](Input("Enabled"))
public ISpread<bool> EnabledIn;
[Input("Port Name", EnumName = COM_PORT_ENUM_NAME)](Input("Port Name", EnumName = COM_PORT_ENUM_NAME))
public ISpread<EnumEntry> ComPortIn;
[Output("Output")](Output("Output"))
public ISpread<Stream> DataOut;
[Output("DSR State")](Output("DSR State"))
public ISpread<bool> DsrStateOut;
[Output("DCD State")](Output("DCD State"))
public ISpread<bool> DcdStateOut;
[Output("CTS State")](Output("CTS State"))
public ISpread<bool> CtsStateOut;
[Output("RI State")](Output("RI State"))
public ISpread<bool> RiStateOut;
[Output("Break State")](Output("Break State"))
public ISpread<bool> BreakStateOut;
[Output("On Data", IsBang = true)](Output("On Data", IsBang = true))
public ISpread<bool> OnDataOut;
[Output("Connected")](Output("Connected"))
public ISpread<bool> ConnectedOut;
private readonly Spread<SerialPort> FPorts = new Spread<SerialPort>();
static Rs232Node()
{
var portNames = SerialPort.GetPortNames()
.Where(n => n.StartsWith("com", StringComparison.InvariantCultureIgnoreCase))
.ToArray();
EnumManager.UpdateEnum(COM_PORT_ENUM_NAME, portNames.Length > 0 ? portNames[0](0) : string.Empty, portNames);
}
public void OnImportsSatisfied()
{
DataOut.SliceCount = 0;
}
public void Dispose()
{
FPorts.ResizeAndDispose(0);
}
public void Evaluate(int spreadMax)
{
DcdStateOut.SliceCount = spreadMax;
CtsStateOut.SliceCount = spreadMax;
DsrStateOut.SliceCount = spreadMax;
RiStateOut.SliceCount = spreadMax;
BreakStateOut.SliceCount = spreadMax;
FPorts.Resize(spreadMax, CreatePort, DestroyPort);
DataOut.ResizeAndDispose(spreadMax, () => new MemoryStream());
for (int i = 0; i < spreadMax; i++)
{
var port = FPorts[i](i);
// Configure the port
var portName = ComPortIn[i](i).Name;
if (port.PortName != portName)
port.PortName = portName;
if (port.BaudRate != BaudRateIn[i](i))
port.BaudRate = BaudRateIn[i](i);
if (port.DataBits != DataBitsIn[i](i))
port.DataBits = DataBitsIn[i](i);
if (port.StopBits != StopBitsIn[i](i))
port.StopBits = StopBitsIn[i](i);
if (port.Parity != ParityIn[i](i))
port.Parity = ParityIn[i](i);
if (port.Handshake != HandshakeIn[i](i))
port.Handshake = HandshakeIn[i](i);
if (port.DtrEnable != DtrEnableIn[i](i))
port.DtrEnable = DtrEnableIn[i](i);
if (port.RtsEnable != RtsEnableIn[i](i))
port.RtsEnable = RtsEnableIn[i](i);
// Get the in and output streams
var dataIn = DataIn[i](i);
var dataOut = DataOut[i](i);
// Set stream positions back to the beginning
dataIn.Seek(0, SeekOrigin.Begin);
dataOut.Seek(0, SeekOrigin.Begin);
if (EnabledIn[i](i))
{
// Open the port
if (!port.IsOpen)
{
port.Open();
SetStates(i);
}
// Set the break state
port.BreakState = BreakStateIn[i](i);
// Write data to the port
var totalBytesToWrite = dataIn.Length;
if (totalBytesToWrite > 0 && DoSendIn[i](i))
{
var buffer = new byte[1024](1024);
while (totalBytesToWrite > 0)
{
var bytesToWrite = (int)Math.Min(buffer.Length, totalBytesToWrite);
var bytesRead = dataIn.Read(buffer, 0, bytesToWrite);
port.Write(buffer, 0, bytesRead);
totalBytesToWrite -= bytesRead;
}
}
// Read data from the port
var totalBytesToRead = port.BytesToRead;
if (totalBytesToRead > 0)
{
dataOut.SetLength(totalBytesToRead);
var buffer = new byte[1024](1024);
while (totalBytesToRead > 0)
{
var bytesToRead = Math.Min(buffer.Length, totalBytesToRead);
var bytesRead = port.Read(buffer, 0, bytesToRead);
dataOut.Write(buffer, 0, bytesRead);
totalBytesToRead -= bytesRead;
}
// Marks the pin as changed
DataOut[i](i) = dataOut;
// Set the OnData flag
OnDataOut[i](i) = true;
}
else
{
// Clear output
if (dataOut.Length > 0)
{
dataOut.SetLength(0);
// Marks the pin as changed
DataOut[i](i) = dataOut;
// Reset the OnData flag
OnDataOut[i](i) = false;
}
}
}
else
{
// Close the port
if (port.IsOpen)
{
port.Close();
UnsetStates(i);
}
// Clear output
if (dataOut.Length > 0)
{
dataOut.SetLength(0);
// Marks the pin as changed
DataOut[i](i) = dataOut;
// Reset the OnData flag
OnDataOut[i](i) = false;
}
}
// Read connection state
ConnectedOut[i](i) = port.IsOpen;
}
}
SerialPort CreatePort(int slice)
{
var port = new SerialPort();
port.PinChanged += HandlePinChanged;
return port;
}
void DestroyPort(SerialPort port)
{
port.PinChanged -= HandlePinChanged;
port.Dispose();
}
void SetStates(int slice)
{
var port = FPorts[slice](slice);
BreakStateOut[slice](slice) = port.BreakState;
DcdStateOut[slice](slice) = port.CDHolding;
CtsStateOut[slice](slice) = port.CtsHolding;
DsrStateOut[slice](slice) = port.DsrHolding;
RiStateOut[slice](slice) = false;
}
void UnsetStates(int slice)
{
BreakStateOut[slice](slice) = false;
DcdStateOut[slice](slice) = false;
CtsStateOut[slice](slice) = false;
DsrStateOut[slice](slice) = false;
RiStateOut[slice](slice) = false;
}
void HandlePinChanged(object sender, SerialPinChangedEventArgs e)
{
var port = sender as SerialPort;
var slice = FPorts.IndexOf(port);
switch (e.EventType)
{
case SerialPinChange.Break:
BreakStateOut[slice](slice) = !BreakStateOut[slice](slice);
break;
case SerialPinChange.CDChanged:
DcdStateOut[slice](slice) = !DcdStateOut[slice](slice);
break;
case SerialPinChange.CtsChanged:
CtsStateOut[slice](slice) = !CtsStateOut[slice](slice);
break;
case SerialPinChange.DsrChanged:
DsrStateOut[slice](slice) = !DsrStateOut[slice](slice);
break;
case SerialPinChange.Ring:
RiStateOut[slice](slice) = !RiStateOut[slice](slice);
break;
default:
break;
}
}
}
}
you should be able to clone the dynamic plugin template and simply paste this code in there. hope it works, didn’t test it that way.