Node-red-contrib-i2c - Help

I want to use node-red-contrib-i2c to read an SHT31 sensor and whatever I do fail miserably:

Flow
[
    {
        "id": "a52d7898.c71278",
        "type": "i2c out",
        "z": "e02a37191a6c46ac",
        "name": "Write",
        "busno": "1",
        "address": "68",
        "command": "",
        "payload": "",
        "payloadType": "num",
        "count": "1",
        "x": 1250,
        "y": 140,
        "wires": [
            [
                "c3c0ea0c9e3ce683"
            ]
        ]
    },
    {
        "id": "e333b0f6.342f",
        "type": "inject",
        "z": "e02a37191a6c46ac",
        "name": "",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 960,
        "y": 140,
        "wires": [
            [
                "eaddd3b5bf7313fd"
            ]
        ]
    },
    {
        "id": "8da5670fda0baf25",
        "type": "inject",
        "z": "e02a37191a6c46ac",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 960,
        "y": 100,
        "wires": [
            [
                "d729bcefe79882df"
            ]
        ]
    },
    {
        "id": "d729bcefe79882df",
        "type": "function",
        "z": "e02a37191a6c46ac",
        "name": "Reset SHT3x",
        "func": "// Device\nconst i2cBusNo = 1;\nconst i2cAddress = 0x44;\n\n// Command\nconst sht3x_SoftReset = Buffer.from([0xF3, 0x2D]);\n\ni2c.openPromisified(i2cBusNo).\n  then((i2cBus) => i2cBus.i2cWrite(i2cAddress, sht3x_SoftReset.length, sht3x_SoftReset).\n    then((_) => i2cBus.close())\n  ).\n  catch(console.log);\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [
            {
                "var": "nodeCrc",
                "module": "node-crc"
            },
            {
                "var": "i2c",
                "module": "i2c-bus"
            }
        ],
        "x": 1150,
        "y": 100,
        "wires": [
            [
                "0a888bfa1688f5a4"
            ]
        ]
    },
    {
        "id": "0a888bfa1688f5a4",
        "type": "debug",
        "z": "e02a37191a6c46ac",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1390,
        "y": 100,
        "wires": []
    },
    {
        "id": "d674b29f41c7c04e",
        "type": "inject",
        "z": "e02a37191a6c46ac",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 960,
        "y": 60,
        "wires": [
            [
                "a564f8f39a26fd6b"
            ]
        ]
    },
    {
        "id": "a564f8f39a26fd6b",
        "type": "function",
        "z": "e02a37191a6c46ac",
        "name": "Read SHT3x Temp / Hum",
        "func": "// Device\nconst i2cBusNo = 1;\nconst i2cAddress = 0x44;\n\n// Command\nconst sht3x_SingleHighNoStretch = Buffer.from([0x24, 0x00]);\n\n// Result Buffer\nconst sensorData = Buffer.alloc(6);\n\n\nfunction checksum(data) {\n  const result = nodeCrc.crc(\n    0x31, // polyLow\n    0x00, // polyHigh\n    8,\n    0xFF, // initLow\n    0xFF, // initHigh\n    0x00, // XORlow\n    0x00, // XORhigh\n    false, // reflect\n    Buffer.from(data)\n  );\n  return result;\n}\n\nfunction formatTemperature(rawTemp) {\n  return ((rawTemp * 175) / 65535) - 45;\n}\n\nfunction formatHumidity(rawHumidity) {\n  return (rawHumidity * 100) / 65535;\n}\n\nconst awaitTimeout = (delay) =>\n  new Promise((resolve) => setTimeout(resolve, delay));\n\ni2c.openPromisified(i2cBusNo).\n  then((i2cBus) => i2cBus.i2cWrite(i2cAddress, sht3x_SingleHighNoStretch.length, sht3x_SingleHighNoStretch).\n    then((_) => awaitTimeout(15)).\n    then((_) => i2cBus.i2cRead(i2cAddress, sensorData.length, sensorData)).\n    then((data) => {\n      // Temperature\n      if (checksum([data.buffer[0], data.buffer[1]])[0] !== data.buffer[2]) {\n        node.warn('Temperature failed CRC check');\n      } else {\n        const TempRaw = Buffer.from([data.buffer[0], data.buffer[1]]).readInt16BE(0);\n        msg.Temperature = formatTemperature(TempRaw);\n      }\n      // Humidity\n      if (checksum([data.buffer[3], data.buffer[4]])[0] !== data.buffer[5]) {\n        node.warn('Humidity failed CRC check');\n      } else {\n        const HumRaw = Buffer.from([data.buffer[3], data.buffer[3]]).readInt16BE(0);\n        msg.Humidity = formatHumidity(HumRaw);\n      }\n      node.send(msg);\n    }).\n    then((_) => i2cBus.close())\n  ).\n  catch(console.log);\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [
            {
                "var": "nodeCrc",
                "module": "node-crc"
            },
            {
                "var": "i2c",
                "module": "i2c-bus"
            }
        ],
        "x": 1190,
        "y": 60,
        "wires": [
            [
                "9718af37bdfbd7df"
            ]
        ]
    },
    {
        "id": "9718af37bdfbd7df",
        "type": "debug",
        "z": "e02a37191a6c46ac",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1410,
        "y": 60,
        "wires": []
    },
    {
        "id": "eaddd3b5bf7313fd",
        "type": "function",
        "z": "e02a37191a6c46ac",
        "name": "Command",
        "func": "msg.command = Buffer.from([0x24, 0x00]);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1110,
        "y": 140,
        "wires": [
            [
                "a52d7898.c71278"
            ]
        ]
    },
    {
        "id": "1a44a282ddc8e39e",
        "type": "debug",
        "z": "e02a37191a6c46ac",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1650,
        "y": 140,
        "wires": []
    },
    {
        "id": "f0fcd111b1a385a6",
        "type": "i2c in",
        "z": "e02a37191a6c46ac",
        "name": "Read",
        "busno": "1",
        "address": "68",
        "command": "",
        "count": "6",
        "x": 1530,
        "y": 140,
        "wires": [
            [
                "1a44a282ddc8e39e"
            ]
        ]
    },
    {
        "id": "c3c0ea0c9e3ce683",
        "type": "delay",
        "z": "e02a37191a6c46ac",
        "name": "",
        "pauseType": "delay",
        "timeout": "15",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 1390,
        "y": 140,
        "wires": [
            [
                "f0fcd111b1a385a6"
            ]
        ]
    }
]

The first two functions implement the I2C access directly using the i2c-bus node and this is working.

Basically it should be simple:

  • Write 0x2400 to the device
  • Read back the response after a short wait

I just can't get the contrib node to do the same. Apparently I'm missing something pretty obvious but I just can't figure it out. Any pointer would be appreciated.

Have you looked at node-red-contrib-sht31 or node-red-contrib-sht?

Thanks @zenofmud. I should have probably mentioned that it is only an example. I wanted to make more extensive use of the Node-Red-Contrib-I2c nodes and also different devices.
This was more a test-run with (I thought) a pretty easy sensor.

Ok, I think I figured it out:

If I want to write 16bit to the device then the first byte needs to go into the command and the second byte into payload (as integers).
So trying to write 0x2400 translates to:

msg = { "command": 36, "payload": 0 }

It yields the correct result but I cannot say that I understand it. Feels very weird

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.