Este artículo proviene de un motor de traducción automática.
Robótica
Escritura y evaluación de servicios de VPL para comunicación en serie
Trevor Taylor
Microsoft Robotics Developer Studio (RDS) es, como cabría esperar, una plataforma para la programación de robots. RDS se incluye en primer lugar en 2006 y la versión más reciente, RDS 2008 R2, se lanzó en junio de 2009.
RDS consta de cuatro componentes principales: la concurrencia y en tiempo de ejecución de coordinación (CCR) descentralizada Software Services (DSS), lenguaje de programación Visual (VPL) y entorno de simulación visual (VSE). Sara Morgan escribió acerca de VSE en el número de junio de 2008 de MSDN Magazine (MSDN.Microsoft.com/magazine/cc546547).
VPL, sin embargo, es más pertinente para este artículo. VPL es un lenguaje de flujo de datos, lo que significa que crear programas dibujando diagramas en la pantalla. En tiempo de ejecución, los mensajes fluyen desde un bloque a otra en el diagrama y este flujo de datos eficaz es la ruta de acceso de ejecución del programa. Dado que VPL se ha creado en la parte superior del CCR y DSS, dataflows pueden producirse asincrónicamente (como resultado de las notificaciones de servicios) y también puede ejecutar en paralelo. Mientras VPL está pensada para los programadores inexpertos, codificadores experimentados pueden también resultar útil para el desarrollo de prototipos.
En este artículo se describen un sencillo servicio RDS que le permite enviar y recibir datos utilizando un puerto serie (también conocido como un puerto COM). El código de ejemplo ilustra algunos de los conceptos claves implicados en la escritura de servicios reutilizables de RDS.
Para obtener más información acerca de RDS y descargar la plataforma, vaya a microsoft.com/robotics. El paquete incluye un archivo de Ayuda útiles, que también está disponible en msdn.microsoft.com/library/dd936006. Puede obtener ayuda adicional mediante el registro de preguntas a los foros de discusión Robotics diversos en social.msdn.Microsoft.com/Forums/en-us/Category/Robotics.
Servicios RDS
Servicios RDS se generan con CCR y DSS. Son conceptualmente similares a los servicios Web porque RDS tiene una arquitectura orientada a servicios (SOA) basada en un modelo de transferencia de estado de representación (REST) mediante el protocolo de servicios de software descentralizada (DSSP) para la comunicación entre servicios. Encontrar a través de este Sopa, esto significa que usted no habla directamente a los servicios RDS. En su lugar, enviar mensajes a un proxy, que actúa como la interfaz externa al servicio (los desarrolladores de Web de un enfoque estarán familiarizados con). También significa que se pueden distribuir servicios en cualquier parte de la red.
Utilizar a un proxy tiene dos efectos. En primer lugar, los mensajes enviados entre los servicios se serializan antes de la transmisión y deserializados en el otro extremo. XML es el formato habitual para los datos que se transmiten. En segundo lugar, el proxy define un contrato: eficazmente el conjunto de API que están expuestos a otros servicios.
Cada servicio tiene un estado interno, que puede recuperar o modificar operaciones en el servicio. Estos implican enviar un mensaje de solicitud y esperar a un mensaje de respuesta en un proceso similar a la utilizada por la mayoría de los servicios Web.
Cuando se cambia el estado del servicio, puede enviar notificaciones a los suscriptores. Este enfoque de publicación y suscripción distingue RDS servicios de servicios Web tradicionales porque se envían mensajes de notificación asincrónicamente a los suscriptores.
Cuando se genera un nuevo servicio, automáticamente se hace visible en VPL y puede comenzar a utilizar inmediatamente. Esto es una de las características clave de RDS y facilita las pruebas y desarrollo de prototipos muy — Don tiene que escribir mazos de prueba en C#, ya que se puede utilizar VPL.
Controlar un robot de forma remota
Muchos robots educativos simples tienen Microcontroladores 8 o 16 bits para su cerebro a bordo. Pero como RDS se ejecuta en .NET Framework en Windows, no genere código que puede ejecutar directamente en estos robots. Deben controlarse remotamente a través un vínculo de comunicaciones, en su lugar. (La alternativa es tener un equipo a bordo, como, por ejemplo, 3DX MobileRobots Pioneer).
Desde la mayoría de Microcontroladores compatible con puertos serie, una conexión serie es la solución obvia. Sin embargo, no proporciona el vínculo mediante un cable es ideal: limita movilidad del robot.
Como alternativa, puede utilizar Bluetooth para crear una conexión inalámbrica instalando un dispositivo serie para Bluetooth en el robot. Algunos robots, como el NXT LEGO vienen con Bluetooth integrado. Otras, como el RoboticsConnection Stinger tienen módulos opcionales de Bluetooth. Bluetooth es una buena elección, dado que es estándar en la mayoría de los equipos portátiles en estos días. Incluso si su PC no tiene Bluetooth, encontrará dispositivos USB Bluetooth económicos, fácilmente disponibles.
La buena noticia es que usted Don tiene que saber nada acerca de la programación Bluetooth porque la conexión con el robot aparecerá como un puerto serie virtual. Puede utilizar el mismo código, como lo haría si un cable físico proporciona la conexión serie. La única diferencia es que tiene que establecer un emparejamiento entre su PC y el dispositivo Bluetooth en el robot por lo que se creará un puerto COM virtual.
Algunas placas de controlador de robot tiene firmware que puede aceptar comandos mediante un lenguaje de comandos simple. Por ejemplo, con el serializador de RoboticsConnection (que obtiene su nombre de su uso de un protocolo de serie), puede escribir comandos para el controlador a través de un programa terminal como HyperTerminal. Los comandos están todas legibles y terminar cada presionando Escriba.
Si va a diseñar su propio protocolo para uso con un robot, deberá realizar algunas elecciones. En primer lugar, debe decidir si va a enviar datos binarios. Convertir los valores binarios a hexadecimal o decimal para la transmisión requiere más ancho de banda y aumenta el procesamiento sobrecarga de CPU a bordo. Por otro lado, hace que leer los mensajes mucho más fácil y no experimenta ningún comportamiento extraño debido a caracteres de control misinterpreted.
La siguiente pregunta es si desea utilizar los paquetes de longitud fija o un formato más flexible de longitud variable. Longitud fija es más fácil analizar y funciona mejor con formato hexadecimal.
También debe considerar si debe utilizar una suma de comprobación. Para la comunicación de equipo a equipo calcular verificación dígitos es fácil. Si, sin embargo, desea probar su robot escribiendo comandos manualmente, averiguar los dígitos de verificación obtiene muy complicado. Al usar sumas de comprobación, typically el receptor envía seguridad una confirmación (ACK) o reconocimiento negativo (NAK) dependiendo de si el comando suministrado a través de correctamente o no. Su decisión sobre el uso de una suma de comprobación realmente llega hacia abajo a la confiabilidad de la conexión.
El servicio SerialPort
Debería ser evidente por ahora por qué un servicio de puerto serie sería útil. Sin embargo, el paquete RDS no incluye un servicio, aunque muchas de las muestras del robot utilizan vínculos de comunicaciones serie. Si explora el código de ejemplo RDS, encontrará cada ejemplo que controla el puerto serie diferente. En este artículo se describe un enfoque del uso de un puerto serie. No es la única manera de hacerlo y no necesariamente la mejor opción.
Antes de pasar cualquiera aún más, asegúrese de que ha descargado y instalado RDS. La descarga de este artículo contiene el código fuente del servicio SerialPort. Descomprímalo en una carpeta bajo el directorio de instalación de RDS (también conocido como el punto de montaje). Separar de nota que debe mantener el código de la carpeta de ejemplos que se incluye con RDS por lo tanto, que le Don mezclar el código con el código de Microsoft. También, se recomienda colocar el código debajo del punto de montaje RDS, y no en otro lugar en el disco duro, porque simplifica el desarrollo. Tengo una carpeta de proyectos donde puedo mantener mi propio código en subcarpetas, facilitando la tarea de copia de seguridad.
Los archivos principales en el código fuente del SerialPort son SerialPort.cs, SerialPortTypes.cs y SerialPort.manifest.xml.
SerialPort.cs contiene la implementación del servicio o el comportamiento. Compuesta de la propia clase del servicio, que contiene los controladores de operación, además de los requeridos compatible con métodos y variables.
SerialPortTypes.cs contiene las definiciones del estado del servicio, los tipos de operación y tipos de mensajes. En efecto, describe la interfaz al servicio y no debe contener ningún código ejecutable. Se trata de un punto clave acerca de un contrato de servicio, es sólo una definición de datos.
SerialPort.manifest.xml se denomina el manifiesto y describe cómo se combinan, o servicios orquestados para ejecutar una aplicación. Este archivo se utiliza como entrada para la utilidad DssHost, que crea un nodo DSS servicios se ejecutan dentro de. En este caso el manifiesto sólo ejecuta el servicio SerialPort, que es bastante inútil. Un manifiesto útil especificaría también otros servicios que dependen del servicio SerialPort para realizar conexiones.
Antes de utilizar el servicio SerialPort, debe ejecutar la herramienta DssProjectMigration y vuelva a compilar el servicio. Abra un símbolo de DSS (busque en RDS en el menú Inicio) y asegúrese de que las rutas de acceso se configuran por lo que se pueden ejecutar archivos en la carpeta \bin. A continuación, cambie al directorio donde se han descomprimido el código y escriba el comando siguiente:
Dssprojectmigration /b- .
Significa el /b-option Don crear una copia de seguridad y el carácter de punto (.) hace referencia al directorio actual.
Puede compilar el servicio en Visual Studio o hacerlo desde la línea de comandos escribiendo:
Msbuild serialport.sln
Compilar el servicio genera el archivo DLL de servicio, un archivo DLL del servidor proxy y una transformación (Esto se traduce los tipos de datos entre el archivo DLL de servicio y el proxy). Todos éstos se colocarán en la carpeta \bin bajo mountpoint RDS. También debe conservar juntos los archivos de manifiesto y config, cópielas en la carpeta \Ejemplos\config (aunque no es esencial).
El contrato de servicio
Cada servicio tiene un identificador único del contrato, que se declara en el archivo Types.cs y se parece a una dirección URL. Sin embargo, tenga en cuenta que no tiene importancia en el Web y utilizando un identificador de estilo de dirección URL es simplemente una forma cómoda para garantizar la unicidad al permitir a las organizaciones crear sus propios espacios de nombres. (Para los proyectos deberá utilizar un espacio de nombres distinto microsoft.com/robotics.) SerialPortTypes.cs contiene la siguiente definición:
public sealed class Contract {
[DataMember]
public const string Identifier = "http://www.promrds.com/contracts/2009/12/serialport.html";
}
Un contrato de servicio también incluye el estado y las operaciones que definen qué propiedades pueden manipular otros servicios y cómo. SerialPortState (consulte La figura 1) incluye la configuración de puerto serie, algunos parámetros para los tiempos de espera y el último byte recibidas al funcionar de forma asincrónica.
Figura 1 SerialPortState
[DataContract]
public class SerialPortState {
private bool _openOnStart;
private bool _asynchronous;
private SerialPortConfig _config;
private byte _lastByteReceived;
private bool _isOpen;
// Open the COM port when the service starts
// Must be set in config file
[DataMember]
public bool OpenOnStart {
get { return _openOnStart; }
set { _openOnStart = value; }
}
// Operate in Asynchronous mode
[DataMember]
public bool Asynchronous {
get { return _asynchronous; }
set { _asynchronous = value; }
}
// Configuration parameters for the serial port
[DataMember]
public SerialPortConfig Config {
get { return _config; }
set { _config = value; }
}
// Last byte received from the serial port
[DataMember]
public byte LastByteReceived {
get { return _lastByteReceived; }
set { _lastByteReceived = value; }
}
// Indicates if the port is currently open
[DataMember]
public bool IsOpen {
get { return _isOpen; }
set { _isOpen = value; }
}
}
Puede definir sus propios tipos de datos para su uso en los tipos de estado y el mensaje. En este servicio, hay una clase SerialPortConfig. Para que sean visibles en el servidor proxy, debe ser pública y marcada con el atributo [DataContract]. Cada propiedad en la clase se debe declarar como público y también se etiquetan mediante el atributo [DataMember]. Si no está hecho, la propiedad no estará accesible.
También puede exponer las enumeraciones públicas, de ese modo otros programadores no es necesario utilizar números de magia en código que utiliza el servicio. Es una buena práctica demasiado, de programación porque permite comprobar el tipo de datos.
Al diseñar un servicio, tendrá que decidir cómo otros servicios interactúan con él. Este servicio SerialPort admite las siguientes operaciones que se enumeran a continuación en grupos lógicos:
- Obtener, suscribirse
- ReceiveByte
- SetConfig, abrir, cerrar, ClearBuffers
- ReadString ReadByte ReadByteArray,
- WriteString WriteByte WriteByteArray,
Tenga en cuenta que la operación ReceiveByte es para uso interno por el servicio propio y no debería ser utilizada por otros servicios. Más adelante hablaremos sobre esto.
Las operaciones de lectura y escritura son sincrónicas todo: el servicio no responde hasta que se haya completado la operación. Si abre el puerto serie en modo asincrónico (que se explica más adelante), el servicio enviará una notificación de ReceiveByte por cada byte recibido y no debe utilizar las operaciones de lectura. Sin embargo, las operaciones de escritura, siempre son sincrónicas.
Cada operación tiene un tipo de mensaje de solicitud y un tipo de mensaje de respuesta. Algunos de ellos podrían tener propiedades y otros estará vacíos, el tipo de datos es suficiente para transmitir el mensaje apropiado.
Comportamiento de servicio
Como mencionamos anteriormente, el código ejecutable del servicio está en SerialPort.cs. Todos los servicios se derivan de DsspServiceBase, que proporciona una serie de propiedades y métodos auxiliares. Cuando se inicia un servicio, se llama a su método de inicio:
protected override void Start() {
InitializeState();
base.Start();
if (_state.OpenOnStart)
OpenPort();
}
Inicio se encarga de inicializar el estado (si es necesario) y, a continuación, abra el puerto serie automáticamente si OpenOnStart se especificó en el archivo de configuración (que se explica más adelante).
Cada operación admitida por un servicio debe tener un controlador de servicio. Pero algunas operaciones, como GET y colocar están controlados por la infraestructura (a menos que se desea reemplazar el comportamiento predeterminado).
El OpenHandler muestra un controlador muy simple:
[ServiceHandler]
public void OpenHandler(Open open) {
// Remember the Asynchronous flag
_state.Asynchronous = open.Body.Asynchronous;
if (OpenPort()) {
open.ResponsePort.Post(
DefaultSubmitResponseType.Instance);
}
else {
throw (new Exception(“Open Failed”));
}
}
Este controlador llama OpenPort, un método interno. Si es correcta, se registra volver una respuesta. Puesto que no hay información tiene que se va a devolver, se trata simplemente una respuesta predeterminada proporcionada por DSS.
Si se produce un error en el abierto, se produce una excepción. DSS detecta la excepción y la convierte a un error en el, que se envía como respuesta. Aunque no obvio, si se produce una excepción en OpenPort, también se traspasarse a otro nivel y devolver un error.
No es necesario explicar todos del método OpenPort, pero un punto es importante, puede abrir el puerto serie para la operación sincrónica o asincrónica. Las en el modo sincrónico, todas solicitudes de lectura y escritura completas antes de devolver una respuesta. Sin embargo, si abre en modo asincrónico, las notificaciones se envían para cada carácter recibido. Para hacer este trabajo, el código establece un controlador de eventos convencional:
if (_state.Asynchronous) {
// Set up an Event Handler for received characters
sp.ReceivedBytesThreshold = 1;
sp.DataReceived += new SerialDataReceivedEventHandler(
DataReceivedHandler);
}
El controlador de eventos se muestra en Figura 2. Este controlador se ejecuta en un subproceso. NET. Pero para interoperar con DSS, debe conmutarse a un subproceso CCR, por lo que el código expone una solicitud ReceiveByte en el puerto de operaciones principales del servicio. Después de contabilizar una solicitud, el código debe recibir la respuesta; en caso contrario, será una pérdida de memoria. Este es el propósito de Arbiter.Choice, que utiliza la notación abreviada de C# para delegados anónimos para controlar las dos respuestas posibles. Es necesario para colocar el receptor Choice en la cola activa un Activate. Sólo un fallo es relevante en este caso, y un resultado correcto no hace nada.
Figura 2 Identificador de sucesos
void DataReceivedHandler(object sender,
SerialDataReceivedEventArgs e) {
int data;
while (sp.BytesToRead > 0) {
// Read a byte - this will return immediately because
// we know that there is data available
data = sp.ReadByte();
// Post the byte to our own main port so that
// notifications will be sent out
ReceiveByte rb = new ReceiveByte();
rb.Body.Data = (byte)data;
_mainPort.Post(rb);
Activate(Arbiter.Choice(rb.ResponsePort,
success => { },
fault => { LogError("ReceiveByte failed"); }
));
}
}
El controlador ReceiveByte se ejecutará a continuación para procesar el carácter de nueva:
[ServiceHandler]
public void ReceiveByteHandler(ReceiveByte recv) {
_state.LastByteReceived = recv.Body.Data;
// Send a notification, but only if in asynch mode
if (_state.Asynchronous)
SendNotification(_submgrPort, recv);
recv.ResponsePort.Post(DefaultUpdateResponseType.Instance);
}
El atributo [DmServer] permite DSS enlazar el controlador para el puerto de las operaciones durante la inicialización del servicio. El controlador envía una notificación a los suscriptores y, a continuación, devuelve una respuesta que decía que la operación de datos. (Servicios que deseen recibir notificaciones deben enviar una operación de suscribirse al servicio SerialPort).
Leen los controladores de servicio para el otro y las operaciones de escritura son bastante fácil de entender. El WriteStringHandler (consulte Figura 3) contiene una arruga pequeña, sin embargo, puede insertar un pequeño retraso entre el envío de caracteres. Esto está diseñado para ayudar a Microcontroladores más lento que quizás no pueda mantenerse si los datos se envían a la velocidad máxima, dispositivos de especially como el BasicStamp bit banging y Don tienen un hardware asíncrono universal transmisor-receptor (UART), por lo que realizar E/s serie en software.
Figura 3 WriteStringHandler
[ServiceHandler]
public virtual IEnumerator<ITask> WriteStringHandler(
WriteString write) {
if (!_state.IsOpen) {
throw (new Exception("Port not open"));
}
// Check the parameters - An empty string is valid, but not null
if (write.Body.DataString == null)
throw (new Exception("Invalid Parameters"));
// NOTE: This might hang forever if the comms link is broken
// and you have not set a timeout. On the other hand, if there
// is a timeout then an exception will be raised which is
// handled automatically by DSS and returned as a Fault.
if (_state.Config.InterCharacterDelay > 0) {
byte[] data = new byte[1];
for (int i = 0; i < write.Body.DataString.Length; i++) {
data[0] = (byte)write.Body.DataString[i];
sp.Write(data, 0, 1);
yield return Timeout(_state.Config.InterCharacterDelay);
}
sp.WriteLine("");
}
else
sp.WriteLine(write.Body.DataString);
// Send back an acknowledgement now that the data is sent
write.ResponsePort.Post(DefaultSubmitResponseType.Instance);
yield break;
}
Otro punto acerca de este controlador es que es un elemento de iteración. Observe la declaración del método como IEnumerator <itask>y el hecho de que utiliza yield para devolver yield break. Esta característica del lenguaje C# permite CCR suspender tareas sin bloquear un subproceso. Cuando se ejecuta yield return, el subproceso que ejecuta el método se devuelve al grupo. Una vez finalizado el tiempo de espera, vuelve envía un mensaje que hace que la ejecución Reanudar, aunque posiblemente en un subproceso diferente.
Configuración del servicio
Un archivo de configuración es una versión XML serializado del estado de servicio que se carga durante la inicialización del servicio. Es una buena idea para admitir un archivo de configuración, ya que permite cambiar el comportamiento del servicio sin tener que volver a compilar. Esto es especialmente importante para establecer el número de puerto COM.
Puede especificar el nombre del archivo en el servicio cuando se declara la instancia de estado (en SerialPort.cs):
[ServiceState]
// Add an initial state partner to read the config file
[InitialStatePartner(Optional = true,
ServiceUri = "SerialPort.Config.xml")]
SerialPortState _state = new SerialPortState();
En este caso hemos declarado config como opcionales; de lo contrario, el servicio no se iniciará si no se encuentra el archivo de config. Por otro lado, esto significa que debe comprobar el estado en el método de inicio del servicio e inicializar algunos valores predeterminados razonables si es necesario.
Porque no se especificó ninguna ruta para el ServiceUri, DSS asumirá que el archivo es en la misma carpeta que el manifiesto utilizada para iniciar el servicio. Figura 4 muestra el contenido de un archivo de configuración típica.
Figura 4 Archivo de configuración de SerialPortState
<?xml version="1.0" encoding="utf-8"?>
<SerialPortState
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns=http://www.promrds.com/contracts/2009/12/serialport.html
>
<OpenOnStart>false</OpenOnStart>
<Asynchronous>false</Asynchronous>
<Config>
<PortNumber>1</PortNumber>
<BaudRate>57600</BaudRate>
<Parity>None</Parity>
<DataBits>8</DataBits>
<StopBits>One</StopBits>
<ReadTimeout>0</ReadTimeout>
<WriteTimeout>0</WriteTimeout>
<InterCharacterDelay>0</InterCharacterDelay>
</Config>
<LastByteReceived>0</LastByteReceived>
<IsOpen>false</IsOpen>
</SerialPortState>
Tenga en cuenta que este archivo de config no solicita el servicio para abrir el puerto COM automáticamente, por lo que deba enviar una solicitud de abrir.
Si desea que su servicio tenga un aspecto profesional, debe prestar atención a detalles como la descripción de servicio y los iconos. Incluso si se Don va a utilizar VPL usted mismo, es una buena idea para probar su servicio en VPL y hacerla VPL fáciles por lo que pueden utilizar otras personas fácilmente.
Puede decorar la clase de servicio con dos atributos que describen el servicio:
[DisplayName("Serial Port Service")]
[Description("SerialPort service provides access to a Serial (COM) Port")]
Muestra el primer atributo como el nombre del servicio en la lista de servicio VPL (consulte Figura 5), y el segundo atributo aparece como información sobre herramientas si mueve el mouse sobre el nombre del servicio en la lista.
Figura 5 Lista de servicios VPL
Si tiene un sitio Web y desea documentar sus servicios en línea, se puede conectar otro atributo a la clase de servicio para proporcionar el hipervínculo:
[DssServiceDescription("http://www.promrds.com/SerialPort.htm")]
Cuando VPL ve este atributo, agrega un icono de información pequeño (“ i ” en un disco de azul de blanco) junto al servicio en la lista de servicio.
Si Agregar iconos a su servicio, lo cual puede realizarse fácilmente, aparecerán en diagramas VPL y en la lista de servicio. Observe el icono pequeño, denominado vista en miniatura, junto al nombre del servicio en Figura 5. Figura 6 ilustra la versión más grande de icono, que se mostrará dentro del bloque que aparece en los diagramas de VPL.
Figura 6 Bloque de servicio
Al agregar estas imágenes a un proyecto, asegúrese de que cambie las propiedades de archivo, de modo que se establezca el valor de acción de generación en recurso incrustado. PNG es el formato de archivo preferido, ya que es compatible con un canal alfa. Esto le permite crear un icono con un fondo transparente estableciendo el valor alfa en el color de fondo a cero.
La imagen del icono de servicio debe ser 32 por 32 píxeles y la miniatura de 16 por 16. Los nombres de archivo de las imágenes deben comenzar con el nombre de clase de servicio, en este caso SerialPortService. Por lo tanto se han efectuado los nombres de archivo para mi ejemplo SerialPortService.Image.png y SerialPortService.Thumbnail.png.
Uso del servicio
El servicio es bastante flexible. Puede especificar la configuración de puerto serie en un archivo de configuración (que es la manera más común) o enviando una solicitud SetConfig. Una vez haya establecido la configuración, se puede llamar a la operación Open. Para mayor comodidad, un indicador en el archivo de configuración hará que el servicio abrir el puerto automáticamente en el inicio. Si el puerto ya está abierto, la llamada a Open se primero cierre y, a continuación, vuelva a abrirlo.
Debe decidir cómo desea utilizar el servicio: forma sincrónica o asincrónica. Cuando funciona sincrónicamente, cada lectura o escritura petición esperará hasta que finaliza la operación antes de enviar una respuesta de vuelta. En términos de VPL, éste es un enfoque sencillo, porque se detendrá el flujo de mensajes en el bloque SerialPort en el diagrama. Tenga en cuenta que la operación asincrónica no es totalmente asincrónico: escribir operaciones siguen producen sincrónicamente. Pero todos los bytes recibidos se envían como una notificación a los suscriptores.
En teoría, cada operación de modificación de estado en un servicio debe hacer que una notificación se envía para que los suscriptores pueden mantener su propia versión en caché del estado del servicio. Esto significa que todas las operaciones basándose en las operaciones de reemplazar DSSP, Update, INSERT, DELETE y Upsert deben enviar una notificación correspondiente. Sin embargo, los desarrolladores a menudo reproducción rápida y no estricta con este requisito.
Por motivos de simplicidad, el servicio SerialPort sólo envía notificaciones utilizando el tipo de operación ReceiveByte en el modo asincrónico. Open, Close, y operaciones SetConfig también provocan notificaciones para enviarse.
Porque las operaciones de lectura y escritura no modifican el estado, son una subclase fuera de la operación enviar DSSP. Por supuesto, tienen un efecto lateral, que consiste en recibir y enviar datos a través del vínculo de serie.
Pruebas con VPL
La descarga de este artículo incluye dos programas de VPL de ejemplo (EchoAsynch y EchoSynch, se muestra cómo utilizar el servicio en modo asincrónico (a través de notificaciones) y el modo sincrónico. Los ejemplos VPL utilizan archivos de configuración para establecer los parámetros iniciales para el puerto COM, incluido el número de puerto (que se establece en 21 en los archivos config y debe cambiarse para que coincida con dirección de puerto COM del equipo).
Tenga en cuenta que para probar el servicio será necesario un cable de módem nulo y dos equipos con puertos serie o dos puertos en el mismo equipo. Dispositivos de USB a serie están fácilmente disponibles, por lo que es bastante factible tener varios puertos serie en un mismo computador. Cuando tenga los puertos COM conectados entre sí, ejecute un emulador de terminal como HyperTerminal y conéctese a uno de los puertos COM. Comience ejecutando el programa EchoAsynch VPL en el otro puerto serie. (VPL puede encontrar en el menú Inicio, en RDS). Cuando se escribe en la ventana emulador de terminal, debería ver los caracteres que se muestra.
Puede utilizar VPL para crear archivos de configuración. Haga clic en un bloque de servicio SerialPort en el diagrama y busque en el panel Propiedades. Verá algo parecido a Figura 7. Asegúrese de que el númeroDePuerto está establecida correctamente para su PC. (Debe ser el puerto de serie, no en la que abrió en el emulador de terminal). Observará que la paridad y StopBits son listas desplegables. Las entradas de estas listas proceder directamente de las enumeraciones definidas en SerialPortTypes.cs.
Figura 7 Configuración del servicio de puerto serie
Se trata de un único lugar donde comentarios de documentación XML útiles. Colocar el puntero del mouse sobre un parámetro de configuración con el cursor del mouse (ratón), una información sobre herramientas emergerá que muestra el comentario correspondiente para cada Estado miembro.
Cuando ejecute el programa de EchoAsynch VPL, la primera parte del programa en Figura 8 abre el puerto serie en modo asincrónico.
Figura 8 Abre el puerto serie en modo asincrónico
Si ha especificado valores no válidos en la configuración, como una tasa de baudios incorrecta, se producirá un error en el campo Abrir. (Es posible que se produzcan también errores si el puerto COM está en uso, el puerto no existe o no tiene permisos adecuados). Éste es el motivo por el programa busca un error y lo muestra.
El resto del programa (consulte Figura 9) sólo el eco cada carácter recibido. Esto se consigue teniendo los caracteres desde ReceiveByte notificaciones diseñados y enviándolos mediante WriteByte.
Para facilitar la lectura de la salida, un retorno de carro (ASCII 13, decimal) de carácter tiene un avance de línea (10) anexado por lo que el cursor se desplaza a la línea siguiente en la ventana del emulador de terminal. Tenga en cuenta que todos los SerialPortService se bloquea en Figura 9 diagrama hacen referencia a la misma instancia del servicio.
Figura 9 Programa EchoAsynch
El programa EchoSynch VPL (consulte Figura 10) utiliza el modo sincrónico de operación: no utilizar las notificaciones. (De hecho, las notificaciones no se nunca envían en el modo sincrónico).
Figura 10 El programa EchoSynch
A diferencia del programa anterior, éste utiliza ReadString y WriteString a los datos de eco. Estas operaciones realizan funciones similares a las de ReadByteArray y WriteByteArray, sin embargo, las cadenas son fáciles de controlar en VPL sean matrices de bytes.
Las operaciones de cadena que la utilice un carácter de avance de línea (o carácter de nueva línea) como marcador de fin de línea. Por lo tanto, ReadString finaliza al presionar la tecla avance de línea (CTRL-J) no cuando presione ENTRAR. Esto puede confundir la primera vez que pruebe el programa mediante un emulador de Terminal Server, porque puede estar preguntando por qué no hay nada está devolviendo el eco. WriteString agrega un retorno de carro y avance de línea a los resultados para que cada cadena aparezca en una línea independiente.
Tenga en cuenta que el archivo de configuración EchoSynch un InterCharacterDelay de 500 ms. Esto hace que las cadenas que se van a enviarse muy lentamente. Pruebe a cambiar este valor.
Trevor Taylor PH.d., es el Administrador de programas de Robotics Studio Developer en Microsoft. Es el coautor con Kyle Johns, de “ Professional Robotics Developer Studio ” (Wrox, 2008). Código de ejemplo desde el libro está disponible desde promrds.com.
* *
Gracias a los siguientes expertos técnicos para la revisión de este artículo: Kyle Johns