{"id":18331569,"url":"https://github.com/angrycoding/rpctransport","last_synced_at":"2025-09-12T21:18:16.422Z","repository":{"id":26167244,"uuid":"29612771","full_name":"angrycoding/RPCTransport","owner":"angrycoding","description":"Provides easy way to organize two - way communication between Arduino and Node.js, uses the serial port as transport layer","archived":false,"fork":false,"pushed_at":"2024-09-09T07:24:04.000Z","size":66,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-01T23:09:58.151Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/angrycoding.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-01-21T20:49:50.000Z","updated_at":"2024-09-09T07:24:07.000Z","dependencies_parsed_at":"2024-11-05T19:55:25.542Z","dependency_job_id":null,"html_url":"https://github.com/angrycoding/RPCTransport","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/angrycoding/RPCTransport","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angrycoding%2FRPCTransport","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angrycoding%2FRPCTransport/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angrycoding%2FRPCTransport/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angrycoding%2FRPCTransport/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/angrycoding","download_url":"https://codeload.github.com/angrycoding/RPCTransport/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angrycoding%2FRPCTransport/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274879254,"owners_count":25367095,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-12T02:00:09.324Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-05T19:33:24.175Z","updated_at":"2025-09-12T21:18:16.367Z","avatar_url":"https://github.com/angrycoding.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"#  💜If you like my projects, you can support me.\n\n| Coin/Symbol | Network | Adress |\n|------|---------|--------|\n| Bitcoin (BTC) | BTC | 1LU7DtLiKkWe3aAXbhRhNAMUFdrapWuAHW |\n| Tether (USDT) | TRC20 | TK7f7TXozWVbkHxdArAJd2rELu725q1Ac5 |\n| Tether (USDT) | TON | UQDI4e7xm_B7O_REaYd5CoyEz1Ki08t0EPlUim022_K9B2xa |\n\n\n# Arduino \u003c-\u003e Node.js RPC transport\n\nProvides easy way to organize two - way communication between Arduino and Node.js, uses the serial port as transport layer. There are plenty of libraries that provides similar functionality, so what is the reason to create another one? Firstly I've tried the library called [Johnny-Five](https://github.com/rwaldron/johnny-five), well this library itself is quiet cool, but if you need to drive your Arduino using Node.js, it's very unlikely that you'd prefer to call low-level Arduino subroutines (such as pinMode, digitalWrite and so on), unless you are building something really weird, or you don't know C++ at all, so the only way for you is to use JavaScript to program Arduino. Second library that I've tried to use in order to accomplish my project, called [CmdMessenger](http://playground.arduino.cc/Code/CmdMessenger), this one looks more like what I actually need, but I couldn't use it because it has no Node.js integration + API looks quiet complicated to me (not in terms of understanding but in terms of usage). So I've come up with the idea to create my own library, with blackjack and hookers. So here is the list of features that in my opinion had to be done in order to make this library uber cool:\n* Smallest possible footprint, so library itself should not be bigger than your project, unfortunately this is not the case for both of the libraries listed above.\n* All basic data types must be supported (null, boolean, floats, ints and strings). Note that arrays and objects, despite that they are widely used in JavaScript are not supported, because supporting it would either increase size of your scetch and decrease performance. Anyways if you really need arrays and objects, then you should consider using something like [aJSON](https://github.com/interactive-matter/aJson).\n* Simple API, make things as intuitive and simple to use as possible.\n* Two - way communication, means that Node.js can call previously registered Arduino subroutine and receive result of it's execution and all the way around, Arduino can call previously registered subroutine on Node.js side, so more JavaScript, Node.js, web 2.0, HTML5 than hardcore C++.\n\n```c++\n// include library\n#include \"RPCTransport.h\"\n\n#define LED_PIN 8\n\n// instantiate RPCTransport and attach it to desired Serial\nRPCTransport transport(\u0026Serial);\n\n// used to set LED state\nvoid setState(RPCRequest* packet) {\n\t// get desired state\n\tbool state = packet-\u003egetBool(0);\n\t// write LED state\n\tdigitalWrite(LED_PIN, state);\n\t// clear request arguments\n\tpacket-\u003eclear();\n}\n\n// used to get LED state\nvoid getState(RPCRequest* packet) {\n\t// clear request arguments\n\tpacket-\u003eclear();\n\t// read LED state\n\tbool state = digitalRead(LED_PIN);\n\t// add return value\n\tpacket-\u003epushBool(state);\n}\n\n// this will be called when Node.js client is connected to the board\nvoid registerMethods() {\n\ttransport.on(\"setState\", setState);\n\ttransport.on(\"getState\", getState);\n}\n\nvoid setup() {\n\t// set the digital pin as output\n\tpinMode(LED_PIN, OUTPUT);\n\t// initialize Serial\n\tSerial.begin(115200);\n\t// initialize RPCTransport\n\ttransport.begin(registerMethods);\n}\n\n// called if there is serial data in the buffer\nvoid serialEvent() {\n\t// process incoming request\n\ttransport.process();\n}\n```\nYou start by instantiating RPCTransport and attaching it to desired serial port:\n```c++\n// instantiate RPCTransport and attach it to desired Serial\nRPCTransport transport(\u0026Serial);\n```\nWhen you ready to receive (or send) commands you call **transport.begin** and pass optional argument - callback function where you can register functions that will be available for calling from Node.js side (but don't forget to initialize serial communication first). Register public methods by calling **transport.on**, note that this method can only be called inside of the callback that is passed into **transport.begin**, attempt to call it in any other place won't take any effect. First argument is the name of your method (will be used to call it from Node.js), second argument is callback function, that will be executed when it's called:\n```c++\nvoid canBeCalledFromNode1(RPCRequest* packet) {\n\t...\n}\n\nvoid canBeCalledFromNode2(RPCRequest* packet) {\n\t...\n}\n\n// this will be called when Node.js client is connected to the board\nvoid registerMethods() {\n\ttransport.on(\"command1\", canBeCalledFromNode1);\n\ttransport.on(\"command2\", canBeCalledFromNode2);\n}\n\nvoid setup() {\n\t// don't forget to initialize Serial\n\tSerial.begin(115200);\n\t// initialize RPCTransport\n\ttransport.begin(registerMethods);\n}\n```\nIn order to process incoming messages, you have to call **transport.process**, if you don't do that, Node.js won't be able to call Arduino methods. There are two common places where you would call it, inside of loop subroutine or inside of special [serialEvent](http://arduino.cc/en/Tutorial/SerialEvent) subroutine (preferred):\n```c++\nvoid serialEvent() {\n\t// process incoming messages\n\ttransport.process();\n}\n```\nIf you do everything right, Node.js can now execute methods on Arduino side, reading passed arguments is quite straightforward:\n```c++\nvoid canBeCalledFromNode1(RPCRequest* packet) {\n\t// reading first argument as boolean\n\tbool a1 = packet-\u003egetBool(0);\n\t// reading second argument as float\n\tfloat a2 = packet-\u003egetFloat(1);\n\t// reading third argument as long\n\tlong a3 = packet-\u003egetInt(2);\n\t// reading fourth argument as string\n\tchar* a4 = packet-\u003egetString(3);\n}\n```\nRetrieving result is a bit tricky, same pointer is used to read arguments and to forward result to the caller. Before writing result, don't forget to clear the packet, otherwise everthing that you've received as an argument will be passed into result (echo mode):\n```c++\nvoid canBeCalledFromNode1(RPCRequest* packet) {\n\t// read first argument as boolean\n\tbool value = packet-\u003egetBool(0);\n\t// if you don't do it, result will contain original request\n\tpacket-\u003eclear();\n\t// push boolean into result set\n\tpacket-\u003epushBool(true);\n\t// push string into result set\n\tpacket-\u003epushString(\"result from Arduino\");\n}\n```\nMore realistic example, let's create method that will allow Node.js to call digitalWrite on Arduino side:\n```c++\n// include library\n#include \"RPCTransport.h\"\n\n// instantiate RPCTransport and attach it to desired Serial\nRPCTransport transport(\u0026Serial);\n\n// our digitalWrite implementation available to Node.js\nvoid myDigitalWrite(RPCRequest* packet) {\n\t// read pin number\n\tbyte pinNumber = packet-\u003egetInt(0);\n\t// read pin state\n\tbool pinState = packet-\u003egetBool(1);\n\t// do digitalWrite thing\n\tdigitalWrite(pinNumber, pinState);\n\t// clear request arguments\n\tpacket-\u003eclear();\n\t// let's respond with actual pinState\n\tpacket-\u003epushBool(digitalRead(pinNumber));\n}\n\n// this will be called when Node.js client is connected to the board\nvoid registerMethods() {\n\ttransport.on(\"digitalWrite\", myDigitalWrite);\n}\n\nvoid setup() {\n\t// initialize Serial\n\tSerial.begin(115200);\n\t// initialize RPCTransport\n\ttransport.begin(registerMethods);\n}\n\n// called if there is serial data in the buffer\nvoid serialEvent() {\n\t// process incoming request\n\ttransport.process();\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangrycoding%2Frpctransport","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fangrycoding%2Frpctransport","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangrycoding%2Frpctransport/lists"}