Sharer es un .NET y una biblioteca Arduino . Permite que una aplicación de escritorio lea/escriba variables y funciones de llamadas remotas en Arduino , utilizando el protocole compartido de una comunicación en serie. Inicialmente, Sharer se ha desarrollado para el Proyecto BallCuber (https://ballcuber.github.io), pero ahora es una biblioteca independiente;).
// C#
var connection = new SharerConnection ( "COM3" , 115200 ) ;
connection . Connect ( ) ; Observación: Para algunos tableros, como Micro y Leonardo, es necesario establecer las señales RTS y DTR con las propiedades RtsEnable y DtrEnable .
// C# - My Arduino code has a function : int Sum(int a, byte b);
var result = connection . Call ( "Sum" , 10 , 12 ) ;
// result.Status : OK
// result.Type : int
// result.Value : 22 // C# - Read all digital pins : digitalRead(0) to digitalRead(13)
for ( int i = 0 ; i <= 13 ; i ++ ) {
var digitalValue = connection . Call ( "digitalRead" , i ) ;
// digitalValue.Status : OK
// digitalValue.Type : bool
// digitalValue.Value : true or false
} // C# - Definition of all functions
var functions = connection . Functions ;
// functions[0].Name : function name
// functions[0].ReturnType : enum void, int, long, ...
// functions[0].Arguments[0].Name // Name of first argument
// functions[0].Arguments[0].Type // enum void, int, long, ... // C#
connection . WriteVariable ( "myVar" , 15 ) ; // returns true if writting OK // C# - Write simultaneously several variables by passing a List<WriteVariable>()
connection . WriteVariables ( listOfVariablesToWrite ) ; // C# - Definition of all variables
var variables = connection . Variables ;
// variables[0].Name : variable name
// variables[0].Type : enum int, long, ... // C#
var value = connection . ReadVariable ( "myVar" ) ;
// value.Status : OK
// value.Value : 12 // C# - Read simultaneously several variables
var values = connection . ReadVariables ( new string [ ] { "myVar" , "anotherVar" , "yetAnother" } ) ; // C#
var info = connection . GetInfos ( ) ;
// info.Board : Arduino UNO
// info.CPUFrequency : 16000000 (Hz)
// a lot more : info.CPlusPlusVersion, info.FunctionMaxCount, info.VariableMaxCount, ... Puede enviar y recibir mensajes clásicos en el puerto serie con las funciones de WriteUserData . Además, el evento UserDataReceived se plantea cuando el Arduino envía datos.
ADVERTENCIA: No es posible leer o escribir variables y llamar a las funciones en su manejador de eventos UserDataReceived .
// C#
connection . WriteUserData ( "Hello!" ) ;
connection . WriteUserData ( 12.2 ) ;
connection . WriteUserData ( new byte [ ] { 0x12 , 0x25 , 0xFF } ) ;
// Event raised when new user data sent by Arduino
connection . UserDataReceived += UserDataReceived ; // C++ Arduino
# include < Sharer.h >
// A simple function that sums an integer and a byte and return an integer
int Sum ( int a, byte b) {
return a + b;
}
// a simple integer
int myVar = 25 ;
void setup () {
Sharer. init ( 115200 ); // Init Serial communication with 115200 bauds
// Expose this function to Sharer : int Sum(int a, byte b)
Sharer_ShareFunction ( int , Sum, int , a, byte, b);
// Share system functions
Sharer_ShareFunction ( bool , digitalRead, uint8_t , pin);
Sharer_ShareVoid (pinMode, uint8_t , pin);
// Expose this variable to Sharer so that the desktop application can read/write it
Sharer_ShareVariable ( int , myVar);
}
// Run Sharer engine in the main Loop
void loop () {
Sharer. run ();
}Sharer se divide en 2 repositorios, uno para las fuentes de Arduino y el otro para las fuentes de .NET
Sharer está disponible en el Administrador de biblioteca disponible en las Tools/Manage Libraries... Solo busque Sharer e instale la última versión.
Descargue el archivo de la biblioteca compartida: https://github.com/rufus31415/sharer/releases/latest/download/sharer.zip
Sharer ha sido probado con Arduino Uno, Nano, Mega y Due. Puede funcionar con otros tableros. Extraiga para obtener un directorio compartido en su directorio de "bibliotecas" de Arduino: C:Program Files (x86)ArduinolibrariesSharer
Luego puede disfrutar de los ejemplos reiniciando su IDE Arduino e ir al File / examples / Sharer .
Sharer.net está disponible en Nuget: https://www.nuget.org/packages/sharer/
Use esta línea de comandos para instalarla con su administrador de paquetes:
Install-Package Sharer
El ensamblaje de Sharer.dll se puede descargar aquí: https://github.com/rufus31415/sharer.net/releases/latest/download/sharerasssemblies.zip
Este archivo contiene el paquete nuget sharer.nupkg y sharer.dll compilado en la versión anycpu para los siguientes objetivos:
El ejemplo de Windows Forms requiere .NET Framework 3.5. Se puede descargar aquí: https://github.com/rufus31415/sharer.net/releases/latest/download/sharerwindowsformsexample.zip
El ejemplo de la consola se ejecuta con .NET Core 3.0. Pero no necesita ningún tiempo de ejecución para ejecutarlo. Los ejemplos de consola independiente están disponibles aquí:
© RUFUS31415 Consulte el archivo de licencia para obtener más detalles.
El archivo de encabezado <Sharer.h> debe incluirse.
En Function setup() , Sharer se inicializa pasando un Baudrate a Function Sharer.init(...) . Llame internamente Serial.init() con el mismo Baudrate.
En function loop() , se debe llamar Sharer.run() . Ejecuta el núcleo interno de Sharer que decodifica los comandos recibidos.
# include < Sharer.h >
void setup () {
Sharer. init ( 115200 );
}
void loop () {
Sharer. run ();
}También puede inicializar a Sharer con otra transmisión, como el Serial2 de Arduino vencido si usa Serial2 para comunicarse con la aplicación de escritorio:
void setup () {
// Initialize with another Serial interface
Serial2. begin ( 9600 );
Sharer. init (Serial2);
} Para agregar una variable en la lista de variables compartidas, debe llamar al macro Sharer_ShareVariable . Su primer argumento es el tipo de variable, y el segundo es su nombre. Esta macro permite que Sharer tenga un puntero a la variable, su nombre, su tipo y su tamaño de memoria.
byte myByteVar;
long myLongVar;
int myIntArray[ 2 ];
void setup () {
Sharer. init ( 115200 );
Sharer_ShareVariable (byte, myByteVar);
Sharer_ShareVariable ( long , myLongVar);
Sharer_ShareVariable ( int , myIntArray[ 0 ]);
Sharer_ShareVariable ( int , myIntArray[ 1 ]);
} Para agregar una variable en la lista de funciones compartidas, debe llamar a Macro Sharer_ShareFunction . Su primer argumento es el tipo devuelto, y el segundo es su nombre. Siguiendo los argumentos de la macro describe el argumento de la función compartida por su tipo y su nombre. No hay límite en el número de argumentos que puede compartir, pero todos los argumentos deben compartirse.
El intercambio de métodos de clase no es compatible y las funciones compartidas deben ser funciones gratuitas (funciones estáticas no miembros).
Puede compartir sus propias funciones, pero todas las funciones del sistema como Analogread, DigitalRead, DigitalWrite, Millis, ...
int Sum ( int a, byte b) {
return a + b;
}
void setup () {
Sharer. init ( 115200 );
// Share your function to Sharer : int Sum(int a, byte b)
Sharer_ShareFunction ( int , Sum, int , a, byte, b);
// Sharer system functions
Sharer_ShareFunction ( int , analogRead, uint8_t , pin);
Sharer_ShareFunction ( bool , digitalRead, uint8_t , pin);
} Las funciones vacías son funciones sin tipo devuelto. Debe llamar a Macro Sharer_ShareVoid para compartir una función vacía. El primer argumento es su nombre, seguido de tipo y nombre de cada argumento.
void TurnLEDOn ( void ) {
pinMode ( 13 , OUTPUT);
digitalWrite ( 13 , true );
}
void SetLEDState ( bool state) {
pinMode ( 13 , OUTPUT);
digitalWrite ( 13 , state);
}
void setup () {
Sharer. init ( 115200 );
// Share your void fuctions
Sharer_ShareVoid (TurnLEDOn);
Sharer_ShareVoid (SetLEDState, bool , state);
// Sharer system void functions
Sharer_ShareVoid (digitalWrite, uint8_t , pin);
}La clase compartida hereda de la transmisión, por lo que puede usar las siguientes funciones. Por favor, nunca use Sharer.print (), ShareR.println () o Sharer.Write () dentro de una función compartida, se ignorará la escritura.
void loop () {
Sharer. run ();
// gets the number of bytes available in the stream
int available = Sharer. available ();
// reads last reveided byte (-1 if no data to read)
int lastByte = Sharer. read ();
// Empty the stream
Sharer. flush ();
// reads data from the serial buffer until the target is found
// returns, true if data is found
bool found = Sharer. find ( " string to find " );
// Returns the next byte of incoming serial data without removing it from the internal serial buffer
// Successive calls to peek() will return the same character
int nextByte = Sharer. peek ();
// reads characters from the serial buffer into a String
String str = Sharer. readString ();
// Looks for the next valid integer in the incoming serial
int lastInt = Sharer. parseInt ();
lastInt = 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
lastInt = Sharer. parseInt (SKIP_NONE); // nothing is skipped, and the stream is not touched unless the first waiting character is valid.
lastInt = Sharer. parseInt (SKIP_WHITESPACE); // only tabs, spaces, line feeds, and carriage returns are skipped.
// returns the first valid floating point number from the Serial buffer
float lastFloat = Sharer. parseFloat ();
lastFloat = 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.
lastFloat = Sharer. parseFloat (SKIP_NONE); // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
lastFloat = Sharer. parseFloat (SKIP_WHITESPACE); // only tabs, spaces, line feeds, and carriage returns are skipped.
// Prints ASCII encoded string
Sharer. print ( 85 ); // sends the string "85"
Sharer. print ( 1.23456 ); // sends the string "1.23"
Sharer. print ( ' N ' ); // sends the string "N"
Sharer. print ( " Hello world. " ); // sends the string "Hello world."
Sharer. print ( 78 , BIN); // sends the string "1001110"
Sharer. print ( 78 , OCT); // sends the string "116"
Sharer. print ( 78 , DEC); // sends the string "78"
Sharer. print ( 78 , HEX); // sends the string "4E"
Sharer. print ( 1.23456 , 0 ); // sends the string "1"
Sharer. print ( 1.23456 , 2 ); // sends the string "1.23"
Sharer. print ( 1.23456 , 4 ); // sends the string "1.2345"
Sharer. println ( " Hello ;) " ); // send the string and a new line "Hello ;)n"
Sharer. println (); // just sends a new line
// Write a single byte
Sharer. write ( 0x12 );
} Puede cambiar los límites de Sharer editando las constantes del archivo C:Program Files (x86)ArduinolibrariesSharersrcSharerConfig.h .
// maximum number of shared functions
# define _SHARER_MAX_FUNCTION_COUNT 16
// maximum number of shared variables
# define _SHARER_MAX_VARIABLE_COUNT 32
// circle buffer size for user serial message
# define _SHARER_USER_RECEIVE_BUFFER_SIZE 64
// maximum number of call to Serial.read() each time Sharer.Run() is called
# define _SHARER_MAX_BYTE_READ_PER_RUN 1000 Puede encontrar aquí la documentación completa de Sharer.net: /sharer.net/sharer.net.documentation.md.
Un comando tarda menos de 10 ms para ser llamados en un Arduino Uno (comando + respuesta) a 115200 baudios. El protocole está optimizado para no tener cadenas para decodificar, solo una secuencia binaria para interpretar, byte por byte. La huella de memoria se ha optimizado utilizando f () macro y progmem para almacenar nombres de variables, función y argumentos en flash.
Sharer utiliza un protocolo único llamado Protocolo Sharer. Todos los comandos en serie recibidos por el Arduino están interrumpidos.
Para continuar, lo prometo ...
Tengo algunas ideas para extender las características compartidas como:
Si está interesado en ayudarme con el desarrollo compartido, estaré encantado de recibir solicitudes de funciones. Fork también es bienvenido;)