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.