De COM2 a COM3 :-)

Repitiendo una antigua entrada y atendiendo la solicitud de Benjam铆n .. “quiero conectar mediante vb los puerto com3 y com2. saludos”

DeCom2aCom3VB

tambi茅n os dejo este corto聽 en C#: DeCom2aCom3Saludos 馃檪

 

 

Using SerialPort Legacy on Windows 8.1

Desde la aparici贸n de Windows 8, se ha escrito mucho sobre la utilizaci贸n de los espacios de nombres de .NET desde WinRT. Es divertido observar como muchos nos aferramos a estereotipos aparentemente para no tener que cambiar la forma en que utilizamos o hacemos las cosas.

El contenido del siguiente post no es valido si est谩is pensando en aplicaciones para la versi贸n RT de Windows… es obvio que dif铆cilmente encontrareis puertos nativos en dispositivos con “RT” ni聽 USB’s de terceras partes con drivers que los soporten… dicho lo cual :

Esta es una de aquellas discusiones en foros y publicaciones en las que justificamos el porque WinRT no dispone de una implementaci贸n para utilizar los eternos “serial ports”.

SerialPortOnWindows81

Mas que la motivaci贸n por escribir un simple post, me mueve la inquietud generada al聽conversar con聽un responsable聽de RD聽en el que discut铆amos sobre la聽decisi贸n de desarrollar una soluci贸n聽en WPF por las limitaciones de WinRT para soportar聽la herencia de antiguos dispositivos unidos con alg煤n聽 tipo de “Hardware” cuyos drivers llegaron como mucho a “Windows 7”.

De hecho la respuesta oficial, es que Windows 8 y posteriores soportan puertos series “CDC” a con WINUSB… la realidad es que no todos los fabricantes han actualizado el “firmware” para que sus聽 drivers se sustenten en “WinUSB”.

Dicho lo cual incluso antes que apareciera la inquietud de acceder a los puertos series nativos desde aplicaciones para la tienda, he utilizado WCF para compartir la comunicaci贸n con alg煤n dispositivo de forma concurrente… no olvid茅is que al tratarse de una comunicaci贸n聽PeerToPeer聽si nuestra aplicaci贸n “abre” el puerto serie nadie mas podr谩 acceder a el hasta que liberemos el recurso.

Aqu铆 es donde entra en juego la implementaci贸n de un modelo “singlet” que nos permita acceder al envi贸 y recepci贸n de tramas de forma compartida.

Que mas f谩cil que llamar a un servicio WCF desde Windows 8.x para poder acceder a cualquier objeto que expongamos de .NET, simpre y聽cuando no estemos en uno聽de聽los escenarios donde PCL “Portable Class Library” nos聽cubra las necesidades.

El siguiente c贸digo muestra un punto de partida, entendible, simple y f谩cil… a petici贸n vuestra podr铆amos ir desarrollando el tema si es de inter茅s general.

Empezaremos creando un servicio con una simple funci贸n de enviar una trama al puerto serie (“con total independencia de si es un puerto nativo, CDC USB…etc”)

<ServiceContract()>
PublicInterfaceISerialPortService
聽聽聽聽<OperationContract()>
聽聽聽聽Function聽PortWrite(frame聽AsString)聽AsString 
EndInterface
Imports聽WcfSerialPort
PublicClassSerialPortService
聽聽聽聽ImplementsISerialPortService
聽聽聽聽PublicProperty聽mySerialPort聽AsNew聽System.IO.Ports.SerialPort

聽聽聽聽PublicFunction聽writePort(frame聽AsString)聽AsStringImplementsISerialPortService.PortWrite
聽聽聽聽聽聽聽聽Try
聽聽聽聽聽聽聽聽聽聽聽聽mySerialPort.ReadTimeout聽=聽1000
聽聽聽聽聽聽聽聽聽聽聽聽mySerialPort.NewLine聽=聽vbCrLf
聽聽聽聽聽聽聽聽聽聽聽聽mySerialPort.PortName聽=聽"COM4"
聽聽聽聽聽聽聽聽聽聽聽聽mySerialPort.BaudRate聽=聽1200
聽聽聽聽聽聽聽聽聽聽聽聽mySerialPort.Open()
聽聽聽聽聽聽聽聽聽聽聽聽mySerialPort.Write(frame聽+聽vbCrLf)
 
聽聽聽聽聽聽聽聽聽聽聽聽Dim聽response聽=聽ReadResponse()
聽聽聽聽聽聽聽聽聽聽聽聽mySerialPort.Close()
聽聽聽聽聽聽聽聽聽聽聽聽Return聽response
聽聽聽聽聽聽聽聽Catch聽ex聽AsException
聽聽聽聽聽聽聽聽聽聽聽聽Return聽ex.Message
聽聽聽聽聽聽聽聽EndTry
聽聽聽聽EndFunction
 
聽聽聽聽PrivateFunction聽ReadResponse()聽AsString
聽聽聽聽聽聽聽聽Try
聽聽聽聽聽聽聽聽聽聽聽聽Return聽mySerialPort.ReadLine()
聽聽聽聽聽聽聽聽Catch聽ex聽AsException
聽聽聽聽聽聽聽聽聽聽聽聽Return聽ex.Message
聽聽聽聽聽聽聽聽EndTry
聽聽聽聽EndFunction
 
EndClass

Una vez tengamos en servicio en marcha solo tendremos que a帽adir un proyecto nuevo para la tienda y listo!!

PublicNotInheritableClassMainPage
聽聽聽聽InheritsPage
聽聽聽聽Private聽miSerialPort聽As
           New聽WcfSerialPort.SerialPortServiceClient
 
聽聽聽聽AsyncSub聽Btn_Click(sender聽AsObject,聽
                             e聽AsRoutedEventArgs)
聽聽聽聽聽聽聽聽Dim聽result聽=聽Await聽miSerialPort.PortWriteAsync                          ("Hello聽Windows聽8.1聽App!!")
聽聽聽聽聽聽聽聽Dim聽msgbox聽AsNew聽Windows.UI.Popups.MessageDialog(result)
聽聽聽聽聽聽聽聽Await聽msgbox.ShowAsync()
聽聽聽聽EndSub
EndClass

Como veis… no muy dif铆cil para empezar 馃檪
Me gustara que continu茅is en este post, con vuestras conversaciones. Saludos domingueros!!
PepLluis,

Imprimir en Negrita… como en los Viejos Tiempos

Un amable lector (Eduardo), a propósito de manejar impresoras al viejo estilo. me Pregunta :

<Estoy mandando a imprimir a una impresora movil, solo que necesito saber como darle formato al texto, es decir quiero mandar cierta linea en negrita, otra linea en un tamaño de fuente mas grande, etc etc, espero me puedas apoyar.>

Te respondo a la pregunta, pensando en aquellos tiempos en los que atacábamos a las impresoras directamente “sin drivers” usando el puerto paralelo o el puerto serie, quien no recuerda las ProPrinter II o las NEC.

Si no recuerdo mal, aunque algunos fabricantes coincidan, cada impresora disponía de un pequeño manual que contenía lo que conocíamos como “Secuencias de Escape”.

Por lo tanto disponíamos de dos clásicos, la selección de negrita : enviando una secuencia de [ESC]+[e] (o bien 0x27+0x45, la selección de ancho con [ESC]+[W] o 0x27+0x57.

Si la impresora la tienes unida al equipo con una interface Serie… desde tu aplicación deberás abrirlo “SerialPort.Open(“COMx”,9600…etc) según la configuración de fabrica y posteriormente mandarle las secuencias con “SerialPort.Write(Chr(27)+Chr(45))” por poner un ejemplo.

He encontrado un link con un antiguo  manual espero que te sirva : http://support.epson.ru/products/manuals/000350/part1.pdf

Saludos,
PepLluis,

Enviar cadena hexadecimal en c#

Mario me pregunta :
<Espero me puedas ayudar necesito escribir una cadena en un cuadro de texto en valores hexadecimales y enviarlos por un puerto serial y capturar la respuesta y convertirla en hexadecimal ejemplo: enviar 7E000408014E4464 (son valores hexadecimales) capturar la respuesta (también es una cadena)y convertirla a hexadecimal mostrándola en un texbox ya convertida. estoy utilizando C# con sharpdevelop.>

Respuesta : (C# Visual Studio) 馃檪

using System;
using System.Windows.Forms;
 
namespace WindowsFormsApplication1
{
 
    public partial class Form1 : Form
    {
        System.IO.Ports.SerialPort port = new System.IO.Ports.SerialPort();
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            string toSend = "454647484950";
            for (int ndx = 0; ndx <= toSend.Length-1; ndx+=2)
            {
                byte asc = Convert.ToByte(toSend.Substring(ndx, 2), 16);
                char sendChar = Convert.ToChar(asc);
                port.Write(sendChar.ToString());
            }
            //
            // No olvideis que 'E' es '69' en decimal y '45' en Hex
            byte[] Recibidos = { 69,70,71,72,73};
            string hexInString = "";
            foreach (int val in Recibidos)
            {
                hexInString+=String.Format("{0:x2}",val);
            }
        }
    }
}

Saludos,
PepLluis,

NetMF 鈥 Serial Port – Echo response App

Some people ask me to have any soft start guide using microframework serial port. Well, as you know in desktop apps is the typical “Hello World”, the translation into serial port apps are “Echo for response”.

This code shows how to open the serial port to read incoming bytes and resend it as an echo. Is the first brick to check that the UART is all right! After this lab, you are ready to build your own DCE/DTE protocol and play serial commands between both sides.

Imports System.IO.Ports
Imports System.Text
 
Imports Microsoft.SPOT
Imports Microsoft.SPOT.Hardware
 
Module EchoResponse
 
    Private WithEvents SerialComm As SerialPort =
        New SerialPort("COM1", 9600, Parity.None, 8, StopBits.One)
 
    Private DataReceived As String = ""
    Private PortActivity As New OutputPort(CType(55, Cpu.Pin), False)
 
    Sub Main()
        SerialComm.Open()
        ' include your functions here
        Thread.Sleep(Timeout.Infinite)
    End Sub
 
    Private Sub SerialIn() Handles SerialComm.DataReceived
        PortActivity.Write(True)
        Dim Length As Integer = SerialComm.BytesToRead
        Dim Frame(Length) As Byte
        SerialComm.Read(Frame, 0, Length)
        SerialComm.Write(Frame, 0, Length)
        DataReceived = ""
        PortActivity.Write(False)
    End Sub
End Module

Enjoy!! PepLluis,

Convertir la trama recibida de ASCii a HEX

Respondiendo a la pregunta de David : “Al leer del puerto serie leo su contenido pero me lo muestra como ASCii, existe alguna forma para visualizar su contenido en HEX o Decimal?”

    Function AsciiToHex(TramaRecibida As String, ConvertToHex As BooleanAs String
        '
        ' Conversion de un string a una cadena de Hexadecimales / decimales
        For Each c As Char In TramaRecibida
            If ConvertToHex Then
                AsciiToHex += "0x" + Hex(Asc(c)) + " "
            Else
                AsciiToHex += Asc(c).ToString + " "
            End If
        Next
        Return AsciiToHex
    End Function

Para invocar la funcion :

        Dim RespuestaEnHex As String = AsciiToHex("abcABCD_CualquierTextoRecibido"True)
        Dim RespuestaEnDEC As String = AsciiToHex("abcABCD_CualquierTextoRecibido"False)

Espero  te sea util.
Saludos,
PepLluis,

El puerto Serie, como usarlo en WPF

Atendiendo el comentario de Jose Fco en el que indica :

<< He podido leer diversos ejemplos de como utilizar e implementar las funciones básicas de acceso al puerto serie principalmente en aplicaciones WinForms, seria posible obtener una esqueleto base en WPF tal como tienes para los anteriores.>>

El siguiente ejemplo, se entiende como ejercicio para realizar la transmisión y recepción de una trama utilizando un temporizador de un segundo en un proyecto WPF, para cerrar el circuito deberás insertar un conector en el puerto serie con un puente entre los pines 2 y 3. Recordad que el uso de ReadLine suspende la ejecucion del thread hasta recibir la sequencia definida en ‘SerialPort.NewLine’.

Partial Public Class Window1

    Delegate Sub Actualizar()     Private WithEvents Puerto1 As New System.IO.Ports.SerialPort     Private temporizador As New System.Timers.Timer     Private Recibidos As String = ""

    Sub New()         ' Llamada necesaria para el Diseñador de Windows Forms.          InitializeComponent()         Puerto1 = My.Computer.Ports.OpenSerialPort("COM1", 9600)         AddHandler Puerto1.DataReceived, AddressOf Recepcion         temporizador.Interval = 1000         temporizador.Enabled = True         AddHandler temporizador.Elapsed, AddressOf Peticion     End Sub
    Private Sub Recepcion()             Recibidos = Puerto1.ReadLine             Me.Dispatcher.Invoke(New Actualizar(AddressOf Datos))     End Sub
    Sub Peticion()             Puerto1.WriteLine("Saludos!")     End Sub
    Sub Datos()             Me.Label1.Content = Recibidos     End Sub End Class

Espero que cumpla con tus espectativas.
Saludos,
PepLluis,

Enviar un Hexadecimal al puerto serie, a partir de un entero en formato texto.

Es complicado poder atender todas las solicitudes recibidas en este blog, a menudo intento responder a vuestras inquietudes a pesar de que tambien siempre intento convenceros de que utilizemos los Foros de MSDN puesto que es el sitio adecuado para poder compartir vuestras preguntas para que todos los expertos puedan aportar su opinion.

Para preguntas sobre el puerto serie os recomiendo visitar : http://social.msdn.microsoft.com/Forums/es-ES/devcommes/threads

Una vez aclarado 馃檪
Bolivar pregunta : a luis tenia una consulta , como puedo convertir cualquier numero entero introducido en un textbox para despues convertirlo a hexadecimal y luego enviarlo por RS232

Repuesta:

    Private MiPuertoSerie As New IO.Ports.SerialPort
    Sub EnviarHex(Numero As String)
        Numero = Hex(Val(Numero)).ToString
        MiPuertoSerie.Write(Numero)
    End Sub

Como declarar el puerto serie de forma Global

Respondiendo una pregunta de los foros, me complace compartir con vosotros el siguiente ejercicio; no sin antes puntualizar que se trata de la puesta en escena de un ejemplo que utilizaría un modulo como “clase estática” donde depositar objetos compartidos dentro de nuestro espacio de aplicación.

Para evitar interpretaciones, este es uno de esos ejemplos que no debe considerarse “modelo” pues su escenario es poco menos que atípico, aclarar que en situaciones similares lo adecuado seria diseñar una clase completa con toda la funcionalidad y acceso, para posteriormente incluirla como propiedad en un modulo. La dificultad se encuentra en la cantidad de código que deberíamos desplegar para realizar una explicación que finalmente terminaría siendo compleja de seguir y entender.

Dicho esto, el siguiente es solo un punto de entrada para las personas que intentan iniciarse en el tema y se encuentran en situaciones como la que expone “Caudiz” en los foros… necesita poder acceder al puerto serie desde dos forms diferentes.

Primero definiríamos el modulo que contendrá toda la lógica de acceso al puerto serie y podría ser algo similar a lo que sigue :

Imports System.IO.Ports
 
Module SerialComm
 
    Private SerialPort1 As New SerialPort
    Private LastFrameRead As String
 
    Public Event DataAvailable()
 
    Sub New()
        SerialPort1.PortName = "COMx"
        SerialPort1.Open()
        AddHandler SerialPort1.DataReceived, AddressOf ReceiveData
    End Sub
 
    Private Sub ReceiveData()
        LastFrameRead += SerialPort1.ReadExisting.ToString()
        RaiseEvent DataAvailable()
    End Sub
 
    Public Function ReadData() As String
        Return LastFrameRead
    End Function
 
    Public Sub WriteData(Frame)
        SerialPort1.Write(Frame)
    End Sub
 
    Public Sub ClearData()
        LastFrameRead = ""
    End Sub
 
End Module

Finalmente incluiríamos el siguiente código para acceder a dicha funcionalidad en este caso desde el ‘Form1’ aunque evidentemente podemos incluirlo desde cualquier otro punto del espacio de nuestra aplicación.

Public Class Form1
 
    Sub Form1_Load(sender As System.Object, e As System.EventArgsHandles MyBase.Load
        AddHandler SerialComm.DataAvailable, AddressOf ReadData
        Form2.Show()
    End Sub
 
    Sub ReadData()
        Me.Label1.Text = SerialComm.ReadData
    End Sub
 
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgsHandles Button1.Click
        SerialComm.WriteData("Hola 馃檪 from 1")
    End Sub
End Class
Public Class Form2
 
    Private Sub Form2_Load(sender As System.Object, e As System.EventArgsHandles MyBase.Load
        AddHandler SerialComm.DataAvailable, AddressOf ReadData
    End Sub
 
    Sub ReadData()
        Me.Label1.Text = SerialComm.ReadData
    End Sub
 
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgsHandles Button1.Click
        SerialComm.WriteData("Hola 馃檪 from 2")
    End Sub
 
End Class

Espero vuestros comentarios y que a partir de esta idea, podáis construir de forma robusta la implementación de vuestra solucion.
Saludos,
PepLluis,