Serial Port Management Features?

Just throwing a few ideas out there about Serial Ports. Do you think it will ever be possible to Open, Close, or Configure a Serial Port from inside a Running Flow?

I am thinking I should be able to Modify that "Configuration Node" of a Serial Port to Change Baud, Stop, Parity.
I guess I will try to implement the work around.

End Goal- is to eventually figure out how to have a serial port automatically change its settings(using a few reconfigured Serial Port Templates), until "human readable" chars are found. I work with a lot of Scales, Thickness Gauges, Instruments which all have Serial Ports. End users will be moving equipment, unhooking, re-hooking cables, potentially.

I might just have to do this in Python until higher level management features are added in Node-Red(Open Port, Close Port, Configure Port).

1 Like

Sounds a bit too specialised for general usage. What happens when you plug into a device that expects to be talked to first ? does it send random characters to provoke a response ? How can it guess what to send ? - by the time it has guessed what to say you could have looked up the baud rate in the manual :slight_smile:

I guess most things do use 8 bits, 1 stop and no parity... but are you going to iterate over all those combos as well ?

This is also going to be highly platform specific. Certainly Windows and Linux have very different ways of managing serial ports.

a little off-topic, but I recently found that a fresh usb-tty in RPi using NR serial port is NOT binary transparent without adjusting settings in stty outside of NR. had me going for more than a few hours suspecting my firmware at the other end of the link - until I notices that 0x11 & 0x12 incoming seemed primarily affected.

Hi Guys,
Thanks for the feedback. Ignore my End Goal for a second. Do you foresee any reasons of not being able to Open or Close a Serial Port from a Running Flow? If a Serial Port is Closed you should be able to update the Configuration Node of Serial Port.

I am not sure how Node Red currently Auto Opens Serial Ports. Or the fundamentals behind Configuration Nodes, maybe they can only be changed and require a redeploy?

In the future could it be possible to Open, Close and Configure a Closed Port from inside the Flow?

1 Like

This is really a question about how serial ports work. As I say, this is different depending on the platform. After the platform differences, it is then down to the way that Node.JS uses the ports. You may have seen after a Node.JS update that the serial port module has to be rebuilt. That's because it is a platform dependent binary that has to be recompiled.

In general, serial port devices can only be opened by a single process, even opening them as read-only locks them. So unless Node.JS has a way to release the ports (I suspect it does but I'm not an expert), Node-RED won't be able to either.

1 Like

In theory it could be possible for the config node to close and restart the port. However as config nodes have no dynamic input there is no easy way to set those internal settings. You can use environment variables to set those that are text easily enough - but they only get read when the node is re-deployed.

Also top level nodes (the in and out). The In from the serial port node has no input wire so there is no concept of being able to change its configuration dynamically, so realistically I think this would be a new sort of serial node.

2 Likes

Is anyone up for working together to write this node?

I have no experience writing nodes but love node-red for its IOT applications and would love to find a way to help create something useful to the community.

Another aspect to this general question is the need to control the serial device "pins" such as DTR and RTS and to read the CTS state at will. This is a VERY common usage for serial ports in Mil Std. modems in particular. The modem is "keyed" by raising RTS. CTS is used as a hardware flow control when buffering data to the modem. DTR is commonly used to enable/disable a modem's receiver as well.

I see that the configuration node for serial in and out nodes can set some of these pins as it notes "Permanently", which is a bit nebulous, but implies only for logic uses outside of the serial port itself. Using the pins for their intended purposes would be a great help.

It is indeed possible to do what you want within node red, it took a bit of messing around, and it's not perfect but it does what you want, with the added bonus of opening and closing the serial port automatically.

You have to inject the msg.topic = "flows";

[{"id":"ca9de98e.484218","type":"function","z":"116f2e1.eb364d2","name":"Modify serial out settings","func":"//this loads the entire config (not just the current flow)\n//as we are looking for a global config node, which is not on \n//a flow. It then walks through all the nodes until it finds\n//the correct node matching the sn, then if modifies the relevant\n//field and posts the entire flow back again, \n//the post causes Node-red to redeploy the flows. \n\nvar fn = msg.payload;\nvar sn = 'b468106b.27ca7';\nmsg.headers = {\n    'Content-Type': 'application/json',\n    'Accept' : 'application/json'};\nmsg.url = \"http://localhost:1880/\"+ msg.topic;\nmsg.method =\"POST\";\nfor(var i=0;i<fn.length;i++) {\n    if (fn[i].id == sn) {\n        //fn[i].parity = \"odd\";\n        fn[i].parity     = flow.get(\"runtimes.parity\");\n        fn[i].serialbaud = flow.get(\"runtimes.baudrate\");\n        return msg;\n    }\n        \n}\n\nreturn msg;","outputs":1,"noerr":0,"x":1130,"y":1360,"wires":[["a8c09712.6f13a8"]]},{"id":"a8c09712.6f13a8","type":"http request","z":"116f2e1.eb364d2","name":"Save flow","method":"use","ret":"txt","paytoqs":false,"url":"","tls":"","persist":false,"proxy":"","authType":"","x":1360,"y":1360,"wires":[["10b60464.bb3f7c"]]},{"id":"e8a215c9.228658","type":"http request","z":"116f2e1.eb364d2","name":"Get {{{topic}}}","method":"GET","ret":"obj","paytoqs":false,"url":"http://localhost:1880/{{{topic}}}","tls":"","persist":false,"proxy":"","authType":"basic","x":860,"y":1360,"wires":[["ca9de98e.484218"]]},{"id":"10b60464.bb3f7c","type":"debug","z":"116f2e1.eb364d2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1530,"y":1360,"wires":[]},{"id":"690fa5ed.f8de8c","type":"comment","z":"116f2e1.eb364d2","name":"Modify Serial port settings","info":"[https://flows.nodered.org/flow/6fe183c197b3464a1fe4d89744e068ff]()\n\nA Flow which modifies settings of another\nnode via the Admin API of NR (HTTP)\n\n1. You need to setup the flow id in the injection flow.\n2. Set the Topic accordingly. You can get the flow id by typing the following in the editor on the javascript console\n ```\nRED.workspaces.active()\n\"4c8b228.985ecdc\"\n```\n3. You need the id of the tcp out node as well and change it in the function node\n4. After deployment the tcp out node settings will be changed on click on inject in the editor\n \n\n\n\n","x":1030,"y":1280,"wires":[]}]

It is possible to close the serial port from the flow. you have to modify the 25-serial.js file.

All credit to the person in the link that showed how to change the baudrate on the fly (this is a part of the serial.js file) and it doesn't need the port to be closed.

Looking at the api for the serial.js, you have to close the port for making any other changes to the serial port, I had a go at setting the serial port parity, but wasn't successful. I did however manage to close the serial port (it automatically reopens)

    // receives msgs and sends them to the serial port
    function SerialOutNode(n) {
        RED.nodes.createNode(this,n);
        this.serial = n.serial;
        this.serialConfig = RED.nodes.getNode(this.serial);

        if (this.serialConfig) {
            var node = this;
            node.port = serialPool.get(this.serialConfig);

            node.on("input",function(msg) {
//MKB Added to allow dynamic baudrate and parity
                if (msg.hasOwnProperty("baudrate")) {
                        var baud = parseInt(msg.baudrate);
                        if (baud == NaN) {
                                var errmsg = err.toString().replace("Serialport","Serialport "+node.port.serial.path);
                                node.error(errmsg,"Cannot parse baudrate property");
                        } else {
                                node.port.update({baudRate: baud},function(err,res) {
                                        if (err) {
                                                var errmsg = err.toString().replace("Serialport","Serialport "+node.port.serial.path);
                                                node.error(errmsg,msg);
                                        }
                                });
                        }
                }

                if (msg.hasOwnProperty("close")) {
                        node.port.close();

                }

//               if (msg.hasOwnProperty("parity")) {
//                        this.serialConfig.parity = msg.parity;
//                }

//MKB end addition
                if (!msg.hasOwnProperty("payload")) { return; } // do nothing unless we have a payload
                var payload = node.port.encodePayload(msg.payload);
                node.port.write(payload,function(err,res) {
                    if (err) {
                        var errmsg = err.toString().replace("Serialport","Serialport "+node.port.serial.path);
                        node.error(errmsg,msg);
                    }
                });
            });

and also this bit in the serialPool = (function(){

                      },
                        write: function(m,cb) { this.serial.write(m,cb); },
//MKB Added to make baudrate and parity dynamic
                        update: function(m,cb) { this.serial.update(m,cb); },
//End MKB addition
                        enqueue: function(msg,sender,cb) {

I have a system which has serial type barcode readers. It becomes necessary to disconnect Node-RED from the port to allow "ESP" (Microscan Easy Setup Program) to address the device and allow configuration.

So, you see we need to allow the port to be accessed by other clients in order to configure and then connect to the system ... Node-RED is running the operations.

You mention, here in this article, that the port automatically re-connects. This is a feature which I would like to control programmatically for the purpose of re-connecting once the front end is told to "Start" it's function. Does your suggested patch allow for this type of operation?

Thanks,

Serial ports are normally locked when opened and not easily shared. This has already been covered in this thread.

Depending on your platform, there are virtual serial ports that may let you share the port. But whether this works for you is highly dependent on the devices, platform and software.

@TotallyInformation,
Yes, of course, I understand that point. Serial ports are not shared. I don't think I mentioned sharing the serial port...
It is simply the ability to tell the node to disconnect from it. Then allow another software access to the port. That is in the mention of Microscan ESP. It is never my intention to open it while Node-RED "node-red-node-serialport" has control of the port.

The dialog suggests that it can disconnect, but it will re-connect automatically. I guess I was not specific enough to express... Has anyone, can it be allowed to remain disconnected?

TCP nodes have options for them to disconnect with multiple modes. It would be very nice for this to become a feature if it can.