Skip to content

Instantly share code, notes, and snippets.

@WillSams
Last active June 21, 2023 10:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WillSams/0db368dd01b85843b461fab0aebc5d80 to your computer and use it in GitHub Desktop.
Save WillSams/0db368dd01b85843b461fab0aebc5d80 to your computer and use it in GitHub Desktop.
Node Red / OpenPLC / Modbus
[
{
"id": "bf767ff1cdc5fa2f",
"type": "tab",
"label": "Getting Started",
"disabled": false,
"info": "",
"env": []
},
{
"id": "3301341bac651a70",
"type": "tab",
"label": "Hello World Example",
"disabled": false,
"info": ""
},
{
"id": "feaffe784243c357",
"type": "tab",
"label": "Variables Example",
"disabled": false,
"info": "",
"env": []
},
{
"id": "8d032cedaac7f1a0",
"type": "tab",
"label": "Bit Set Example",
"disabled": false,
"info": "",
"env": []
},
{
"id": "7eb2d70e8ea91d6d",
"type": "tab",
"label": "Faux Bit Set Example",
"disabled": false,
"info": "",
"env": []
},
{
"id": "f80b18febf27a651",
"type": "ui_tab",
"name": "Home",
"icon": "dashboard",
"disabled": false,
"hidden": false
},
{
"id": "fe767ed83b084b44",
"type": "ui_base",
"theme": {
"name": "theme-light",
"lightTheme": {
"default": "#0094CE",
"baseColor": "#0094CE",
"baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif",
"edited": true,
"reset": false
},
"darkTheme": {
"default": "#097479",
"baseColor": "#097479",
"baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif",
"edited": false
},
"customTheme": {
"name": "Untitled Theme 1",
"default": "#4B7930",
"baseColor": "#4B7930",
"baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"
},
"themeState": {
"base-color": {
"default": "#0094CE",
"value": "#0094CE",
"edited": false
},
"page-titlebar-backgroundColor": {
"value": "#0094CE",
"edited": false
},
"page-backgroundColor": {
"value": "#fafafa",
"edited": false
},
"page-sidebar-backgroundColor": {
"value": "#ffffff",
"edited": false
},
"group-textColor": {
"value": "#1bbfff",
"edited": false
},
"group-borderColor": {
"value": "#ffffff",
"edited": false
},
"group-backgroundColor": {
"value": "#ffffff",
"edited": false
},
"widget-textColor": {
"value": "#111111",
"edited": false
},
"widget-backgroundColor": {
"value": "#0094ce",
"edited": false
},
"widget-borderColor": {
"value": "#ffffff",
"edited": false
},
"base-font": {
"value": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"
}
},
"angularTheme": {
"primary": "indigo",
"accents": "blue",
"warn": "red",
"background": "grey",
"palette": "light"
}
},
"site": {
"name": "Node-RED Dashboard",
"hideToolbar": "false",
"allowSwipe": "false",
"lockMenu": "false",
"allowTempTheme": "true",
"dateFormat": "DD/MM/YYYY",
"sizes": {
"sx": 48,
"sy": 48,
"gx": 6,
"gy": 6,
"cx": 6,
"cy": 6,
"px": 0,
"py": 0
}
}
},
{
"id": "bb31ddb7c1d7b596",
"type": "ui_group",
"name": "Default",
"tab": "f80b18febf27a651",
"order": 1,
"disp": true,
"width": "6",
"collapse": false,
"className": ""
},
{
"id": "2dadfc00.5aa6a4",
"type": "modbus-client",
"name": "PLC",
"clienttype": "tcp",
"bufferCommands": true,
"stateLogEnabled": false,
"queueLogEnabled": false,
"failureLogEnabled": true,
"tcpHost": "127.0.0.1",
"tcpPort": "502",
"tcpType": "DEFAULT",
"serialPort": "/dev/ttyUSB",
"serialType": "RTU-BUFFERD",
"serialBaudrate": "9600",
"serialDatabits": "8",
"serialStopbits": "1",
"serialParity": "none",
"serialConnectionDelay": "100",
"serialAsciiResponseStartDelimiter": "",
"unit_id": 1,
"commandDelay": 1,
"clientTimeout": 1000,
"reconnectOnTimeout": true,
"reconnectTimeout": 2000,
"parallelUnitIdsAllowed": true
},
{
"id": "c2222727e07a4eef",
"type": "modbus-client",
"name": "PLC",
"clienttype": "tcp",
"bufferCommands": true,
"stateLogEnabled": false,
"tcpHost": "127.0.0.1",
"tcpPort": "502",
"tcpType": "DEFAULT",
"serialPort": "/dev/ttyUSB",
"serialType": "RTU-BUFFERD",
"serialBaudrate": "9600",
"serialDatabits": "8",
"serialStopbits": "1",
"serialParity": "none",
"serialConnectionDelay": "100",
"unit_id": 1,
"commandDelay": 1,
"clientTimeout": 1000,
"reconnectTimeout": 2000
},
{
"id": "server_id",
"type": "modbus-client",
"name": "Modbus Server",
"clienttype": "tcp",
"bufferCommands": true,
"stateLogEnabled": false,
"queueLogEnabled": false,
"tcpHost": "localhost",
"tcpPort": "502",
"tcpType": "DEFAULT",
"serialPort": "/dev/ttyUSB",
"serialType": "RTU-BUFFERD",
"serialBaudrate": "9600",
"serialDatabits": "8",
"serialStopbits": "1",
"serialParity": "none",
"serialConnectionDelay": "100",
"unit_id": 1,
"commandDelay": 1,
"clientTimeout": 500,
"reconnectTimeout": 2000
},
{
"id": "0e43769103b1bc98",
"type": "comment",
"z": "bf767ff1cdc5fa2f",
"name": "OpenPLC address registers are a word (16 bits) wide. In regards to binary, each bit can be 0 or 1.",
"info": "",
"x": 350,
"y": 40,
"wires": []
},
{
"id": "43cdeb80972b0b09",
"type": "comment",
"z": "bf767ff1cdc5fa2f",
"name": "Avoid unintended writes into addresses by planning the memory map for your flow. ",
"info": "",
"x": 310,
"y": 80,
"wires": []
},
{
"id": "231197911b397039",
"type": "comment",
"z": "bf767ff1cdc5fa2f",
"name": "For more info, visit https://openplcproject.com/docs/2-5-modbus-addressing/",
"info": "",
"x": 290,
"y": 120,
"wires": []
},
{
"id": "d23dd7e0da5e3019",
"type": "comment",
"z": "bf767ff1cdc5fa2f",
"name": "Big-endian: least signifcant byte is stored on the left.",
"info": "",
"x": 210,
"y": 460,
"wires": []
},
{
"id": "0bec82b5b7bca2aa",
"type": "comment",
"z": "bf767ff1cdc5fa2f",
"name": "Little-endian: least significant byte is stored on the right. At the address, the last bit would be set. [10000000]",
"info": "",
"x": 390,
"y": 540,
"wires": []
},
{
"id": "2c1bb18fe71cc916",
"type": "comment",
"z": "bf767ff1cdc5fa2f",
"name": "Both little-endian and big-endian representations of values in binary are the same but are stored differently in memory. ",
"info": "",
"x": 410,
"y": 360,
"wires": []
},
{
"id": "f857eaa7249f536a",
"type": "comment",
"z": "bf767ff1cdc5fa2f",
"name": "As an example, let's discuss how the binary representation of byte 00000001 (1 in decimal) is stored at a stored at a given address.",
"info": "",
"x": 460,
"y": 400,
"wires": []
},
{
"id": "2c8239fee0c85b58",
"type": "comment",
"z": "bf767ff1cdc5fa2f",
"name": "4 bits = a \"nibble\"",
"info": "",
"x": 300,
"y": 180,
"wires": []
},
{
"id": "7425db8ddc00581a",
"type": "comment",
"z": "bf767ff1cdc5fa2f",
"name": "8 bits = a \"byte\"",
"info": "",
"x": 300,
"y": 220,
"wires": []
},
{
"id": "4480b0e77c339f21",
"type": "comment",
"z": "bf767ff1cdc5fa2f",
"name": "16 bits = 2 bytes (a \"word\")",
"info": "",
"x": 330,
"y": 260,
"wires": []
},
{
"id": "a401fc394799e160",
"type": "comment",
"z": "bf767ff1cdc5fa2f",
"name": "32 bits = 4 bytes (a \"double word\", \"long\" or \"real\")",
"info": "",
"x": 410,
"y": 300,
"wires": []
},
{
"id": "591ddb7d968ca6cf",
"type": "comment",
"z": "bf767ff1cdc5fa2f",
"name": "I.e., for a 8-bit register starting at address 0, the bit \"1\" would be set at bit 7 (leftmost) of the byte at address 0.",
"info": "",
"x": 390,
"y": 500,
"wires": []
},
{
"id": "e16a581ba7faf792",
"type": "comment",
"z": "bf767ff1cdc5fa2f",
"name": "I.e., for a 8-bit register starting at address 0, the bit \"1\" would be set at bit 0 (rightmost) of the byte at address 0. [00000001]",
"info": "",
"x": 430,
"y": 580,
"wires": []
},
{
"id": "49ebec515a41c6e7",
"type": "modbus-read",
"z": "3301341bac651a70",
"name": "",
"topic": "",
"showStatusActivities": true,
"logIOActivities": false,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "HoldingRegister",
"adr": "0",
"quantity": "16",
"rate": "1",
"rateUnit": "s",
"delayOnStart": false,
"startDelayTime": "",
"server": "2dadfc00.5aa6a4",
"useIOFile": false,
"ioFile": "",
"useIOForPayload": false,
"emptyMsgOnFail": true,
"x": 110,
"y": 380,
"wires": [
[],
[
"4aa64aecb817c7b7"
]
]
},
{
"id": "214337a4d6cb7e20",
"type": "modbus-write",
"z": "3301341bac651a70",
"name": "Toggle Message",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "MHoldingRegisters",
"adr": "0",
"quantity": "5",
"server": "2dadfc00.5aa6a4",
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 320,
"y": 260,
"wires": [
[],
[]
]
},
{
"id": "0cd2163e496e6bba",
"type": "inject",
"z": "3301341bac651a70",
"name": "Hello",
"props": [
{
"p": "payload"
}
],
"repeat": "2",
"crontab": "",
"once": true,
"onceDelay": "1",
"topic": "",
"payload": "[72, 101, 108, 108, 111]",
"payloadType": "json",
"x": 90,
"y": 240,
"wires": [
[
"214337a4d6cb7e20"
]
]
},
{
"id": "62fa7ee746e6048f",
"type": "debug",
"z": "3301341bac651a70",
"name": "Debug",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload.data",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 450,
"y": 380,
"wires": []
},
{
"id": "9a03d58abeec2d53",
"type": "inject",
"z": "3301341bac651a70",
"name": "World",
"props": [
{
"p": "payload"
}
],
"repeat": "2",
"crontab": "",
"once": true,
"onceDelay": "2",
"topic": "",
"payload": "[87, 111, 114, 108, 100]",
"payloadType": "json",
"x": 100,
"y": 280,
"wires": [
[
"214337a4d6cb7e20"
]
]
},
{
"id": "8b0361213420c54d",
"type": "comment",
"z": "3301341bac651a70",
"name": "Read from PLC using Modbus Client",
"info": "",
"x": 160,
"y": 340,
"wires": []
},
{
"id": "b983e149c7da2ee3",
"type": "comment",
"z": "3301341bac651a70",
"name": "Write to PLC using Modbus Client",
"info": "",
"x": 150,
"y": 160,
"wires": []
},
{
"id": "4aa64aecb817c7b7",
"type": "function",
"z": "3301341bac651a70",
"name": "Get Message",
"func": "function convertAsciiToString(asciiArray) {\n const charArray = asciiArray.map((ascii) => String.fromCharCode(ascii));\n const string = charArray.join('');\n return string;\n};\n\nmsg.payload = {\n data: convertAsciiToString(msg.payload.data)\n};\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 290,
"y": 380,
"wires": [
[
"62fa7ee746e6048f"
]
]
},
{
"id": "42087d34f6ee6f9f",
"type": "comment",
"z": "3301341bac651a70",
"name": "Alternate values at address 0, 1, 2, 3, 4",
"info": "",
"x": 170,
"y": 200,
"wires": []
},
{
"id": "f84b0c8ad158f711",
"type": "modbus-write",
"z": "3301341bac651a70",
"name": "Clear All 1024 Holding Registers",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "MHoldingRegisters",
"adr": "0",
"quantity": "64",
"server": "2dadfc00.5aa6a4",
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 590,
"y": 140,
"wires": [
[],
[]
]
},
{
"id": "c6c1055988f25438",
"type": "function",
"z": "3301341bac651a70",
"name": "Get Zeros Array",
"func": "const zerosArray = Array.from({ length: 1024 }, () => 0);\nmsg.payload = zerosArray;\nreturn msg;\n\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 600,
"y": 60,
"wires": [
[
"8ec446dbcfc1103e"
]
]
},
{
"id": "f37184e2d0cda244",
"type": "inject",
"z": "3301341bac651a70",
"name": "Inject",
"props": [],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"x": 590,
"y": 20,
"wires": [
[
"c6c1055988f25438"
]
]
},
{
"id": "8ec446dbcfc1103e",
"type": "split",
"z": "3301341bac651a70",
"name": "Break Into 64-bit Chunks",
"splt": "\\n",
"spltType": "str",
"arraySplt": "64",
"arraySpltType": "len",
"stream": false,
"addname": "",
"x": 590,
"y": 100,
"wires": [
[
"f84b0c8ad158f711"
]
]
},
{
"id": "5ad5a8a1dff35045",
"type": "comment",
"z": "3301341bac651a70",
"name": "For the following example, we'll assume a big-endian architecture. ",
"info": "",
"x": 250,
"y": 20,
"wires": []
},
{
"id": "47c062a63417d1fa",
"type": "comment",
"z": "3301341bac651a70",
"name": "Not useful for this discussion, but just assume. =)",
"info": "",
"x": 200,
"y": 60,
"wires": []
},
{
"id": "4592b54df9c51cb0",
"type": "comment",
"z": "feaffe784243c357",
"name": "For our own memory map, we can define how big our registers can be.",
"info": "",
"x": 270,
"y": 200,
"wires": []
},
{
"id": "6686903e15f24759",
"type": "modbus-write",
"z": "feaffe784243c357",
"name": "Clear All 1024 Holding Registers",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "MHoldingRegisters",
"adr": "0",
"quantity": "64",
"server": "2dadfc00.5aa6a4",
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 590,
"y": 140,
"wires": [
[],
[]
]
},
{
"id": "be0e20a64ce6910a",
"type": "function",
"z": "feaffe784243c357",
"name": "Get Zeros Array",
"func": "const zerosArray = Array.from({ length: 1024 }, () => 0);\nmsg.payload = zerosArray;\nreturn msg;\n\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 600,
"y": 60,
"wires": [
[
"93ae3d223f237c2f"
]
]
},
{
"id": "e822ee51efcdf1f1",
"type": "inject",
"z": "feaffe784243c357",
"name": "Inject",
"props": [],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 590,
"y": 20,
"wires": [
[
"be0e20a64ce6910a"
]
]
},
{
"id": "93ae3d223f237c2f",
"type": "split",
"z": "feaffe784243c357",
"name": "Break Into 64-bit Chunks",
"splt": "\\n",
"spltType": "str",
"arraySplt": "64",
"arraySpltType": "len",
"stream": false,
"addname": "",
"x": 590,
"y": 100,
"wires": [
[
"6686903e15f24759"
]
]
},
{
"id": "1524664d1819511a",
"type": "modbus-read",
"z": "feaffe784243c357",
"name": "",
"topic": "",
"showStatusActivities": true,
"logIOActivities": false,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "HoldingRegister",
"adr": "16",
"quantity": "16",
"rate": "3",
"rateUnit": "s",
"delayOnStart": false,
"startDelayTime": "",
"server": "2dadfc00.5aa6a4",
"useIOFile": false,
"ioFile": "",
"useIOForPayload": false,
"emptyMsgOnFail": true,
"x": 110,
"y": 480,
"wires": [
[],
[
"886a1c37b76273b3"
]
]
},
{
"id": "3d2a9a9df833008c",
"type": "modbus-write",
"z": "feaffe784243c357",
"name": "Set variable1",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "MHoldingRegisters",
"adr": "16",
"quantity": "8",
"server": "2dadfc00.5aa6a4",
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 310,
"y": 280,
"wires": [
[],
[]
]
},
{
"id": "2ae85b46698adb29",
"type": "inject",
"z": "feaffe784243c357",
"name": "variable1",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": "1",
"topic": "",
"payload": "[72, 101, 108, 108, 111, 0, 0, 0]",
"payloadType": "json",
"x": 100,
"y": 280,
"wires": [
[
"3d2a9a9df833008c"
]
]
},
{
"id": "f46a0d3e1329dd37",
"type": "debug",
"z": "feaffe784243c357",
"name": "Debug",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload.data",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 450,
"y": 480,
"wires": []
},
{
"id": "8bf55f1f84f90f17",
"type": "inject",
"z": "feaffe784243c357",
"name": "variable2",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": "1",
"topic": "",
"payload": "[87, 111, 114, 108, 100, 0, 0, 0]",
"payloadType": "json",
"x": 100,
"y": 380,
"wires": [
[
"0e6b3532962f1c8e"
]
]
},
{
"id": "ac6082bcaefaa618",
"type": "comment",
"z": "feaffe784243c357",
"name": "Read from PLC using Modbus Client",
"info": "",
"x": 160,
"y": 440,
"wires": []
},
{
"id": "a964c27e44bbaa09",
"type": "comment",
"z": "feaffe784243c357",
"name": "Write to PLC using Modbus Client",
"info": "",
"x": 150,
"y": 160,
"wires": []
},
{
"id": "886a1c37b76273b3",
"type": "function",
"z": "feaffe784243c357",
"name": "Get Values",
"func": "msg.payload = {\n data: String(msg.payload.data)\n};\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 290,
"y": 480,
"wires": [
[
"f46a0d3e1329dd37"
]
]
},
{
"id": "c177b65c1768bb97",
"type": "comment",
"z": "feaffe784243c357",
"name": "Reserve 8 bits for variable1 (address 16 through 23)",
"info": "",
"x": 210,
"y": 240,
"wires": []
},
{
"id": "f494e329e41eeb02",
"type": "comment",
"z": "feaffe784243c357",
"name": "Reserve 8 bits for variable1 (address 24 through 31)",
"info": "",
"x": 210,
"y": 340,
"wires": []
},
{
"id": "0e6b3532962f1c8e",
"type": "modbus-write",
"z": "feaffe784243c357",
"name": "Set variable2",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "MHoldingRegisters",
"adr": "24",
"quantity": "8",
"server": "2dadfc00.5aa6a4",
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 310,
"y": 380,
"wires": [
[],
[]
]
},
{
"id": "890cc9ebc36e2fd4",
"type": "comment",
"z": "feaffe784243c357",
"name": "For the following example, we'll assume a big-endian architecture. ",
"info": "",
"x": 250,
"y": 20,
"wires": []
},
{
"id": "5b19f46aa91d08fa",
"type": "comment",
"z": "feaffe784243c357",
"name": "Not useful for this discussion, but just assume. =)",
"info": "",
"x": 200,
"y": 60,
"wires": []
},
{
"id": "899b077608b75088",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "6502 Status Register Example - NV0BDIZC",
"info": "7 6 5 4 3 2 1 0\nN\tV\t0\tB\tD\tI\tZ\tC\n\nNote: bit 5 in the 6502 processor is always 0.",
"x": 180,
"y": 120,
"wires": []
},
{
"id": "cad8f48bd0537bf2",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "007 06 05 04 3 2 1 0",
"info": "",
"x": 120,
"y": 160,
"wires": []
},
{
"id": "c97934b62979bce3",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "N- Negative - Set when operation results in a negative value (bit 7 set)",
"info": "N\tV\t0\tB\tD\tI\tZ\tC",
"x": 650,
"y": 200,
"wires": []
},
{
"id": "4ed75f188850972a",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "V - Overflow - Set when arithmetic operation or compare results in an overflow value",
"info": "N\tV\t0\tB\tD\tI\tZ\tC",
"x": 690,
"y": 240,
"wires": []
},
{
"id": "a47da15dbb67b1e1",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "Bit 5 in the 6502 status register is always 0",
"info": "B - Break - Set when a BRK opcode has been executed, is only written to the stack",
"x": 560,
"y": 280,
"wires": []
},
{
"id": "2829e5b3c22e159f",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "B - Break - Set when a BRK opcode has been executed, is only written to the stack",
"info": "N\tV\t0\tB\tD\tI\tZ\tC",
"x": 690,
"y": 320,
"wires": []
},
{
"id": "dbd23ddf469cf8f2",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "D - Decimal - Decimal flag",
"info": "Note: The Famicom/NES does not have a decimal mode.",
"x": 510,
"y": 360,
"wires": []
},
{
"id": "e2ce14e8542b7a65",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "I - Interrupt - Set to disable interrupts (deprecated)",
"info": "N\tV\t0\tB\tD\tI\tZ\tC",
"x": 590,
"y": 400,
"wires": []
},
{
"id": "e824f0865b7db573",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "Z - Zero - Set when operation results in a zero value",
"info": "N\tV\t0\tB\tD\tI\tZ\tC",
"x": 590,
"y": 440,
"wires": []
},
{
"id": "94a304b660ef6277",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "C - Carry - Carry for arithmetic operations and compares",
"info": "N\tV\t0\tB\tD\tI\tZ\tC",
"x": 610,
"y": 480,
"wires": []
},
{
"id": "a68ed910727f70c7",
"type": "modbus-write",
"z": "8d032cedaac7f1a0",
"name": "Clear All 1024 Holding Registers",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "MHoldingRegisters",
"adr": "0",
"quantity": "64",
"server": "2dadfc00.5aa6a4",
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 580,
"y": 140,
"wires": [
[],
[]
]
},
{
"id": "55dc47189521cce8",
"type": "function",
"z": "8d032cedaac7f1a0",
"name": "Get Zeros Array",
"func": "const zerosArray = Array.from({ length: 1024 }, () => 0);\nmsg.payload = zerosArray;\nreturn msg;\n\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 590,
"y": 60,
"wires": [
[
"4f5c393502d9c5ec"
]
]
},
{
"id": "c6579cdc2867663e",
"type": "inject",
"z": "8d032cedaac7f1a0",
"name": "Inject",
"props": [],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"x": 580,
"y": 20,
"wires": [
[
"55dc47189521cce8"
]
]
},
{
"id": "4f5c393502d9c5ec",
"type": "split",
"z": "8d032cedaac7f1a0",
"name": "Break Into 64-bit Chunks",
"splt": "\\n",
"spltType": "str",
"arraySplt": "64",
"arraySpltType": "len",
"stream": false,
"addname": "",
"x": 580,
"y": 100,
"wires": [
[
"a68ed910727f70c7"
]
]
},
{
"id": "d90572add7e8296f",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "Address 32",
"info": "",
"x": 310,
"y": 180,
"wires": []
},
{
"id": "8c9f09414e1a3f26",
"type": "modbus-read",
"z": "8d032cedaac7f1a0",
"name": "",
"topic": "",
"showStatusActivities": true,
"logIOActivities": false,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "HoldingRegister",
"adr": "32",
"quantity": "1",
"rate": "1",
"rateUnit": "s",
"delayOnStart": false,
"startDelayTime": "",
"server": "2dadfc00.5aa6a4",
"useIOFile": false,
"ioFile": "",
"useIOForPayload": false,
"emptyMsgOnFail": true,
"x": 110,
"y": 440,
"wires": [
[],
[
"5e481a1c8173ef4c"
]
]
},
{
"id": "ce22ce8dcc4ceda0",
"type": "debug",
"z": "8d032cedaac7f1a0",
"name": "Debug",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload.data",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 190,
"y": 500,
"wires": []
},
{
"id": "a9249ca858f669ee",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "Read from PLC using Modbus Client",
"info": "",
"x": 160,
"y": 400,
"wires": []
},
{
"id": "42a2c20cba9e037a",
"type": "inject",
"z": "8d032cedaac7f1a0",
"name": "Set Bits",
"props": [
{
"p": "payload"
}
],
"repeat": "2",
"crontab": "",
"once": true,
"onceDelay": "2",
"topic": "",
"payload": "129",
"payloadType": "num",
"x": 100,
"y": 300,
"wires": [
[
"d8093ac257c16bf0"
]
]
},
{
"id": "d8093ac257c16bf0",
"type": "modbus-write",
"z": "8d032cedaac7f1a0",
"name": "Set the C to 1, Z to 0, N to 1",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "HoldingRegister",
"adr": "32",
"quantity": "1",
"server": "2dadfc00.5aa6a4",
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 160,
"y": 340,
"wires": [
[],
[]
]
},
{
"id": "5e481a1c8173ef4c",
"type": "function",
"z": "8d032cedaac7f1a0",
"name": "Get Values",
"func": "const value = (msg.payload.data & 0xFFFF)\nconst data = value.toString(2).padStart(16, '0');\nmsg.payload = { data };\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 290,
"y": 440,
"wires": [
[
"ce22ce8dcc4ceda0"
]
]
},
{
"id": "b1b848ab4747951a",
"type": "inject",
"z": "8d032cedaac7f1a0",
"name": "Default",
"props": [
{
"p": "payload"
}
],
"repeat": "2",
"crontab": "",
"once": true,
"onceDelay": "1",
"topic": "",
"payload": "2",
"payloadType": "num",
"x": 100,
"y": 240,
"wires": [
[
"fcd042c80d2327eb"
]
]
},
{
"id": "fcd042c80d2327eb",
"type": "modbus-write",
"z": "8d032cedaac7f1a0",
"name": "Reset Status Register",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "HoldingRegister",
"adr": "32",
"quantity": "1",
"server": "2dadfc00.5aa6a4",
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 280,
"y": 260,
"wires": [
[],
[]
]
},
{
"id": "083a31158fb87418",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "The 6502 follows a little-endian byte ordering.",
"info": "",
"x": 180,
"y": 20,
"wires": []
},
{
"id": "c61aea0b448c6e2b",
"type": "comment",
"z": "8d032cedaac7f1a0",
"name": "128 64 32 16 8 4 2 1",
"info": "",
"x": 120,
"y": 200,
"wires": []
},
{
"id": "bda3446a1fd595b9",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "6502 Status Register Example - NV0BDIZC",
"info": "7 6 5 4 3 2 1 0\nN\tV\t0\tB\tD\tI\tZ\tC\n\nNote: bit 5 in the 6502 processor is always 0.",
"x": 190,
"y": 160,
"wires": []
},
{
"id": "e39dcdff240959d4",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "7 6 5 4 3 2 1 0",
"info": "",
"x": 90,
"y": 200,
"wires": []
},
{
"id": "fdf1a0619fa43cfa",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "N- Negative - Set when operation results in a negative value (bit 7 set)",
"info": "N\tV\t0\tB\tD\tI\tZ\tC",
"x": 650,
"y": 200,
"wires": []
},
{
"id": "f3fd8705ad7dccfc",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "V - Overflow - Set when arithmetic operation or compare results in an overflow value",
"info": "N\tV\t0\tB\tD\tI\tZ\tC",
"x": 690,
"y": 240,
"wires": []
},
{
"id": "c5c41803d9f24134",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "Bit 5 in the 6502 status register is always 0",
"info": "B - Break - Set when a BRK opcode has been executed, is only written to the stack",
"x": 560,
"y": 280,
"wires": []
},
{
"id": "a690d73acb3353fe",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "B - Break - Set when a BRK opcode has been executed, is only written to the stack",
"info": "N\tV\t0\tB\tD\tI\tZ\tC",
"x": 690,
"y": 320,
"wires": []
},
{
"id": "cef4523e48a56ce8",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "D - Decimal - Decimal flag",
"info": "Note: The Famicom/NES does not have a decimal mode.",
"x": 510,
"y": 360,
"wires": []
},
{
"id": "b1c5ea5c05631628",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "I - Interrupt - Set to disable interrupts (deprecated)",
"info": "N\tV\t0\tB\tD\tI\tZ\tC",
"x": 590,
"y": 400,
"wires": []
},
{
"id": "4a4d13b36070fb75",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "Z - Zero - Set when operation results in a zero value",
"info": "N\tV\t0\tB\tD\tI\tZ\tC",
"x": 590,
"y": 440,
"wires": []
},
{
"id": "73682fca895b5ea6",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "C - Carry - Carry for arithmetic operations and compares",
"info": "N\tV\t0\tB\tD\tI\tZ\tC",
"x": 600,
"y": 480,
"wires": []
},
{
"id": "52bffe25abe81084",
"type": "modbus-write",
"z": "7eb2d70e8ea91d6d",
"name": "Clear All 1024 Holding Registers",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "MHoldingRegisters",
"adr": "0",
"quantity": "64",
"server": "2dadfc00.5aa6a4",
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 590,
"y": 140,
"wires": [
[],
[]
]
},
{
"id": "cf65f2186960513b",
"type": "function",
"z": "7eb2d70e8ea91d6d",
"name": "Get Zeros Array",
"func": "const zerosArray = Array.from({ length: 1024 }, () => 0);\nmsg.payload = zerosArray;\nreturn msg;\n\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 600,
"y": 60,
"wires": [
[
"9c166fec984f998d"
]
]
},
{
"id": "b98e77e605c4b44c",
"type": "inject",
"z": "7eb2d70e8ea91d6d",
"name": "Inject",
"props": [],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"x": 590,
"y": 20,
"wires": [
[
"cf65f2186960513b"
]
]
},
{
"id": "9c166fec984f998d",
"type": "split",
"z": "7eb2d70e8ea91d6d",
"name": "Break Into 64-bit Chunks",
"splt": "\\n",
"spltType": "str",
"arraySplt": "64",
"arraySpltType": "len",
"stream": false,
"addname": "",
"x": 590,
"y": 100,
"wires": [
[
"52bffe25abe81084"
]
]
},
{
"id": "6e9a2979b1b15296",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "Address 33 through 40",
"info": "",
"x": 280,
"y": 200,
"wires": []
},
{
"id": "74d620e0f95ca639",
"type": "modbus-read",
"z": "7eb2d70e8ea91d6d",
"name": "",
"topic": "",
"showStatusActivities": true,
"logIOActivities": false,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "HoldingRegister",
"adr": "33",
"quantity": "8",
"rate": "1",
"rateUnit": "s",
"delayOnStart": false,
"startDelayTime": "",
"server": "2dadfc00.5aa6a4",
"useIOFile": false,
"ioFile": "",
"useIOForPayload": false,
"emptyMsgOnFail": true,
"x": 110,
"y": 560,
"wires": [
[],
[
"d2e4605307a21102"
]
]
},
{
"id": "fcb7ed0226e730a0",
"type": "debug",
"z": "7eb2d70e8ea91d6d",
"name": "Debug",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload.data",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 390,
"y": 520,
"wires": []
},
{
"id": "a3a8d5e07e2e3711",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "Read from PLC using Modbus Client",
"info": "",
"x": 160,
"y": 520,
"wires": []
},
{
"id": "cb25a7a0646f0582",
"type": "inject",
"z": "7eb2d70e8ea91d6d",
"name": "1",
"props": [
{
"p": "payload"
}
],
"repeat": "2",
"crontab": "",
"once": true,
"onceDelay": "2",
"topic": "",
"payload": "[1]",
"payloadType": "json",
"x": 250,
"y": 300,
"wires": [
[
"0190991ec4347e7f",
"a61fb5bd4563391e"
]
]
},
{
"id": "0190991ec4347e7f",
"type": "modbus-write",
"z": "7eb2d70e8ea91d6d",
"name": "Set the Carry flag (C) to 1",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "HoldingRegister",
"adr": "40",
"quantity": "1",
"server": "2dadfc00.5aa6a4",
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 250,
"y": 340,
"wires": [
[],
[]
]
},
{
"id": "ebe4458438558463",
"type": "modbus-write",
"z": "7eb2d70e8ea91d6d",
"name": "Set the Zero flag (Z) to 0",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "HoldingRegister",
"adr": "39",
"quantity": "1",
"server": "2dadfc00.5aa6a4",
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 250,
"y": 400,
"wires": [
[],
[]
]
},
{
"id": "a61fb5bd4563391e",
"type": "modbus-write",
"z": "7eb2d70e8ea91d6d",
"name": "Set the Negative flag (N) to 1",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "HoldingRegister",
"adr": "33",
"quantity": "1",
"server": "2dadfc00.5aa6a4",
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 260,
"y": 460,
"wires": [
[],
[]
]
},
{
"id": "1308189fb266f1d1",
"type": "inject",
"z": "7eb2d70e8ea91d6d",
"name": "0",
"props": [
{
"p": "payload"
}
],
"repeat": "2",
"crontab": "",
"once": true,
"onceDelay": "2",
"topic": "",
"payload": "[0]",
"payloadType": "json",
"x": 90,
"y": 300,
"wires": [
[
"ebe4458438558463"
]
]
},
{
"id": "d2e4605307a21102",
"type": "function",
"z": "7eb2d70e8ea91d6d",
"name": "Get Values",
"func": "msg.payload = {\n data: String(msg.payload.data)\n};\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 290,
"y": 580,
"wires": [
[
"fcb7ed0226e730a0"
]
]
},
{
"id": "d8aa990e2322e0ee",
"type": "inject",
"z": "7eb2d70e8ea91d6d",
"name": "Default",
"props": [
{
"p": "payload"
}
],
"repeat": "2",
"crontab": "",
"once": true,
"onceDelay": "1",
"topic": "",
"payload": "[0, 0, 0, 0, 0, 0, 1, 0]",
"payloadType": "json",
"x": 100,
"y": 240,
"wires": [
[
"cc75cda670f1b72b"
]
]
},
{
"id": "cc75cda670f1b72b",
"type": "modbus-write",
"z": "7eb2d70e8ea91d6d",
"name": "Reset Status Register",
"showStatusActivities": true,
"showErrors": true,
"showWarnings": true,
"unitid": "1",
"dataType": "MHoldingRegisters",
"adr": "33",
"quantity": "8",
"server": "2dadfc00.5aa6a4",
"emptyMsgOnFail": true,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 280,
"y": 240,
"wires": [
[],
[]
]
},
{
"id": "0c162c06ef6db153",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "The 6502 follows a little-endian byte ordering. It's important to note",
"info": "",
"x": 260,
"y": 20,
"wires": []
},
{
"id": "093a704f35f02497",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "in this example, we are simulating an 8-bit register by assigning ",
"info": "",
"x": 250,
"y": 60,
"wires": []
},
{
"id": "ae1286b7b1483d9f",
"type": "comment",
"z": "7eb2d70e8ea91d6d",
"name": "8 addresses as if they represent individual bits.",
"info": "",
"x": 200,
"y": 100,
"wires": []
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment