How to manage the control of a contactor with self-holding using a DHT22 probe

Hello; I'm testing this project on my Raspberry Pi 3B: https://pexpeppers.com/blogs/pepper-growing/diy-greenhouse-control
It's thanks to this project that I discovered the power of Node-RED. This project works very well, but I need to modify a few things for it to work on my greenhouse project. My setup uses opening windows controlled by switches that only need a pulse (push button). I want the DHT22 to send this pulse. But I can't configure the project I'm using to send a pulse instead of the continuous operating time (like a fan). I've been trying to fix this myself for several days, but I lack the necessary knowledge. Could you help me? Thank you.

How are you controlling the DHT? Can't you just send ON followed by OFF a fraction of a second later?
You can do that with a Trigger node.

Thanks for your super quick reply :slight_smile:
I haven't been able to get this configuration working with the "trigger" node. I'm a beginner and I still need to improve. Regarding the "trigger" node, when I use it, it remains constantly active because the temperature stays at 1.

There is also a filter node you can set to pass once until the value changes
[edit] not sure this is a hardware problem, seems more to be general

If you configure a Trigger node like this

Then every time you send it a message it will send 1 then 250ms later it will send 0. Is it something like that that you need to do?

I've already tried that solution, but it doesn't stop the control contactor. Because the temperature continues to send the signal, the control contactor remains engaged all the time.

So under what conditions do you want to send the pulse?

I want the signal to be sent for about 2 seconds when the temperature exceeds the programmed threshold. And that's what I'm having trouble with. I don't know which nodes to use for this.

Try this

[{"id":"175dd08cd0737ed6","type":"inject","z":"a46e55dd44eced53","name":"19","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"19","payloadType":"num","x":110,"y":60,"wires":[["e5204562e10295be"]]},{"id":"3936760da074c3a5","type":"inject","z":"a46e55dd44eced53","name":"21","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"21","payloadType":"num","x":110,"y":120,"wires":[["e5204562e10295be"]]},{"id":"e5204562e10295be","type":"switch","z":"a46e55dd44eced53","name":">20?","property":"payload","propertyType":"msg","rules":[{"t":"gt","v":"20","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":260,"y":100,"wires":[["c17c991aeb04459b"],["e56907e70fdb4742"]]},{"id":"c17c991aeb04459b","type":"change","z":"a46e55dd44eced53","name":"High","rules":[{"t":"set","p":"payload","pt":"msg","to":"High","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":80,"wires":[["3b9b138e8c154d50"]]},{"id":"e56907e70fdb4742","type":"change","z":"a46e55dd44eced53","name":"Low","rules":[{"t":"set","p":"payload","pt":"msg","to":"Low","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":120,"wires":[["3b9b138e8c154d50"]]},{"id":"3b9b138e8c154d50","type":"rbe","z":"a46e55dd44eced53","name":"Block unless state changes","func":"rbe","gap":"","start":"","inout":"out","septopics":false,"property":"payload","topi":"topic","x":600,"y":100,"wires":[["934f0137b7e4f47a"]]},{"id":"ed7d7ccb4ea685ba","type":"trigger","z":"a46e55dd44eced53","name":"Pulse","op1":"1","op2":"0","op1type":"num","op2type":"num","duration":"2000","extend":false,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":450,"y":220,"wires":[["e35cb55f8e2f0c11"]]},{"id":"e35cb55f8e2f0c11","type":"debug","z":"a46e55dd44eced53","name":"debug 13","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":620,"y":220,"wires":[]},{"id":"934f0137b7e4f47a","type":"switch","z":"a46e55dd44eced53","name":"High?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"High","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":310,"y":220,"wires":[["ed7d7ccb4ea685ba"]]}]

Thanks for your help. I'll test your solution in a few days. I'll keep you posted.

Hi Colin, your solution works when I inject manually. Now I just need to figure out how to adapt it for use with the DHT22. Thanks again for your help. I'll get back to you if I can't integrate it into my project. Many thanks for your patience and work. Manu

A big thank you from a Frenchman for your help which allowed me to find the solution for my flow. :folded_hands:

1 Like

One other thing to consider when it comes to temperature or any other process sensor control; histeresis. The sensor will have noise, or the process will move around a lot. How often do you want your output to toggle state? Turning a fan on and off every few seconds will cause contactor failure quickly. How much over the threshold do you want the temperature to be before switching? Noise may make the fan turn on sooner than it needs to. What about when the temperature comes back down? At a minimum, build in a differential window into your logic. If you want the process output ON above 20C, you should probably have it turn OFF again at something like .2-.5 degree away from that (I don't know if this is a heating or cooling mode process output).

Example flow:

[
    {
        "id": "8b914fb8f77edcb4",
        "type": "group",
        "z": "5114d0e940ab3dee",
        "name": "toggle output (each pulse will latch/unlatch relay)",
        "style": {
            "label": true
        },
        "nodes": [
            "175dd08cd0737ed6",
            "3936760da074c3a5",
            "e5204562e10295be",
            "c17c991aeb04459b",
            "e56907e70fdb4742",
            "3b9b138e8c154d50",
            "ed7d7ccb4ea685ba",
            "e35cb55f8e2f0c11",
            "c1969523872e30c6",
            "c5e50060547c0a9e"
        ],
        "x": 674,
        "y": 159,
        "w": 732,
        "h": 202
    },
    {
        "id": "175dd08cd0737ed6",
        "type": "inject",
        "z": "5114d0e940ab3dee",
        "g": "8b914fb8f77edcb4",
        "name": "19",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "19",
        "payloadType": "num",
        "x": 770,
        "y": 280,
        "wires": [
            [
                "e5204562e10295be"
            ]
        ]
    },
    {
        "id": "3936760da074c3a5",
        "type": "inject",
        "z": "5114d0e940ab3dee",
        "g": "8b914fb8f77edcb4",
        "name": "21",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "21",
        "payloadType": "num",
        "x": 770,
        "y": 200,
        "wires": [
            [
                "e5204562e10295be"
            ]
        ]
    },
    {
        "id": "e5204562e10295be",
        "type": "switch",
        "z": "5114d0e940ab3dee",
        "g": "8b914fb8f77edcb4",
        "name": ">20?",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "gt",
                "v": "20",
                "vt": "num"
            },
            {
                "t": "lte",
                "v": "19.5",
                "vt": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 920,
        "y": 240,
        "wires": [
            [
                "c17c991aeb04459b"
            ],
            [
                "e56907e70fdb4742"
            ]
        ]
    },
    {
        "id": "c17c991aeb04459b",
        "type": "change",
        "z": "5114d0e940ab3dee",
        "g": "8b914fb8f77edcb4",
        "name": "High",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "High",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1050,
        "y": 220,
        "wires": [
            [
                "3b9b138e8c154d50"
            ]
        ]
    },
    {
        "id": "e56907e70fdb4742",
        "type": "change",
        "z": "5114d0e940ab3dee",
        "g": "8b914fb8f77edcb4",
        "name": "Low",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "Low",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1050,
        "y": 260,
        "wires": [
            [
                "3b9b138e8c154d50"
            ]
        ]
    },
    {
        "id": "3b9b138e8c154d50",
        "type": "rbe",
        "z": "5114d0e940ab3dee",
        "g": "8b914fb8f77edcb4",
        "name": "Block unless state changes",
        "func": "rbe",
        "gap": "",
        "start": "",
        "inout": "out",
        "septopics": false,
        "property": "payload",
        "topi": "topic",
        "x": 1260,
        "y": 240,
        "wires": [
            [
                "ed7d7ccb4ea685ba",
                "c1969523872e30c6"
            ]
        ]
    },
    {
        "id": "ed7d7ccb4ea685ba",
        "type": "trigger",
        "z": "5114d0e940ab3dee",
        "g": "8b914fb8f77edcb4",
        "name": "Pulse",
        "op1": "1",
        "op2": "0",
        "op1type": "num",
        "op2type": "num",
        "duration": "250",
        "extend": false,
        "overrideDelay": false,
        "units": "ms",
        "reset": "",
        "bytopic": "all",
        "topic": "topic",
        "outputs": 1,
        "x": 930,
        "y": 320,
        "wires": [
            [
                "e35cb55f8e2f0c11"
            ]
        ]
    },
    {
        "id": "e35cb55f8e2f0c11",
        "type": "debug",
        "z": "5114d0e940ab3dee",
        "g": "8b914fb8f77edcb4",
        "name": "debug 13",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 1080,
        "y": 320,
        "wires": []
    },
    {
        "id": "c1969523872e30c6",
        "type": "debug",
        "z": "5114d0e940ab3dee",
        "g": "8b914fb8f77edcb4",
        "name": "debug 11",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 1240,
        "y": 200,
        "wires": []
    },
    {
        "id": "c5e50060547c0a9e",
        "type": "inject",
        "z": "5114d0e940ab3dee",
        "g": "8b914fb8f77edcb4",
        "name": "19.8",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "19.8",
        "payloadType": "num",
        "x": 770,
        "y": 240,
        "wires": [
            [
                "e5204562e10295be"
            ]
        ]
    }
]

In some cases where there's a lot of noise, using the filter node can help to ensure that the sensor level changes a certain amount before passing it along... OR it can ensure that high noise spikes don't make your process toggle states because of a momentary blip. OR, you can use one filter node to do BOTH those things.

I really do love controls. Happy coding.

Thanks for your reply. My problem is that the DHT22 sends a constant signal as soon as the temperature is reached or exceeded. Whereas I only need a temporary signal (about 2 seconds) as soon as the temperature is reached or exceeded. In my flow, the signal must be sent long enough to activate a contactor that has a self-holding function to open a window. Then, when the window is open, the contactor stops thanks to a limit switch that cuts the power. The same applies for closing. For now, Colin's solution works quite well. If you have another flow in mind, I'd be happy to try it. And thanks again for your help.

I see, so you've got your threshold and sampling offloaded to some other device? I didn't realize the DHT22 does this internally... anyway if you want to manage the controls on your own, now you have a couple examples of reading a raw number value and doing a comparison/logic check.

The DHT22 doesn't handle that at all. I used Colin's flow diagram to "force" it to only send one pulse to my contactor. This means the contactor "flashes" when the temperature reaches the temperature I've set. If the temperature remains stable, the contactor will receive a pulse every 2 seconds until the threshold changes. It's not perfect, but I don't know how to do better. I'm pasting my flow diagram so you understand :stuck_out_tongue:

Sorry, my flow dont ok on this post

My flow is too big for for here

flows (1).json (3.6 KB)

This file seems to just be a dashboard ui-node, but it as I suspected before, your DHT22 is sending in a payload which is a number. Like in my example, the inject nodes are just for testing, you hook the node-red-contrib-dht-sensor node to the switch node (">20?") and you control your relay based on the login in that switch node. BUT, if you don't have a windows where the switch node makes no change, then you'll have an output that goes high/low frequently as your temperature crosses your threshold over and over.

Anyway, if it's working, it's working. Best of luck!