{"id":16153578,"url":"https://github.com/rufus31415/sharer","last_synced_at":"2025-07-04T15:36:39.310Z","repository":{"id":129287403,"uuid":"126520905","full_name":"Rufus31415/Sharer","owner":"Rufus31415","description":"Arduino \u0026 .NET serial communication library to read/write variables and remote call functions using the Sharer protocol. Works on Windows, Linux and MacOS.","archived":false,"fork":false,"pushed_at":"2022-01-16T14:04:45.000Z","size":236,"stargazers_count":39,"open_issues_count":0,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-02T18:54:53.810Z","etag":null,"topics":["arduino","board","c","communication","csharp","library","linux","macos","net","netcore","netframework","protocol","remote","rpc","sharer","windows"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Rufus31415.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"custom":"paypal.me/FlorentGIRAUD","github":"Rufus31415"}},"created_at":"2018-03-23T17:54:47.000Z","updated_at":"2024-12-24T19:40:53.000Z","dependencies_parsed_at":"2023-03-24T13:47:26.268Z","dependency_job_id":null,"html_url":"https://github.com/Rufus31415/Sharer","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/Rufus31415/Sharer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rufus31415%2FSharer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rufus31415%2FSharer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rufus31415%2FSharer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rufus31415%2FSharer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Rufus31415","download_url":"https://codeload.github.com/Rufus31415/Sharer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rufus31415%2FSharer/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263568042,"owners_count":23481605,"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","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":["arduino","board","c","communication","csharp","library","linux","macos","net","netcore","netframework","protocol","remote","rpc","sharer","windows"],"created_at":"2024-10-10T01:13:44.957Z","updated_at":"2025-07-04T15:36:39.303Z","avatar_url":"https://github.com/Rufus31415.png","language":"C++","funding_links":["paypal.me/FlorentGIRAUD","https://github.com/sponsors/Rufus31415"],"categories":[],"sub_categories":[],"readme":"![GitHub](https://img.shields.io/github/license/rufus31415/sharer)\n![GitHub release](https://img.shields.io/github/v/release/rufus31415/sharer.net)\n\n![.NET Framework 3.5](https://img.shields.io/badge/.NET_Framework-3.5-blueviolet)\n![.NET Framework 4.0](https://img.shields.io/badge/.NET_Framework-4.0-blueviolet)\n![.NET Framework 4.5](https://img.shields.io/badge/.NET_Framework-4.5-blueviolet)\n![.NET Framework 4.6](https://img.shields.io/badge/.NET_Framework-4.6-blueviolet)\n![.NET Framework 4.7](https://img.shields.io/badge/.NET_Framework-4.7-blueviolet)\n![.NET Framework 4.8](https://img.shields.io/badge/.NET_Framework-4.8-blueviolet)\n\n\n![.NET Core 2.0](https://img.shields.io/badge/.NET_Core-2.0-blueviolet)\n![.NET Core 2.1](https://img.shields.io/badge/.NET_Core-2.1-blueviolet)\n![.NET Core 2.2](https://img.shields.io/badge/.NET_Core-2.2-blueviolet)\n![.NET Core 3.0](https://img.shields.io/badge/.NET_Core-3.0-blueviolet)\n![.NET Core 3.1](https://img.shields.io/badge/.NET_Core-3.1-blueviolet)\n\n![.NET Standard 2.1](https://img.shields.io/badge/.NET_Standard-2.1-blueviolet)\n\n![Arduino Uno](https://img.shields.io/badge/Arduino-Uno-blue)\n![Arduino Mega](https://img.shields.io/badge/Arduino-Mega-blue)\n![Arduino Nano](https://img.shields.io/badge/Arduino-Nano-blue)\n![Arduino Due](https://img.shields.io/badge/Arduino-Due-blue)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/Rufus31415/Sharer.NET/master/Sharer.png\"\u003e\n\u003c/p\u003e\n\nSharer is both a \u003cb\u003e.NET and an Arduino Library\u003c/b\u003e. It allows a desktop application to \u003cb\u003eread/write variables\u003c/b\u003e and \u003cb\u003eremote call functions on Arduino\u003c/b\u003e, using the Sharer protocole accross a serial communication.\nSharer has initially been developped for the Ballcuber project (https://ballcuber.github.io), but it is now a standalone library ;).\n\n\u003cp align=\"center\"\u003e\n\t\u003ca href=\"https://github.com/Rufus31415/Sharer/releases\"\u003e\n\t\t\u003cimg alt=\"Download arduino library and examples\" src=\"https://img.shields.io/badge/▼-Download%20Arduino%20library%20and%20examples-blue?logo=arduino\u0026style=for-the-badge\" /\u003e\n\t\u003c/a\u003e\n\t\u003ca href=\"https://github.com/Rufus31415/Sharer.NET/releases\"\u003e\n\t\t\u003cimg alt=\"Download .NET library and example\" src=\"https://img.shields.io/badge/▼-Download%20.NET%20Library%20and%20examples-green?logo=c%20sharp\u0026style=for-the-badge\" /\u003e\n\t\u003c/a\u003e\n\t\u003cbr/\u003e\n\t\u003ca href=\"https://www.nuget.org/packages/Sharer\"\u003e\n\t\t\u003cimg alt=\"Download Nuget library\" src=\"https://img.shields.io/badge/▼-Download%20Nuget%20.NET%20Library-20038d?logo=nuget\u0026style=for-the-badge\" /\u003e\n\t\u003c/a\u003e\n\u003c/p\u003e\n\n# Overview 🧐\n### How to connect\n``` C#\n// C#\nvar connection = new SharerConnection(\"COM3\", 115200);\nconnection.Connect();\n```\n\nRemark : for some boards, like Micro and Leonardo, it is necessary to set the RTS and DTR signals with the ```RtsEnable``` and ```DtrEnable``` properties.\n\n### How to call a function\n``` C#\n// C# - My Arduino code has a function : int Sum(int a, byte b);\nvar result = connection.Call(\"Sum\", 10, 12);\n// result.Status : OK\n// result.Type : int\n// result.Value : 22\n```\n\n``` C#\n// C# - Read all digital pins : digitalRead(0) to digitalRead(13)\nfor(int i=0; i \u003c= 13; i++){\n\tvar digitalValue = connection.Call(\"digitalRead\", i);\n\t// digitalValue.Status : OK\n\t// digitalValue.Type : bool\n\t// digitalValue.Value : true or false\n}\n```\n``` C#\n// C# - Definition of all functions\nvar functions = connection.Functions;\n// functions[0].Name : function name\n// functions[0].ReturnType : enum void, int, long, ...\n// functions[0].Arguments[0].Name // Name of first argument\n// functions[0].Arguments[0].Type // enum void, int, long, ...\n```\n\n### How to write a variables\n``` C#\n// C#\nconnection.WriteVariable(\"myVar\", 15); // returns true if writting OK\n```\n``` C#\n// C# - Write simultaneously several variables by passing a List\u003cWriteVariable\u003e()\nconnection.WriteVariables(listOfVariablesToWrite);\n```\n``` C#\n// C# - Definition of all variables\nvar variables = connection.Variables;\n// variables[0].Name : variable name\n// variables[0].Type : enum int, long, ...\n```\n\n### How to read variables\n``` C#\n// C#\nvar value = connection.ReadVariable(\"myVar\");\n// value.Status : OK\n// value.Value : 12\n```\n``` C#\n// C# - Read simultaneously several variables\nvar values = connection.ReadVariables(new string[] {\"myVar\", \"anotherVar\", \"yetAnother\"});\n```\n\n### Get board information\n``` C#\n// C#\nvar info = connection.GetInfos();\n// info.Board : Arduino UNO\n// info.CPUFrequency : 16000000 (Hz)\n// a lot more : info.CPlusPlusVersion, info.FunctionMaxCount, info.VariableMaxCount, ...\n```\n\n### Receive and send custom messages\nYou can send and receive classic messages on the serial port with the ```WriteUserData``` functions. Also, the ```UserDataReceived``` event is raised when data is sent by the Arduino.\n\nWarning : it is not possible to read or write variables and call functions in your ```UserDataReceived``` event handler.\n\n``` C#\n// C#\nconnection.WriteUserData(\"Hello!\");\nconnection.WriteUserData(12.2);\nconnection.WriteUserData(new byte[] {0x12, 0x25, 0xFF});\n\n// Event raised when new user data sent by Arduino\nconnection.UserDataReceived += UserDataReceived;\n```\n\n\n### Arduino code\n``` C++\n// C++ Arduino\n#include \u003cSharer.h\u003e\n\n// A simple function that sums an integer and a byte and return an integer\nint Sum(int a, byte b) {\n\treturn a + b;\n}\n\n// a simple integer\nint myVar = 25;\n\nvoid setup() {\n\tSharer.init(115200); // Init Serial communication with 115200 bauds\n\n\t// Expose this function to Sharer : int Sum(int a, byte b) \n\tSharer_ShareFunction(int, Sum, int, a, byte, b);\n\t\n\t// Share system functions\n\tSharer_ShareFunction(bool, digitalRead, uint8_t, pin);\n\tSharer_ShareVoid(pinMode, uint8_t, pin);\n\n\t// Expose this variable to Sharer so that the desktop application can read/write it\n\tSharer_ShareVariable(int, myVar);\n}\n\n// Run Sharer engine in the main Loop\nvoid loop() {\n\tSharer.run();\n}\n```\n\n# Get Started 💪\n## Sources\nSharer is divided into 2 repositories, one for the Arduino sources and the other for .NET sources\n- Arduino : https://github.com/Rufus31415/Sharer\n- .NET : https://github.com/Rufus31415/Sharer.NET\n\n## Download and install Arduino library\n### Library manager\nSharer is available in the library manager available in the menu ```Tools/Manage Libraries...```. Just look for Sharer and install the latest version.\n\n![Sharer in library manager](https://raw.githubusercontent.com/Rufus31415/Sharer/master/Resources/arduino-package-manager.png)\n\n\n### Direct download\nPlease download the Sharer library archive : https://github.com/Rufus31415/Sharer/releases/latest/download/Sharer.zip\n\nSharer has been tested with Arduino UNO, NANO, MEGA and DUE. It may work with other boards.\nExtract so that you get a Sharer directory in your Arduino \"libraries\" directory : ```C:\\Program Files (x86)\\Arduino\\libraries\\Sharer```\n\nYou can then enjoy the examples by restarting your Arduino IDE and go to menu ```File / examples / Sharer```.\n\n## Sharer .NET\n### Nuget\nSharer.NET is available on nuget : https://www.nuget.org/packages/Sharer/\n\nUse this command line to install it with you package manager :\n\n```Install-Package Sharer```\n\n### Download .NET assembly\nSharer.dll assembly can be downloaded here : https://github.com/Rufus31415/Sharer.net/releases/latest/download/SharerAsssemblies.zip\n\nThis archive contains the nuget package Sharer.nupkg and Sharer.dll compiled in AnyCPU Release for the following targets:\n- NET Framework 3.5, 4.0, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8\n- NET Core 2.0, 2.1, 2.2, 3.0, 3.1\n- NET Standard 2.1\n\n### Try examples\n#### Windows Forms\nWindows Forms example requires .NET Framework 3.5. It can be downloaded here : https://github.com/Rufus31415/Sharer.net/releases/latest/download/SharerWindowsFormsExample.zip\n\n![Winforms example](https://raw.githubusercontent.com/Rufus31415/Sharer.NET/master/Resources/winforms.png)\n\n#### Console cross-plateform example\nThe console example run with .NET Core 3.0. But you don't need any runtime to execute it. The standalone console examples are available here :\n- Windows 64 bits : https://github.com/Rufus31415/Sharer.net/releases/latest/download/SharerConsoleExample_win-x64.zip\n- Windows 32 bits : https://github.com/Rufus31415/Sharer.net/releases/latest/download/SharerConsoleExample_win-x86.zip\n- Windows ARM (for example Windows IOT for Raspberry PI) : https://github.com/Rufus31415/Sharer.net/releases/latest/download/SharerConsoleExample_win-arm.zip\n- Linux ARM (for example Raspbian for Raspberry PI) : https://github.com/Rufus31415/Sharer.net/releases/latest/download/SharerConsoleExample_linux-arm.zip\n- Linux 64 bits : https://github.com/Rufus31415/Sharer.net/releases/latest/download/SharerConsoleExample_linux-x64.zip\n- Mac OS X : https://github.com/Rufus31415/Sharer.net/releases/latest/download/SharerConsoleExample_osx-x64.zip\n\n![Console example](https://raw.githubusercontent.com/Rufus31415/Sharer.NET/master/Resources/console.gif)\n\n# License: MIT 😘\n© Rufus31415\nSee the [license file](https://github.com/Rufus31415/Sharer.NET/blob/master/LICENSE) for details.\n\n\n# Usage 🛠️\n## Arduino Usage\n### Initialization\nThe header file \u003cSharer.h\u003e should be included. \n\nIn function ```setup()```, Sharer is initialized by passing a baudrate to function ```Sharer.init(...)```. It internally call ```Serial.init()``` with the same baudrate.\n\nIn function ```loop()```, ```Sharer.run()``` should be called. It runs the internal kernel of Sharer that decodes commands received.\n``` C++\n#include \u003cSharer.h\u003e\n\nvoid setup() {\n\tSharer.init(115200);\n}\n\nvoid loop() {\n\tSharer.run();\n}\n```\n\nYou also can initialize Sharer with another stream, such as the Serial2 of Arduino DUE if you use Serial2 to communication with the desktop application :\n``` C++\nvoid setup() {\n\t// Initialize with another Serial interface\n\tSerial2.begin(9600);\n\tSharer.init(Serial2);\n}\n```\n\n### Share variables\nTo add a variable in the shared variable list, you should call the macro ```Sharer_ShareVariable```. Its first argument is the type of the variable, and the second is its name. This macro allows Sharer to have a pointer to the variable, its name, its type and its memory size.\n``` C++\nbyte myByteVar;\nlong myLongVar;\nint myIntArray[2];\n\nvoid setup() {\n\tSharer.init(115200);\n\t\n\tSharer_ShareVariable(byte, myByteVar);\n\tSharer_ShareVariable(long, myLongVar);\n\tSharer_ShareVariable(int, myIntArray[0]);\n\tSharer_ShareVariable(int, myIntArray[1]);\n}\n```\n\n### Share functions with a return type\nTo add a variable in the shared function list, you should call the macro ```Sharer_ShareFunction```. Its first argument is the returned type, and the second is its name. Following arguments of the macro describe the argument of the shared function by its type and its name. There is no limit in the number of argument you can share, but all arguments should be shared.\n\nClass method sharing is not supported and shared functions must be free functions (non-member static functions). \n\nYou can share your own functions, but all system functions like analogRead, digitalRead, digitalWrite, millis, ...\n\n``` C++\nint Sum(int a, byte b) {\n\treturn a + b;\n}\n\nvoid setup() {\n\tSharer.init(115200);\n\n\t// Share your function to Sharer : int Sum(int a, byte b) \n\tSharer_ShareFunction(int, Sum, int, a, byte, b);\n\t\n\t// Sharer system functions\n\tSharer_ShareFunction(int, analogRead, uint8_t, pin);\n\tSharer_ShareFunction(bool, digitalRead, uint8_t, pin);\n}\n```\n\n### Share void functions\nVoid functions are functions without returned type. You should call the macro ```Sharer_ShareVoid``` to share a void function. The first argument is its name, followed by type and name of each arguments.\n\n``` C++\nvoid TurnLEDOn(void) {\n\tpinMode(13, OUTPUT);\n\tdigitalWrite(13, true);\n}\n\nvoid SetLEDState(bool state) {\n\tpinMode(13, OUTPUT);\n\tdigitalWrite(13, state);\n}\n\nvoid setup() {\n\tSharer.init(115200);\n\t\n\t// Share your void fuctions\n\tSharer_ShareVoid(TurnLEDOn);\n\tSharer_ShareVoid(SetLEDState, bool, state);\n\t\n\t// Sharer system void functions\n\tSharer_ShareVoid(digitalWrite, uint8_t, pin);\n}\n```\n\n### Receive and send regular serial messages\nSharer class inherits from [Stream](https://www.arduino.cc/reference/en/language/functions/communication/stream/), so you can use the following functions. Please, never use Sharer.print(), Sharer.println() or Sharer.write() inside a shared function, writting woud be ignored.\n\n``` C++\nvoid loop() {\n\tSharer.run();\n\t\n\t //gets the number of bytes available in the stream\n\tint available = Sharer.available();\n\t\n\t// reads last reveided byte (-1 if no data to read)\n\tint lastByte = Sharer.read();\n\t\n\t// Empty the stream\n\tSharer.flush();\n\t\n\t// reads data from the serial buffer until the target is found\n\t// returns, true if data is found\n\tbool found = Sharer.find(\"string to find\");\n\t\n\t//Returns the next byte of incoming serial data without removing it from the internal serial buffer\n\t// Successive calls to peek() will return the same character\n\tint nextByte = Sharer.peek();\n\n\t// reads characters from the serial buffer into a String\n\tString str = Sharer.readString();\n\n\t// Looks for the next valid integer in the incoming serial\n\tint lastInt = Sharer.parseInt();\n\tlastInt = Sharer.parseInt(SKIP_ALL); // all characters other than digits or a minus sign are ignored when scanning the stream for an integer. This is the default mode\n\tlastInt = Sharer.parseInt(SKIP_NONE); // nothing is skipped, and the stream is not touched unless the first waiting character is valid.\n\tlastInt = Sharer.parseInt(SKIP_WHITESPACE); // only tabs, spaces, line feeds, and carriage returns are skipped.\n\t\n\t// returns the first valid floating point number from the Serial buffer\n\tfloat lastFloat = Sharer.parseFloat();\n\tlastFloat = Sharer.parseFloat(SKIP_ALL); // all characters other than a minus sign, decimal point, or digits are ignored when scanning the stream for a floating point number. This is the default mode.\n\tlastFloat = Sharer.parseFloat(SKIP_NONE); // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.\n\tlastFloat = Sharer.parseFloat(SKIP_WHITESPACE); // only tabs, spaces, line feeds, and carriage returns are skipped.\n\t\n\t// Prints ASCII encoded string\n\tSharer.print(85); // sends the string \"85\"\n\tSharer.print(1.23456); // sends the string \"1.23\"\n\tSharer.print('N'); // sends the string \"N\"\n\tSharer.print(\"Hello world.\"); // sends the string \"Hello world.\"\n\tSharer.print(78, BIN); // sends the string \"1001110\"\n\tSharer.print(78, OCT); // sends the string \"116\"\n\tSharer.print(78, DEC); // sends the string \"78\"\n\tSharer.print(78, HEX); // sends the string \"4E\"\n\tSharer.print(1.23456, 0); // sends the string \"1\"\n\tSharer.print(1.23456, 2); // sends the string \"1.23\"\n\tSharer.print(1.23456, 4); // sends the string \"1.2345\"\n\tSharer.println(\"Hello ;)\"); // send the string and a new line \"Hello ;)\\n\"\n\tSharer.println(); // just sends a new line\n\t\n\t// Write a single byte\n\tSharer.write(0x12);\n}\n```\n\n### Capabilities\nYou can change the limits of Sharer by editing the constants of file ```C:\\Program Files (x86)\\Arduino\\libraries\\Sharer\\src\\SharerConfig.h```.\n``` C++\n// maximum number of shared functions\n#define _SHARER_MAX_FUNCTION_COUNT\t\t16\n\n// maximum number of shared variables\n#define _SHARER_MAX_VARIABLE_COUNT\t\t32\n\n// circle buffer size for user serial message\n#define _SHARER_USER_RECEIVE_BUFFER_SIZE\t64\n\n// maximum number of call to Serial.read() each time Sharer.Run() is called\n#define _SHARER_MAX_BYTE_READ_PER_RUN\t\t1000\n```\n\n## .NET usage\nYou can find here the full documentation of Sharer.NET : [/Sharer.NET/Sharer.NET.Documentation.md](https://github.com/Rufus31415/Sharer.NET/blob/master/Sharer.NET/Sharer.NET.Documentation.md).\n\n# Performances 🚀\nA command takes less than 10ms to be called on a Arduino Uno (command + response) at 115200 bauds. The protocole is optimized in order not to have strings to decode, just a binary stream to interprete, byte by byte.\nMemory footprint has been optimized by using F() macro and PROGMEM to store names of variable, function and arguments in flash.\n\n# How it works 🤯\nSharer uses a unique protocole called the Sharer Protocole. Every serial commands received by the Arduino are interprated.\n\nTo be continued, I promise... 😉\n\n![Sharer](https://raw.githubusercontent.com/Rufus31415/Sharer.NET/master/Resources/RemoteFunctionCall.png)\n\n\n# Improvement ideas and contributions 🧠\nI have some ideas to extend Sharer features like :\n- Develop Sharer client for other languages like Python and Node.js\n- Add LabView and Matlab examples for research purposes\n- Add other transport layers like TCP and UDP\n- Add a HTTP REST API based on Sharer that exposes endpoints to call functions, and read/write variables.\n\nIf you are interested in helping me with Sharer development, I will be happy to receive feature requests. Fork is also welcome ;)\n\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003c/summary\u003e\n\u003cimg src=\"https://ga-beacon.appspot.com/UA-163892314-2/Sharer/\"\u003e\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frufus31415%2Fsharer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frufus31415%2Fsharer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frufus31415%2Fsharer/lists"}