Closed tiagoclc closed 5 years ago
Is this actually a problem with the PID node, or is it a problem getting the data into the right format? Please make a small flow with only as many nodes as is needed to show the problem and post that.
I think its a problem with the PID node. Because i tested the data manipulation with other nodes and with debug node. Or i'm missing something... But i tried everything!
reduced flow:
[ { "id": "12fb5918.43acf7", "type": "PID", "z": "57696e5f.f08fb", "name": "", "setpoint": "{{msg.setpoint}}", "pb": "20", "ti": "18", "td": "5", "integral_default": "0", "smooth_factor": "0", "max_interval": 600, "enable": "1", "disabled_op": "0", "x": 850, "y": 500, "wires": [ [ "6c4d5de7.570b9c" ] ] }, { "id": "f25074a4.b57038", "type": "ui_slider", "z": "57696e5f.f08fb", "name": "temperatura", "label": "Temp. alvo", "tooltip": "", "group": "886f1cf5.fe52b", "order": 1, "width": "4", "height": "1", "passthru": true, "outs": "end", "topic": "setpoint", "min": 0, "max": "100", "step": 1, "x": 450, "y": 520, "wires": [ [ "12fb5918.43acf7" ] ] }, { "id": "1e391c76.0ca3fc", "type": "change", "z": "57696e5f.f08fb", "name": "", "rules": [ { "t": "set", "p": "topic", "pt": "msg", "to": "t_derivative", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 660, "y": 780, "wires": [ [ "12fb5918.43acf7" ] ] }, { "id": "182e06f5.bfd2c1", "type": "ui_slider", "z": "57696e5f.f08fb", "name": "ki", "label": "Ki", "tooltip": "", "group": "886f1cf5.fe52b", "order": 3, "width": "0", "height": "0", "passthru": true, "outs": "end", "topic": "", "min": 0, "max": "100", "step": "1", "x": 470, "y": 660, "wires": [ [ "772f5455.de1f54" ] ] }, { "id": "5327f548.afe754", "type": "ui_slider", "z": "57696e5f.f08fb", "name": "kp", "label": "Kp", "tooltip": "", "group": "886f1cf5.fe52b", "order": 2, "width": "0", "height": "0", "passthru": true, "outs": "end", "topic": "prop_band", "min": 0, "max": "100", "step": "1", "x": 470, "y": 580, "wires": [ [ "12fb5918.43acf7" ] ] }, { "id": "a1ae8cd7.c7ccd8", "type": "ui_slider", "z": "57696e5f.f08fb", "name": "kd", "label": "Kd", "tooltip": "", "group": "886f1cf5.fe52b", "order": 4, "width": "0", "height": "0", "passthru": true, "outs": "end", "topic": "t_derivative", "min": 0, "max": "100", "step": "1", "x": 470, "y": 780, "wires": [ [ "1e391c76.0ca3fc" ] ] }, { "id": "6c4d5de7.570b9c", "type": "debug", "z": "57696e5f.f08fb", "name": "Always NaN! WTF?", "active": true, "tosidebar": true, "console": true, "tostatus": false, "complete": "true", "targetType": "full", "x": 1080, "y": 600, "wires": [] }, { "id": "772f5455.de1f54", "type": "function", "z": "57696e5f.f08fb", "name": "", "func": "var temperaturaLida=global.get(\"temperaturaLida\")\nvar valor=parseFloat(msg.payload);\n\nmsg.topic=\"t_integral\";\nmsg.payload=parseInt(temperaturaLida);\nmsg.t_integral=valor;\n\nreturn msg;", "outputs": 1, "noerr": 0, "x": 630, "y": 660, "wires": [ [ "12fb5918.43acf7" ] ] }, { "id": "8d7c46c0.8803a", "type": "ui_button", "z": "57696e5f.f08fb", "name": "", "group": "886f1cf5.fe52b", "order": 1, "width": 0, "height": 0, "passthru": false, "label": "button", "tooltip": "", "color": "", "bgcolor": "", "icon": "", "payload": "20.5", "payloadType": "num", "topic": "", "x": 460, "y": 360, "wires": [ [ "12fb5918.43acf7" ] ] }, { "id": "886f1cf5.fe52b", "type": "ui_group", "z": "", "name": "PID", "tab": "391d5421.9e492c", "disp": true, "width": "8", "collapse": false }, { "id": "391d5421.9e492c", "type": "ui_tab", "z": "", "name": "Bedroom", "icon": "dashboard" } ]
You should not have {{msg.setpoint}}
in the setpoint field of the pid. If you feed in a message with msg.setpoint set then it will use that automatically. Or if you feed a message in with topic of setpoint then it will use that. Otherwise it will use the value from the setpoint field in the configuration.
but this is working...
The other values isnt (prop_band, t_integral and t_derivative). As I said on first post... Those other fields always returns NaN
Actually it is working for me, the reason is that once you feed in a setpoint from the slider then it ignores the value in the field. Does it show NaN for you if you move all the sliders and click Button? Every time you deploy it will go to NaN again because of the illegal setpoint in the config.
So, i cannot set it dynamically, right? And i need to set everything else before setpoint...
You cannot set what dynamically? You are doing that already, it is just that you have an illegal value for the default sepoint so until you set it dynamically the node does not know what to do. Change the {{msg.setpoint}}
to 0 (or whatever default you want) and all will be well.
The value isnt ilegal and i tried every single possibility. After set the value with the slider, setpoint have a valid value asni can see on debug return. Andni am not using the button its used to simulate a mqtt imput.
I already tried with every possible value, including 0.
Tried every possible value for what? To make it easier for me to see what problem you are having use Inject nodes to feed in values and post another flow showing it not working. And tell me what to press to see the problem
I shan't be able to answer again till the morning (it is getting late here).
Set the sliders then press the button and look at the debug window.
No problem! Thanks a lot for you attention!
Found a way! Just create a function and wire the outputs of all sliders to this function and wire the function's output to PID node.
the variable temperaturaLida came from mqtt input with temperature
`var setpoint = global.get("setpoint"); var prop_band = global.get("prop_band"); var t_integral = global.get("t_integral"); var t_derivative = global.get("t_derivative"); var temperaturaLida=global.get("temperaturaLida");
if (msg.topic=="temp"){ setpoint=msg.payload; global.set("setpoint", setpoint); }
if (msg.topic=='kp'){ prop_band=msg.payload; global.set("prop_band", prop_band); }
if (msg.topic=="ki"){ t_integral=msg.payload; global.set("t_integral", t_integral);
}
if (msg.topic=="kd"){ t_derivative=msg.payload; global.set("t_derivative", t_derivative); }
msg.payload = Number(temperaturaLida); msg.setpoint = Number(setpoint); msg.prop_band = Number(prop_band); msg.t_integral = Number(t_integral); msg.t_derivative = Number(t_derivative);
return msg; `
There is no need for all that complexity, try this.
[{"id":"51cd26c7.8d53d8","type":"PID","z":"d7ff0732.2f81d8","name":"","setpoint":"10","pb":"20","ti":"18","td":"5","integral_default":"0","smooth_factor":"0","max_interval":600,"enable":"1","disabled_op":"0","x":396.4285888671875,"y":545.2857666015625,"wires":[["c7e53e5d.c80b88"]]},{"id":"c7e53e5d.c80b88","type":"debug","z":"d7ff0732.2f81d8","name":"Never NaN! Yay.","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":520.4285888671875,"y":613.2857666015625,"wires":[]},{"id":"7b90a3b5.51797c","type":"inject","z":"d7ff0732.2f81d8","name":"PV 20.5","topic":"","payload":"20.5","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":139.5,"y":484,"wires":[["51cd26c7.8d53d8"]]},{"id":"eb05310f.3d5508","type":"inject","z":"d7ff0732.2f81d8","name":"setpoint","topic":"setpoint","payload":"25","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":136,"y":528,"wires":[["51cd26c7.8d53d8"]]},{"id":"762c92c8.5f77ac","type":"inject","z":"d7ff0732.2f81d8","name":"prob band","topic":"prop_band","payload":"10","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":147,"y":569,"wires":[["51cd26c7.8d53d8"]]},{"id":"9674c9ae.13e5d","type":"inject","z":"d7ff0732.2f81d8","name":"Ti","topic":"t_integral","payload":"60","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":136,"y":613,"wires":[["51cd26c7.8d53d8"]]},{"id":"547c4f40.7f62d8","type":"inject","z":"d7ff0732.2f81d8","name":"Td","topic":"t_derivative","payload":"5","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":137,"y":655,"wires":[["51cd26c7.8d53d8"]]}]
If your values are coming in from MQTT then you should be able to replace the Inject nodes with MQTT IN. [Edit] followed by change nodes to change the topics obviously.
Only PV come from mqtt in. The other values are setted with sliders.
OK, it makes little difference.
[{"id":"51cd26c7.8d53d8","type":"PID","z":"d7ff0732.2f81d8","name":"PID","setpoint":"10","pb":"20","ti":"18","td":"5","integral_default":"0","smooth_factor":"0","max_interval":600,"enable":"1","disabled_op":"0","x":396.4285888671875,"y":545.2857666015625,"wires":[["c7e53e5d.c80b88"]]},{"id":"c7e53e5d.c80b88","type":"debug","z":"d7ff0732.2f81d8","name":"Never NaN! Yay.","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":520.4285888671875,"y":613.2857666015625,"wires":[]},{"id":"7b90a3b5.51797c","type":"inject","z":"d7ff0732.2f81d8","name":"PV 20.5","topic":"","payload":"20.5","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":139.5,"y":484,"wires":[["51cd26c7.8d53d8"]]},{"id":"7df50cb1.9ae1c4","type":"ui_slider","z":"d7ff0732.2f81d8","name":"Setpoint","label":"Setpoint","tooltip":"","group":"d6ed8dbc.a12f98","order":1,"width":"4","height":"1","passthru":true,"outs":"end","topic":"setpoint","min":0,"max":"100","step":1,"x":110,"y":531,"wires":[["51cd26c7.8d53d8"]]},{"id":"a9a9b618.859448","type":"ui_slider","z":"d7ff0732.2f81d8","name":"Ti","label":"Ti","tooltip":"","group":"d6ed8dbc.a12f98","order":3,"width":"0","height":"0","passthru":true,"outs":"end","topic":"t_integral","min":0,"max":"100","step":"1","x":119,"y":614,"wires":[["51cd26c7.8d53d8"]]},{"id":"4a296c62.e030c4","type":"ui_slider","z":"d7ff0732.2f81d8","name":"Prob band","label":"Prob band","tooltip":"","group":"d6ed8dbc.a12f98","order":2,"width":"0","height":"0","passthru":true,"outs":"end","topic":"prop_band","min":0,"max":"100","step":"1","x":101,"y":574,"wires":[["51cd26c7.8d53d8"]]},{"id":"8da71348.84978","type":"ui_slider","z":"d7ff0732.2f81d8","name":"Td","label":"Td","tooltip":"","group":"d6ed8dbc.a12f98","order":4,"width":"0","height":"0","passthru":true,"outs":"end","topic":"t_derivative","min":0,"max":"100","step":"1","x":117,"y":658,"wires":[["51cd26c7.8d53d8"]]},{"id":"d6ed8dbc.a12f98","type":"ui_group","z":"","name":"PID","tab":"66bd50bf.e1a158","disp":true,"width":"8","collapse":false},{"id":"66bd50bf.e1a158","type":"ui_tab","z":"","name":"Bedroom","icon":"dashboard"}]
Hi colinl I also need to change the Prop Band dynamically I used your example suggestion to change the PB, but I don't get the desired result.
Initially I set the PB = 5 and the SetPoint = 28 in the PID and everything works fine.
When I try to modify the PB from 5 to 3, I verify that also the PID set point has been modified, the PID starts to intervene at 24 and ends at 27 The anomaly that returned is that, the change in the value of the PB took place correctly, but the SetPoint has also decreased by going from 28 to 27
I did other tests ... if I change PB = 2 the SetPoint goes down to 26.5 if I change PB = 1 the SetPoint goes down to 26
Thanks
Put a debug node showing complete message on the input to the pid and another on the output and show me the message you are sending that changes both the PB and the Setpoint. Include the previous message out of the PID so we can see what the Setpoint was previously.
Also I would be interested to know what sort of process you are controlling that requires dynamic changes to the tuning parameters. That is quite unusual.
Hi Colinl I am a homebrewing, the process I am trying to control requires the control of an electric pot with 28 liters of water in which some kg of malts are immersed, at different temperature steps.
I enclose a photo of the steps of a recipe, to understand the values at stake ...
The temperature, between recipes, does not change much ... a step can be omitted ... but, what changes and can affect the management of the temperature control are the liters of water and the kg of immersed malt, which can vary between the various recipes.
My idea is for each recipe to find the right parameters and store them in a 'profile', which I will use when replicing a recipe
For this the 'first time' that I make a new recipe, I must be able to change the parameters dynamically, to make the T oscillate, as little as possible, around the value of the setpoint of each step.
I had tried to calibrate the PID by simulating the complete process with only water, but the real situation is too different
I will try to 'capture' incoming and outgoing messages from the PID to publish them
Did you see my request for the debug output showing the setpoint being messed up?
I can see you might need different tuning parameters if you are significantly changing the volume. What is the heating pot like (in terms of how the heating is arranged for example) and how are you measuring the temperature (with a probe in the liquid or what)? Is the liquid being stirred? If so how is that arranged? Are you sending the data to something like Influxdb and charting with Grafana? For tuning it is vital to be able to see the temperature, setpoint and power in a chart. The advantage of influx and grafana is that you can easily go back and look at previous runs. I am surprised there is a big difference between plain water and water with maltings. I would be interested to see the chart you are currently getting with your best tuning so far, and tell me what the parameters are set to for that chart.
Hi colinl many questions .... many answers Do you prefer to continue the discussion in this thread?
Don't mind where. Whichever you prefer.
Ok I will create a telegram channel I add a bit of information and answers and then I send you the link to connect. Are you well ?
Sorry, I thought you meant the node-red forum or here. Not something like telegram please.
Okay, i'll continue on node-red forum I will notify you when I put the new post Thanks
Don't worry, I will see it.
See also issue #10
Hi!
I'm facing a problem and hope someone could help.
Trying to set prop_band, t_integral and t_derivative dynamically with sliders, but it always return NaN. Already tried to use function using parseFloat(), parseInt() and Number(), but nothing seems to work. Tried to change topics respectively and nothing. Changing setpoint this way works flawlessly, like github's instructions. (https://github.com/colinl/node-red-contrib-pid 1)
Am I missing something?
Here goes my flow:
smaller below