Reading from serial. Works in sample-js file, but when running in node-red serial port gets closed

Hallo,

I try to read data from a serial port of raspberry PI. I have connected two PIs via serial Port. With "node serialtest.js" I get a new line for each character I send to node.js

With node-red this is my testflow. I now my node sends no messages, so debug window stays empty.
[{"id":"cf7998f7.96c67","type":"debug","z":"b451655f.5db818","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":890,"y":100,"wires":[]},{"id":"4339883f.6904c","type":"inject","z":"b451655f.5db818","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":360,"y":100,"wires":[["e7fdda3c.73eee8"]]},{"id":"e7fdda3c.73eee8","type":"testnode","z":"b451655f.5db818","name":"testnode","serialport":"/dev/serial0","x":620,"y":100,"wires":[["cf7998f7.96c67"]]}]

With every click on the inject-node-button it writes "test". I can see that on the terminal receiver. As soon as I type only one character in the terminal, which now should receive node-red I get a "Port closed" log entry in node red. Whats wrong here? Why isn't it running in Node-Red whereas it runs in a demo file?

Please remove the ".txt" from the files, then it has the correct file ending, otherwise I couldn't upload.

serialtest.js.txt (887 Bytes) testnode.html.txt (1.0 KB) testnode.js.txt (1.6 KB) package.json (457 Bytes)

It looks like you are writing your own serial request node (but I dont see where you are handling the serial input/response)

What is wrong with the serial request node from node-red-serialport

In this example you're right. Therefore I could use the nodes from node-red-serialport. However there will be more logic / magic values for a specific device. To to that with the node-red-serialport nodes you need a lot of nodes and makes the flow quite confusing.

I try to handle the serial input in

node.port.on('readable', function () {
            received = node.port.read()
            receivedData = Buffer.concat([receivedData,received])
            console.log('Data:', received)
            if(receivedData.length > 8)
            {
              console.log('total:', receivedData)
              receivedData=Buffer.alloc(0)
                 
            }

        })

However this code is never called, because when it is time to call it, serial port gets closed.

ok, i understand - but (potentially) you could still write your node(s) to work with the existing serial node?

For example, a future realisation might be to pipe your data over TCP or UDP or MQTT or ????. However, if you build the serial part into your node, then decide it might be a good idea to also work over TCP then you will have to built in all the TCP handling etc.

Are you sure there isn't a solution that permits you to implement your node in a way that works nicely with the existing Serial nodes (and keep in mind a future version that might work with the the TCP / UDP nodes)

As for your issue, without knowing (or reading / learning) the serial node code I cant say why your port is getting closed. Perhaps you should be using port.on('data', ...?

ok, i understand - but (potentially) you could still write your node(s) to work with the existing serial node?

When I see this correctly then I need two build in serial nodes (in and out) and my custom node. So it would be three nodes and serial in and out have to be configured to the same port. I'm writing a node to have it all in one, where you configure it at one place.

Are you sure there isn't a solution that permits you to implement your node in a way that works nicely with the existing Serial nodes (and keep in mind a future version that might work with the the TCP / UDP nodes)

I can't find an easy solution with existing nodes. I want to distribute this also as a custom node via the platette manger. When using the existing nodes, I think I can only provide the flow and people won't find it via the palette manager.

As for your issue, without knowing (or reading / learning) the serial node code I cant say why your port is getting closed. Perhaps you should be using port.on('data', ... ?

Thanks for the hint. I've tried it with data (looks even prettier), but still the same error. Serial port gets closed as soon as the first character is receveived, when using the code in Node-Red. Using it directly with Node it works. So it seems that there is some speciality in Node-Red I have to pay attention.

You can include examples with your node if you went down that route...

image

I took a look at the official node red serial node implementation. https://github.com/node-red/node-red-nodes/blob/master/io/serialport/25-serial.js
There is the same package used as I do. Also node.port.on('data', function (data) { is used. They use a serial pool with a configuration node.
I want to do it without a configuration node, because when you share the flow, you have to configure the node. I want to avoid this.

Hope somebody can help me to get this running. As I said running this code solely in node.js works, so it must be something NodeRed specific.

not sure I understand that - If you share a flow that is already configured then it will be configured at the other end - assuming they have the same serial port numbering as you.

But yes you don't need a configuration node as long as you can only have one of your nodes talking to one serial port at a time.

Yes, you're right. Only one node talking to serial iis perfectly ok.

Hope somebody finds out whats wrong with my node, why serial input won't work.

Not clear what pi you are using, however have a look at this.

@edje11 Since it works in node.js standalone script without the node-red environment and I can even send from node red over serial, it can't be a configuring issue.

Well the node-red-node-serialport code does work - so I guess you need to study that some more. It's not really doing anything special - just opening the port - then doing the .on("data" ... then sending what is received.

The code of node-red-node-serialport is much more complex, because it has, lets call it connection pooling, so you can use the same serial port in multiple nodes and thus has its own configuration node. I want to avoid the configuration node.

All it is doing is creating a connection and then sharing that object - you still need to do the same create the connection - but you can do that in your one node - then just use it rather than have to refer to to shared one. In fact all it is doing is node.port = serialPool.get(this.serialConfig); where serialConfig is the shared config - all you need to do is declare that locally instead of in a config node.