Modbus communication done right in Node-Red

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to a new video in my home automation series and today I want to talk about how you could use a mode bus on the Node red and the reason I'm making this video because I've been using modbus for a very very long time and probably you have seen uh quite a few projects which is using modbus because I'm talking to my home automation PLC over modbus and I think I've been using it wrong and I had all sorts of issues like connection issues and reconnecting issues and I thought there is something wrong with the you know the modbus component with the node red but then it turns out that because I was using it for such a long time probably you know from a very early version I got used to a way of you know using the modbus nodes in a specific way whereas I was pointed out there has been a lot of development and made in terms of the reliability you know fixing connection issues and they are all related to like a different set of notes that you should use if you have problems like that so I thought because it was uh giving us so many problems in our past I'm just going to cover it in a video so maybe you can learn how to do it right before I start going into it I just want to show you the the modbus component that I'm using actually if I bring up the palette then so this is it a node-red country modbus and it has a lot of different stuff in it and um you know in the early version I think there was you know maybe that was just a modbus read and a mode bus ride and uh there was like a queue manager and like um and of course the connection node so there has been a lot added here and because I had this earlier um knowledge of how I used to use modbus I kept using this modbus read component and if you just hover over it then even the you know the documentation says that this modbus really is okay to use if you have just a few connections but then if you have you have a device where you want to do a lot of different queries then you should really use the flex getter and the flex right node because most of the the work and enhancements and you know code stabilization has gone into the flex nodes and I didn't really know about this so I was trying to just figure out what is going wrong with my modbus read whereas I should have just dished it and used the flex againter instead so you can see the the flex scatter here or the flex right node so this video is about how you you use these two nodes I'm going to show you two different methods the first method is you can see here so this is how I communicate with my PLC and it has a lot of different inputs because I'm querying coils and registers in different quantities and in different addresses with different intervals so there is a lot that the the model bus node needs to do to queue those messages and you know make sure that let's say a new request is not sent before the last one is processed but then I have um another one where I'm communicating with a touch panel where it's much simpler because I'm just only querying a single um range of Regis no I think I do coils and maybe I write something so that's uh that's simpler but even for that I use the uh the flex nodes and back in the day when we used the old modbus read then you would specify the you know the device that you want to like the PLC that you want to you know that this is the mode by slave that you want to communicate to and then you specify what is the mode bus function and then the address the quantity and the pull rate so with the flex node it is slightly different because in the flex node you have to specify this in the message that you send in so if I look at this one this is how a the input message the flex node should look like so it has the FC so this the this is the mode bus function the unit ID the addresses and the quantity so exactly what you would specify on the old node but here you have to send it in a message and this is why it is flex because well you don't specify it on the Node level because on the Node itself you just only specified the the slave that you want to communicate with all the instructions are coming in from the um from the input in the message and uh and of course this means that you can just you know use multiple requests and use a single Flex scatter node to get this information so let me just show you the the easier example which is here not here uh which is here yeah so as I said I have a touch panel and I want to get I think I just two coils so the first two coils so I need to create a message which has uh you know fc1 because it's coils the unit id1 address zero and the quantity is two so I'm just getting these information and um and here the value is irrelevant because I'm getting data and I want to query this device very frequently actually 500 milliseconds so in the inject node I can only do one second so the information goes in and basically the second one gets a 500 millisecond delay and it goes in so this is how I get uh two requests at a second and this is connected via TCP so I'm not too worried about like you know bandwidth and and whether it will be able to handle this request and the you know I process the information and then um at some point I also need to write something to it so again I'm using a flex right again I just only specify what the client is uh sorry the modbus current is yes and um I also prepare a message which is very similar to the getter message so fc5 is uh reset a single coil unit one address one quantity one and the value is the well because it's a call it's a true or false but if this will be a register then that would be the number that needs to be written into the register so that's how you specify a write request obviously the difference between the read and write request is the modbus function is different and that's the easy way so as long as you have let's say uh I don't I can't really tell whether it's like you know one or two requests but as long as you have a like a like a simpler uh query where you are only you know reading a couple of things from the same device and maybe very occasionally write something to it then you can just use one uh Flex gather node and then one Flex write node and the mode bus itself is going to take care of it so that's the simpler approach but then I thought that if for my main PLC I'm going to use a much um complicated approach and basically I'm going to implement my own queuing and this is what this function node does and the idea behind it is that I have a lot of different requests coming in as you can see I'm reading registers here so here I'm reading registers from address thousand I read 20 and I read another I think it's 20 from here from address 1200 and another 20 from address 1300 and I'm also so these are temperatures and these are my blind positions so from register 1500 again 20. and there are some other ways I can also input from other parts of the floor rather flow so these are all going in so these are the requests and this function node is going to queue these messages and then it's going to send them out and then based on the mode bus function I know whether that's a getter or a write request so it would redirect the message on to either to the getter node or to the flex right node and then um once um I mean if I write something I don't really care what comes back from the mode bus I always you know assume that it was successfully updated so I don't really process the output but for the getter I obviously process the output here and because I'm using this single getter for all these different queries what I do probably we have seen it before that I always specify as a certain topic and then obviously that topic comes through all these nodes so here I know that the message that I've I got out of the flex getter whether that is you know this type that type or you know one of these types here and then I can send those messages to the right places where it gets processed so that's uh that will take care of the you know actual processing the data that we read from the device but then as you can see on the first Port of both the flag scatter and the flex right I also send this to this um change node which assess the topic to next and that feeds back to the function node and basically it is saying to the function node that uh the uh we got a response from the client so we can send the next message and that's the that's the whole queuing mechanism so it sends one message out and then once there is any response then it says okay we got a response so we can send the next one so that will take care of the queuing regardless whether it's uh you know it's a get or the right request and also this will make sure that there is no get and write request set at the same time that's the main idea and then it does a couple of other things as well basically two more let's say three main things um there is a an update in check node which has a topic of update and that just does the it just does basic housekeeping so you can see here that it will update a message saying what was how many seconds ago the last message was sent sorry how many seconds ago the last response was received um if it's a really long time then there is like an internal status management so it will say that the device is offline or online depending on how long that time was and all this information is sent out on the last node so you can use it for you know put it on the dashboard or you know include it in the messaging or logging or something like that the other other point of this whole queuing mechanism is that well at least in my implementation whenever I either read something or write something and if the request is not it doesn't go through but then another request comes in because let's say I want to read something every 10 seconds or two seconds I don't really care what was the previous request because the the last request always overrides the uh the previous one so I don't really keep the most recent request uh for each of the um each type of the queries and this is why the message topic is important because I have a topic which says you know query the temperatures or the blind positions so if I get a second you know query temperature request um well I just keep that I don't need the previous one because well essentially it's always going to be the same anyway so this is what I use the topic for that for each topic the the function node is only going to remember the last setting and actually if you well this oh no story not star flows so this um functional is really fast or this device is really fast so we are not going to really see much but this is where the Q um that's the queue so this is where all the messages are stored and as I said it's you know TCP so as long as the requests come through it is sent immediately so we never see anything actually queuing up here but if you would see then that that's where you will see the messages so the queue is never going to be huge it's always going to be like um in my case it's like five or six because I have five or six different type of carries and everything whenever a new one comes in it will just override the the previous one and then you can always see whenever a read request gets sent through or the right request gets sent through so you can see that it just gets queued up and well it won't get queued up because the the client is faster than how fast the messages are coming in so that's uh that's one thing so I don't keep history I just always keep the the latest version of the message and the last functionality here what you can also see uh here in the um this variable or context value which is called last message is um let's say you send out a request but the client is already offline then you are never going to get a response saying that I have processed a request but then when the device comes back online it won't know anything about the request because it was offline so what this function also does is that it will remember what the last message was and if there was no response let's say in 10 seconds it's going to send it send it again so the last message would it would just keep trying for 10 SEC every 10 seconds so again let's say the the client is disconnected or the power is gone uh node red would just keep sending the last message for every every 10 seconds and then it's also going to just count how long it was since the last communication and if it goes beyond like let's say two minutes it would just send a message that the device is definitely offline it's not responding for the last two minutes but it will just keep trying sending the last message every 10 seconds and then you know once the once the client is back online it will in the in the next 10 seconds it would get the last message again a process it responds then the whole thing with this uh you know with this function node and the loopback is going to start again and um it would just pick up where it left and it is definitely working because I had a small power outage I think this week and I also had some you know smaller network issues when I think my ISP was updating the router and whenever this happens the my internet connection goes away for like a two minutes but then it automatically comes back and the communication started you know flowing between node red and the client as well so but it is so I'm saying that this method is definitely working with this very complicated setup so let me show you how it works because I have a test flow here it is this is exact almost exactly the same as the one above this is an earlier version of the code which doesn't have the resend implemented which is good because I think it would just uh you know cause issues here but if we go into the debugging so you can see that I also have the everyone second update here and that would just um that we just keep sending out these messages like um you know the let me stop let's look at let's look at this one so the um second since the last update was this and the last update you you have a human readable format and you have a stage so that's 99 is offline and one is online so that's the message that the you know the device is offline now and here you can also see the in the status and then you can see it's it's offline so it is red and we have zero messages in the queue so that's fine so I just reset this node and then well we can see that we have zero messages in the queue so if I send my first request in then it has been sent out almost immediately so we didn't see anything here but you can see that I have also simulated this loopback so after five second delay we have a loopback so the counter has reset and if I send in another request it gets sent out immediately and now the delay is working so and then you know once we have the feedback then the counter resets and you can also see that oh that was ah let me just do this one okay and then now we can see that the request was sent out and because this was a read request it comes out of the first port and if I send out a write request then it gets sent out on the second Fort because as I said the first one is all the getter request and the second one is all the write requests and if I want to yeah and if I restart this then you would see that uh I mean that state is now one because the device is online and the last message was nine seconds ago so you can use this information to you know create your own triggers uh uh either on the state change and whenever the state changes there is an extra field which is set to True which I think it's called State change or something similar we are going to see in the documentation and I also want to show you the the context so now if you look at the uh it remembers when the last update was received and then the queue is empty and sent is false so nothing is sent at the moment because we have received the response for the last message and if I do and if I break the connection here let me just do this uh and refresh so if I send the first request in the request gets sent out so there is nothing in the queue and we have a a tag sorry a variable which says that we have a message that has been sent out but we haven't received the confirmation yet so if I send in another request then nothing really happens it just gets queued because it's waiting for the response so now we have one message in the queue that's the we test as the first one if I send another one then now we have two messages in the queue um so read test one read test two if I send the right request then we have one more message yeah with the topic right and then if I see send the read request again then we still only have three because uh we already had a read request and if you can see that uh well it has actually gone to the to the end of the queue but I guess you get the idea and I can uh also simulate the getting a response by sending this next topic manually so now the uh the light the latest one was sent out from a queue so now we only have two and now we have only one and now we have zero because we sent out the last message so that's how it works let's see let me just reconnect this one so that's the uh this is how I can simulate you the the node and if you are interested I'm also going to quickly take you through the the code in the function node so we have a couple of variables in the beginning I'm going to talk about these in a couple of seconds these are basically control how the the the logic Works within the flow and first we are checking if there is a topic because if there is no topic you get a message that the topic is missing as I said it is important the topic is important for the for the rest of the code in the flow and uh and then we get you know the values from the context if you don't for example if the queue is not defined then we just create an empty queue an empty array and then we have this big switch node which uh looks at the topic and then it's going to behave based on you know what is in the topic so if the topic is update which is that every second update then you know it just calculates how much time has spent from the last update the current time and then it it generates this human readable format of how many days hours minutes seconds being passed since the last update and this is where I also implemented the resend logic so if the resend is enabled which is up here it checks whether the time since the last send uh module modulus the resending to what is zero so let's say every 10 seconds and then it's just going to send it takes the last uh the last message from the last message variable and then it's going to send it out yeah it's here and and this is the piece of code which knows whether it needs to be sent out or the first on the second Port because if the mode bus function is one two three or four that's that is a read request so it goes out on the first node and if it's anything else it goes on it goes out on the second sorry not node but port um so that this is the resend logic and here I'm also doing the status management so as I said if the status is not zero and we just got a message then it's going to send a message out that the device is now online so you can see that there is a status change variable set to true so you can look at that one if you want a specific message and if the time spent since the last response is greater than offline thresholds then it's going to be another message which says that the device is not transmitting and it says to say just a 99. uh so and that comes out of the uh out on the third port and the next is only used well it has basically that this is the feedback loop yeah I wanted to say that it's only used for testing but no actually this is the same message what the feedback loop loop uses and it just updates the last update and then it sends the false to uh set sets the send to false and then the internal send is set to true because it will get used later there is also a reset function so if you want to just delete everything you can just send in a message via reset topic and it's going to reset and if the topic is anything else and those are the normal requests that are coming in every let's say 10 seconds or two seconds then it just gets added to the queue oh sorry this is where it looks for any existing messages in the queue and if anything is fun then it's going to delete it and then it's just going to add it to the queue and if if we don't have anything if if the send variable is set to false then it means those will be the cases when um the flow just started and this is the first message which is coming in so that can be sent immediately so that's why we are sending the internal send variable to true that you are going to see later so if the send variable is true which means that we just received the next or this is the first message since the node started then we can send the message out so we just pick out the first message from the queue we remove it from the queue and then we send it out and we use the same logic As Above So if the function is one two three four then it's a getter if it's anything else it's a mode bus Flex write message and that's it that's pretty much it it's not that complicated so if you want to use this flow then in the video description you will find a link where you can access this tester flow and what you would need to do is well obviously you find some examples here so you need to replace these with your get or write functions with the correct timing and everything and in the mode bus queue in within the function node you have these variables right on the top of the flow that you can change so if you want the the node to resend the last message every 10 seconds you set it to true and let's say 10 and if you have received a message in the last 10 seconds then then the device is considered as online and if it's no message is received after 300 seconds then so five minutes then it's considered offline so you can play around with these values and by the way if you select the node and you come to this one then wait oh ah the information one I have written oh bloody come on so I have written a documentation for that so you can view the documentation here so it talks about all the function it does you know what is the um incoming payload how it is expected to look like and then the importance of the topic and some of the reserved topics that I talked about and then how you use port one two and three and what is the status or sorry what are the details of the the message that comes out of the third port so these are the um the messages so I knew that you can do I mean even from the past I was aware that you can do documentation because if you go to a function node you can come here and you can do the documentation but um I so far I was only using this to do comments but now I realize that I can use the same sort of formatting that you would use in GitHub so you know one slash is header one two slash is header two and uh these I think this special apostrophe is for code beginning and end of code section so fairly useful so you can look at the documentation if you get stuck as well but going back to the example flow so those are the values that you can modify on the function node and then you replace debug free with a flex scatter you replace debug 4 with a flex right and then out of the flex getter you have to specify your own switch node so you can switch the responses based on topic and here I only you I use the five second delay just for the testing purposes so you can remove this and then you can connect the other one's Queue at the end of the flex scatter and the flex right so just like here so this one goes to the advanced queue and this one goes to the advanced queue node which then goes all the way back to the modbus queue and with that you will implement the same functionality as I just described here I think I'm not going to save this and of course as I said in in here uh the the code is not the latest version but anyway I will I will update this so by the time this gets uploaded I will just copy and paste the latest version uh to the smoothbus function and as I said the the link to all this is going to be in the video description so if you think that this is something that you want to use then of course just download and make the changes that I described or if you think that you your example is uh sorry or your user for modbus client is somewhat easier then you can just use the my example here where you just have a simple you know flag scatter and then you just send the request in and of course here in this particular case I only used a single single request or single type of request but if you have if you are you know creating different ranges or coins and registers as well you can use the same approach even without my function node and then just use a different topic and then at the end of it you can just use again a switch node to you know the direct the the messages based on the topic and you know how you want to process them but again if you are using this simpler method this is not going to have the resend logic so then you are relying on the you know the internal code and um um the internal you know queuing mechanism of the you know the mode blast Flex getter to you know make sure that the messages are getting sent through but again if um if you're not using my function node then your injects node if they are set up to send a request every two or you know 10 seconds they would just you know keep hitting the uh the flex gallon anyway and I think it does an internal queuing uh as well so it would just keep piling up all the messages but as I said in the beginning I don't see a point you know keeping or piling up all the get requests because it's going to be the same request so it doesn't matter if you are going to you know request the you know reading the calls or the registers once or 100 times because the the response is going to be the same so this is why I said there's no point keeping a history only just keep the last request for every single type I hope it all made sense for you and I also hope that you find this video useful but that will be all for today thanks for watching and hopefully see you next video
Info
Channel: Csongor Varga
Views: 12,678
Rating: undefined out of 5
Keywords: node-red, home automation, smart home, queueing, queue, modbus, communication, bespoke, flex getter, flex write
Id: FVI1hgdqcms
Channel Id: undefined
Length: 31min 31sec (1891 seconds)
Published: Sun Nov 27 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.