Forum

Rs232 - handshake data

hello,

i’m trying to receive the handshake data from a COM port.

light sensor (lichtschranke) connected over usb adapter.

(edited post)

-CTS
-DCD
-RI
-DSR

how can i read this data in vvvv?
or do you know any software that can redirect these
into udp?

thx

What’s wrong with the RS232 (Devices) Node? It has a Hardwarehandshake flag.

Hey Gab,

thanks for replying.

In a program called Serial Port Monitor i can
see CTS and DSR signals going on and off.

It’s not showing up in vvvv, though.
Should i receive a string if this was working?

The OnData pin also remains silent.

r

can anybody confirm that handshake data is generally working?

sorry for being stubborn - someone’s swinging the soldering iron already to get this working - but reading the CTS and DSR directly in vvvv would be cleaner.

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.

klappt, danke elias!!!

tested with:

  • DSR data-set-ready
  • DCD data-carrier-detect
  • CTS clear-to-send
  • RI ring-indicator

all working.

after one week i have to ask: did you experience any serious issues?

totally worked until a photographer leaned against the light sensor.
i will tell you about it at node.
so, thanks again!