-
I'm fighting (and loosing) against the I2C Nodes.
Raspberry Pi
After much trial and even more errors, I figured out how this node work on the RPi: flow.json
What I learned using this node:
Node MCUOk, now back to Node-MCU and attempting the same logic: flow.json
The output in xsbug is:
Ok, something is returned but the returned buffer contains only garbage. Any pointer to where I'm messing it up is highly appreciated. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
I think you are very close. I appreciate your methodical approach. Going back to the RPi nodes, and even the Node.js JavaScript, helps. I believe I know what's going on, but I don't have an SHT3x to try. First, there was a bug in the I2C In & I2C Out node editors. I committed a fix for that. After updating, you should restart Node-RED and hard reload the browser to make sure the caches are flushed. You'll also need to delete the existing I2C In & I2C Out nodes to get the new behavior. The bug is that the Command field always had a value -- you should be able to leave it blank to mean "no command". That's the main reason you were getting garbage. I updated your flow. It eliminates the "function 3" node. In the I2C out node, the Command is empty, and the two byte command is set in the payload as an array using the JSON option. Similarly, the I2C In node has an empty Command. Here's the JSON for the updated llow. Updated flow[
{
"id": "1724269305058a2a",
"type": "tab",
"label": "Flow 4",
"disabled": false,
"info": "",
"env": [],
"_mcu": {
"mcu": false
}
},
{
"id": "5fc1835efa555203",
"type": "debug",
"z": "1724269305058a2a",
"name": "",
"active": true,
"tosidebar": true,
"console": true,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"_mcu": {
"mcu": false
},
"x": 1020,
"y": 300,
"wires": []
},
{
"id": "bce0e0237ce14fb3",
"type": "inject",
"z": "1724269305058a2a",
"name": "",
"props": [],
"repeat": "1",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"_mcu": {
"mcu": false
},
"x": 170,
"y": 300,
"wires": [
[
"c630fba71ae42dfe"
]
]
},
{
"id": "68bd5489e530efee",
"type": "delay",
"z": "1724269305058a2a",
"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,
"_mcu": {
"mcu": false
},
"x": 430,
"y": 300,
"wires": [
[
"bf3faffd7e625643"
]
]
},
{
"id": "c630fba71ae42dfe",
"type": "mcu_i2c_out",
"z": "1724269305058a2a",
"name": "",
"options": {
"clock": "22",
"data": "21",
"hz": "100000",
"address": "68"
},
"command": "",
"bytes": 1,
"payload": "[36,0]",
"payloadType": "json",
"_mcu": {
"mcu": false
},
"x": 290,
"y": 300,
"wires": [
[
"68bd5489e530efee"
]
]
},
{
"id": "bf3faffd7e625643",
"type": "mcu_i2c_in",
"z": "1724269305058a2a",
"name": "",
"options": {
"clock": "22",
"data": "21",
"hz": "100000",
"address": "68"
},
"command": "",
"bytes": "6",
"_mcu": {
"mcu": false
},
"x": 570,
"y": 300,
"wires": [
[
"699de40b2776f167",
"5fc1835efa555203"
]
]
},
{
"id": "699de40b2776f167",
"type": "function",
"z": "1724269305058a2a",
"name": "Read SHT3x Temp / Hum",
"func": "function checksum(data) {\n /*\n *\tName : CRC-8\n *\tPoly : 0x31\tx^8 + x^5 + x^4 + 1\n *\tInit : 0xFF\n *\tRevert: false\n *\tXorOut: 0x00\n *\tCheck : for 0xBE,0xEF CRC is 0x92\n */\n const polynomial = 0x31;\n\n let crc = 0xFF;\n let index = 0;\n\n for (const k in data) {\n crc ^= data[index++];\n for (let i = 8; i > 0; --i) {\n crc = crc & 0x80 ? (crc << 1) ^ polynomial : crc << 1;\n crc &= 0xFF;\n }\n }\n\n return crc;\n}\n\nfunction formatTemperature(rawTemp) {\n return ((rawTemp * 175) / 65535) - 45;\n}\n\nfunction formatHumidity(rawHumidity) {\n return (rawHumidity * 100) / 65535;\n}\n\n// Temperature\nif (checksum([msg.payload[0], msg.payload[1]]) !== msg.payload[2]) {\n node.warn('Temperature failed CRC check');\n} else {\n const TempRaw = (msg.payload[0] << 8) + msg.payload[1];\n msg.Temperature = formatTemperature(TempRaw);\n}\n// Humidity\nif (checksum([msg.payload[3], msg.payload[4]]) !== msg.payload[5]) {\n node.warn('Humidity failed CRC check');\n} else {\n const HumRaw = (msg.payload[3] << 8) + msg.payload[4];\n msg.Humidity = formatHumidity(HumRaw);\n}\nnode.send(msg);\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"_mcu": {
"mcu": false
},
"x": 790,
"y": 260,
"wires": [
[
"5fc1835efa555203"
]
]
}
] FWIW – In the RPi I2C nodes, a Command is always one byte. The MCU version implements this behavior for consistency. It is inconvenient for I2C device with two byte commands. Your attempt to use the command for the first byte and payload for the second probably would work, except for the bug in the editor that disallowed an empty command. I think the approach taken in the updated flow is more straightforward, as it parallels your "pure JS" example above. |
Beta Was this translation helpful? Give feedback.
-
FYI – a small update here. With the recent re-organization of the repository, there has been a nice improvement to the I²C nodes based on your feedback. Now both the Address and Command fields of I2C In and I2C Out nodes access both hex and decimal values. Hex values are prefixed with |
Beta Was this translation helpful? Give feedback.
I think you are very close. I appreciate your methodical approach. Going back to the RPi nodes, and even the Node.js JavaScript, helps. I believe I know what's going on, but I don't have an SHT3x to try.
First, there was a bug in the I2C In & I2C Out node editors. I committed a fix for that. After updating, you should restart Node-RED and hard reload the browser to make sure the caches are flushed. You'll also need to delete the existing I2C In & I2C Out nodes to get the new behavior. The bug is that the Command field always had a value -- you should be able to leave it blank to mean "no command". That's the main reason you were getting garbage.
I updated your flow. It eliminates the "fun…