none
Puerto serie RS232 RRS feed

  • Pregunta

  • Hola:

    Estoy con MonoDevelop con el openSUSE 11.1. Mirando esta web http://www.mono-project.com/HowToSystemIOPorts quiero configurar el puerto serie como a mi me de la gana.

    Lo he puesto así:
    mySerial new SerialPort("/dev/ttyS0", 9600, None, 8, Two); 

    La otra manera con comillas así:
    mySerial new SerialPort("/dev/ttyS0", 9600, "None", 8, "Two"); 


    Código completo:
    // MainWindow.cs created with MonoDevelop 
    // User: metaconta at 17:46 23/02/2009 
    // 
    // To change standard headers go to Edit->Preferences->Coding->Standard Headers 
    // 
    using System; 
    using Gtk; 
    using System.IO.Ports; 
     
    public partial class MainWindow: Gtk.Window 
    {    
        public MainWindow (): base (Gtk.WindowType.Toplevel) 
        { 
            Build (); 
        } 
         
        protected void OnDeleteEvent (object sender, DeleteEventArgs a) 
        { 
            Application.Quit (); 
            a.RetVal = true
        } 
     
        protected virtual void OnButton1Clicked (object sender, System.EventArgs e) 
        { 
            mySerial new SerialPort("/dev/ttyS0", 9600, None, 8, Two); 
        } 


    Estoy intentando pasar este código de Visual C# a Mono, puedes ver el código en las páginas 153 y 154 en este manual en PDF.

    http://www.abcdatos.com/tutoriales/tutorial/z9521.html

    Saludos.

    EDITO:
    He logrado abrir el puerto pero no he sido enviar el código al puerto serie.

    1// MainWindow.cs created with MonoDevelop 
    2// User: metaconta at 17:46 23/02/2009 
    3// 
    4// To change standard headers go to Edit->Preferences->Coding->Standard Headers 
    5// 
    6using System; 
    7using Gtk; 
    8using System.IO.Ports; 
    9 
    10public partial class MainWindow: Gtk.Window 
    11{    
    12    private SerialPort mySerial; 
    13     
    14    public MainWindow (): base (Gtk.WindowType.Toplevel) 
    15    { 
    16        Build (); 
    17    } 
    18     
    19    protected void OnDeleteEvent (object sender, DeleteEventArgs a) 
    20    { 
    21        Application.Quit (); 
    22        a.RetVal = true
    23    } 
    24 
    25    protected virtual void OnButton1Clicked (object sender, System.EventArgs e) 
    26    { 
    27        mySerial = new SerialPort("/dev/ttyS0", 9600, Parity.None, 8, StopBits.Two); 
    28         
    29        if(mySerial == nullreturn
    30 
    31        mySerial.Open(); 
    32         
    33        if(!mySerial.IsOpen) 
    34        { 
    35            label1.Text = "Error abriendo"
    36            mySerial.Dispose(); 
    37            return
    38        } 
    39         
    40        byte[] buffer = new byte[1]; 
    41        buffer[0] = 0x74; 
    42        mySerial.Write(buffer, 0, 1); 
    43         
    44        try 
    45        { 
    46            mySerial.Write(buffer, 0, 1); 
    47        } 
    48        catch(Exception ex) 
    49        { 
    50            //label1.Text = ex.Message;// + " " + ex.StackTrace; 
    51            mySerial.Close(); 
    52            mySerial.Dispose(); 
    53            return
    54        } 
    55         
    56        mySerial.Close(); 
    57    } 
    58



    La verdad no mancha los labios de quien la dice, sino la conciencia de quien la oculta.
    lunes, 23 de febrero de 2009 20:42

Respuestas

  • Me respondo a mi mismo, la respuesta es que el puerto no tiene el permiso desde Linux. Comprobando otra prueba_03:

    // MainWindow.cs created with MonoDevelop 
    // User: metaconta at 7:22 24/02/2009 
    // 
    // To change standard headers go to Edit->Preferences->Coding->Standard Headers 
    // 
    using System; 
    using Gtk; 
    using System.IO.Ports; 
     
    public partial class MainWindow: Gtk.Window 
    {    
        public MainWindow (): base (Gtk.WindowType.Toplevel) 
        { 
            Build (); 
            mySerial = new SerialPort("/dev/ttyS0", 9600, Parity.None, 8, StopBits.Two); 
        } 
         
        protected void OnDeleteEvent (object sender, DeleteEventArgs a) 
        { 
            Application.Quit (); 
            a.RetVal = true
        } 
        private SerialPort mySerial; 
        protected virtual void OnButton1Clicked (object sender, System.EventArgs e) 
        { 
            mySerial.Open();         
            byte[] mBuffer = new byte[1]; 
            mBuffer[0] = 0x74; // ASCII letra t. 
            mySerial.Write(mBuffer, 0, mBuffer.Length); 
            mySerial.Close(); 
        } 
     
        protected virtual void OnButton2Clicked (object sender, System.EventArgs e) 
        { 
            mySerial.Open();         
            byte[] mBuffer = new byte[1]; 
            mBuffer[0] = 0x62; // ASCII letra b. 
            mySerial.Write(mBuffer, 0, mBuffer.Length); 
            mySerial.Close(); 
        } 

    La solución la podemos encontrar en esta Web:
    http://www.gphoto.org/doc/manual/permissions-serial.html

    Lo hago así:
    Contraseña: 
    dhcppc2:~ # ls -l /dev/ttyS0 
    crw-rw---- 1 root uucp 4, 64 Dec  3 05:56 /dev/ttyS0 
    dhcppc2:~ # chown metaconta /dev/ttyS0 
    dhcppc2:~ # ls -l /dev/ttyS0 
    crw-rw---- 1 metaconta uucp 4, 64 Dec  3 05:56 /dev/ttyS0 
    dhcppc2:~ # 
     

    Ejecuto el programa y ya funciona a la primera, aún me falta mejorar el código para hacerlo más eficiente que lo pondré aquí cuando acabe y si lo recuerdo, claro.

    Si hay otra Web mejor que esta en la explicación la dices aquí.

    EDIT:
    En Visual C# Express 2008 es:
    using System; 
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Data; 
    using System.Drawing; 
    using System.Linq; 
    using System.Text; 
    using System.Windows.Forms; 
    using System.IO.Ports; 
     
    namespace PicRS232 
        public partial class Form1_Principal : Form 
        { 
            // Utilizaremos un string como buffer de recepcion 
            string Recibidos; 
            public Form1_Principal() 
            { 
                InitializeComponent(); 
                // Abrir puerto mientra se ejecute la aplicación 
                if (!serialPort1.IsOpen) 
                { 
                    try 
                    { 
                        serialPort1.Open(); 
                    } 
                    catch (System.Exception ex) 
                    { 
                        MessageBox.Show(ex.ToString()); 
                    } 
                } 
                // Ejecutar la funcion Recepcion por disparo del Evento 'DataReived' 
                serialPort1.DataReceived += new 
                System.IO.Ports.SerialDataReceivedEventHandler(Recepcion); 
            } 
            // Al recibir los datos 
            private void Recepcion(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) 
            { 
                // Acumular los carácteres recibidos a nuestro 'buffer' (string) 
                Recibidos += serialPort1.ReadExisting(); 
                // Invocar o llamar al proceso de tramas 
                this.Invoke(new EventHandler(Actualizar)); 
            } 
            // Procesar los datos recibidos en el buffer y extraer tramas completas 
            private void Actualizar(object s, EventArgs e) 
            { 
                // Asignar el valor de la trama al textBox 
                textBox_visualizar_mensaje.Text = Recibidos; 
            } 
            private void button_t_Click(object sender, EventArgs e) 
            { 
                byte[] mBuffer = new byte[1]; 
                mBuffer[0] = 0x74; //ASCII letra "t". 
                serialPort1.Write(mBuffer, 0, mBuffer.Length); 
            } 
     
            private void button_b_Click(object sender, EventArgs e) 
            { 
                byte[] miBuffer = new byte[1]; 
                miBuffer[0] = 0x62; //ASCII letra "b". 
                serialPort1.Write(miBuffer, 0, miBuffer.Length); 
            } 
     
            private void button_a_Click(object sender, EventArgs e) 
            { 
                byte[] mBuffer = new byte[1]; 
                mBuffer[0] = 0x61; //ASCII letra "a". 
                serialPort1.Write(mBuffer, 0, mBuffer.Length); 
            } 
     
            private void button_l_Click(object sender, EventArgs e) 
            { 
                byte[] mBuffer = new byte[1]; 
                mBuffer[0] = 0x6C; //ASCII letra "l". 
                serialPort1.Write(mBuffer, 0, mBuffer.Length); 
            } 
     
            private void button_Espacio_Click(object sender, EventArgs e) 
            { 
                byte[] mBuffer = new byte[1]; 
                mBuffer[0] = 0x20; //ASCII letra "Espacio". 
                serialPort1.Write(mBuffer, 0, mBuffer.Length); 
            } 
     
            private void timer1_Tick(object sender, EventArgs e) 
            { 
                statusStrip1.Items[0].Text = DateTime.Now.ToLongTimeString(); 
            } 
        } 


    La verdad no mancha los labios de quien la dice, sino la conciencia de quien la oculta.
    • Marcado como respuesta Metaconta martes, 24 de febrero de 2009 11:27
    martes, 24 de febrero de 2009 11:27

Todas las respuestas

  • Vamos a empezar desde el principio.

    Utilizando el Mono con gtk#, he introducido un botón normal en el formulario. El código completo lo he hecho de nuevo y ahora es así. Ejecuta sin problemas pero al pulsar el botón hay errores que no se el motivo.

    1// MainWindow.cs created with MonoDevelop 
    2// User: metaconta at 20:59 23/02/2009 
    3// 
    4// To change standard headers go to Edit->Preferences->Coding->Standard Headers 
    5// 
    6using System; 
    7using Gtk; 
    8using System.IO.Ports; 
    9 
    10public partial class MainWindow: Gtk.Window 
    11{    
    12    public MainWindow (): base (Gtk.WindowType.Toplevel) 
    13    { 
    14        Build (); 
    15    } 
    16     
    17    protected void OnDeleteEvent (object sender, DeleteEventArgs a) 
    18    { 
    19        Application.Quit (); 
    20        a.RetVal = true
    21    } 
    22     
    23    public SerialPort mySerial; 
    24 
    25    protected virtual void OnButtonTClicked (object sender, System.EventArgs e) 
    26    { 
    27        mySerial = new SerialPort("/dev/ttyS0", 9600, Parity.None, 8, StopBits.Two); 
    28        mySerial.Open(); 
    29        byte[] mBuffer = new byte[1]; 
    30        mBuffer[0] = 0x74; // LA letra t. 
    31        mySerial.Write(mBuffer, 0, mBuffer.Length); 
    32        mySerial.Close(); 
    33    } 
    34

    En el mensaje de error me da esto:

    Marshaling clicked signal 
    Exception in Gtk# callback delegate 
      Note: Applications can use GLib.ExceptionManager.UnhandledException to handle the exception. 
    System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.IOException: Permiso denegado 
      at System.IO.Ports.SerialPortStream.ThrowIOException () [0x00012] in /usr/src/packages/BUILD/mono-2.0.1/mcs/class/System/System.IO.Ports/SerialPortStream.cs:299  
      at System.IO.Ports.SerialPortStream..ctor (System.String portName, Int32 baudRate, Int32 dataBits, Parity parity, StopBits stopBits, Boolean dtrEnable, Boolean rtsEnable, Handshake handshake, Int32 readTimeout, Int32 writeTimeout, Int32 readBufferSize, Int32 writeBufferSize) [0x0001e] in /usr/src/packages/BUILD/mono-2.0.1/mcs/class/System/System.IO.Ports/SerialPortStream.cs:36  
      at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPortStream:.ctor (string,int,int,System.IO.Ports.Parity,System.IO.Ports.StopBits,bool,bool,System.IO.Ports.Handshake,int,int,int,int) 
      at System.IO.Ports.SerialPort.Open () [0x00078] in /usr/src/packages/BUILD/mono-2.0.1/mcs/class/System/System.IO.Ports/SerialPort.cs:563  
      at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPort:Open () 
      at MainWindow.OnButtonTClicked (System.Object sender, System.EventArgs e) [0x00018] in /home/metaconta/Prueba_02/Prueba_02/MainWindow.cs:28  
      at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (object,object[],System.Exception&) 
      at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00057] in /usr/src/packages/BUILD/mono-2.0.1/mcs/class/corlib/System.Reflection/MonoMethod.cs:157  
      --- End of inner exception stack trace --- 
      at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00071] in /usr/src/packages/BUILD/mono-2.0.1/mcs/class/corlib/System.Reflection/MonoMethod.cs:167  
      at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in /usr/src/packages/BUILD/mono-2.0.1/mcs/class/corlib/System.Reflection/MethodBase.cs:110  
      at System.Delegate.DynamicInvokeImpl (System.Object[] args) [0x000b4] in /usr/src/packages/BUILD/mono-2.0.1/mcs/class/corlib/System/Delegate.cs:422  
      at System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args) [0x00018] in /usr/src/packages/BUILD/mono-2.0.1/mcs/class/corlib/System/MulticastDelegate.cs:71  
      at System.Delegate.DynamicInvoke (System.Object[] args) [0x00000] in /usr/src/packages/BUILD/mono-2.0.1/mcs/class/corlib/System/Delegate.cs:394  
      at GLib.Signal.ClosureInvokedCB (System.Object o, GLib.ClosureInvokedArgs args) [0x0004f] in /usr/src/packages/BUILD/gtk-sharp-2.12.6/glib/Signal.cs:195  
      at GLib.SignalClosure.Invoke (GLib.ClosureInvokedArgs args) [0x0000c] in /usr/src/packages/BUILD/gtk-sharp-2.12.6/glib/SignalClosure.cs:118  
      at GLib.SignalClosure.MarshalCallback (IntPtr raw_closure, IntPtr return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data) [0x0007a] in /usr/src/packages/BUILD/gtk-sharp-2.12.6/glib/SignalClosure.cs:146  
       at GLib.ExceptionManager.RaiseUnhandledException(System.Exception e, Boolean is_terminal) in /usr/src/packages/BUILD/gtk-sharp-2.12.6/glib/ExceptionManager.cs:line 58 
       at GLib.SignalClosure.MarshalCallback(IntPtr raw_closure, IntPtr return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data) in /usr/src/packages/BUILD/gtk-sharp-2.12.6/glib/SignalClosure.cs:line 173 
       at Gtk.Application.gtk_main() 
       at Gtk.Application.Run() in /usr/src/packages/BUILD/gtk-sharp-2.12.6/gtk/generated/AboutDialog.cs:line 1 
       at Prueba_02.MainClass.Main(System.String[] args) in /home/metaconta/Prueba_02/Prueba_02/Main.cs:line 18 
     
     




    La verdad no mancha los labios de quien la dice, sino la conciencia de quien la oculta.
    lunes, 23 de febrero de 2009 22:29
  • Me respondo a mi mismo, la respuesta es que el puerto no tiene el permiso desde Linux. Comprobando otra prueba_03:

    // MainWindow.cs created with MonoDevelop 
    // User: metaconta at 7:22 24/02/2009 
    // 
    // To change standard headers go to Edit->Preferences->Coding->Standard Headers 
    // 
    using System; 
    using Gtk; 
    using System.IO.Ports; 
     
    public partial class MainWindow: Gtk.Window 
    {    
        public MainWindow (): base (Gtk.WindowType.Toplevel) 
        { 
            Build (); 
            mySerial = new SerialPort("/dev/ttyS0", 9600, Parity.None, 8, StopBits.Two); 
        } 
         
        protected void OnDeleteEvent (object sender, DeleteEventArgs a) 
        { 
            Application.Quit (); 
            a.RetVal = true
        } 
        private SerialPort mySerial; 
        protected virtual void OnButton1Clicked (object sender, System.EventArgs e) 
        { 
            mySerial.Open();         
            byte[] mBuffer = new byte[1]; 
            mBuffer[0] = 0x74; // ASCII letra t. 
            mySerial.Write(mBuffer, 0, mBuffer.Length); 
            mySerial.Close(); 
        } 
     
        protected virtual void OnButton2Clicked (object sender, System.EventArgs e) 
        { 
            mySerial.Open();         
            byte[] mBuffer = new byte[1]; 
            mBuffer[0] = 0x62; // ASCII letra b. 
            mySerial.Write(mBuffer, 0, mBuffer.Length); 
            mySerial.Close(); 
        } 

    La solución la podemos encontrar en esta Web:
    http://www.gphoto.org/doc/manual/permissions-serial.html

    Lo hago así:
    Contraseña: 
    dhcppc2:~ # ls -l /dev/ttyS0 
    crw-rw---- 1 root uucp 4, 64 Dec  3 05:56 /dev/ttyS0 
    dhcppc2:~ # chown metaconta /dev/ttyS0 
    dhcppc2:~ # ls -l /dev/ttyS0 
    crw-rw---- 1 metaconta uucp 4, 64 Dec  3 05:56 /dev/ttyS0 
    dhcppc2:~ # 
     

    Ejecuto el programa y ya funciona a la primera, aún me falta mejorar el código para hacerlo más eficiente que lo pondré aquí cuando acabe y si lo recuerdo, claro.

    Si hay otra Web mejor que esta en la explicación la dices aquí.

    EDIT:
    En Visual C# Express 2008 es:
    using System; 
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Data; 
    using System.Drawing; 
    using System.Linq; 
    using System.Text; 
    using System.Windows.Forms; 
    using System.IO.Ports; 
     
    namespace PicRS232 
        public partial class Form1_Principal : Form 
        { 
            // Utilizaremos un string como buffer de recepcion 
            string Recibidos; 
            public Form1_Principal() 
            { 
                InitializeComponent(); 
                // Abrir puerto mientra se ejecute la aplicación 
                if (!serialPort1.IsOpen) 
                { 
                    try 
                    { 
                        serialPort1.Open(); 
                    } 
                    catch (System.Exception ex) 
                    { 
                        MessageBox.Show(ex.ToString()); 
                    } 
                } 
                // Ejecutar la funcion Recepcion por disparo del Evento 'DataReived' 
                serialPort1.DataReceived += new 
                System.IO.Ports.SerialDataReceivedEventHandler(Recepcion); 
            } 
            // Al recibir los datos 
            private void Recepcion(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) 
            { 
                // Acumular los carácteres recibidos a nuestro 'buffer' (string) 
                Recibidos += serialPort1.ReadExisting(); 
                // Invocar o llamar al proceso de tramas 
                this.Invoke(new EventHandler(Actualizar)); 
            } 
            // Procesar los datos recibidos en el buffer y extraer tramas completas 
            private void Actualizar(object s, EventArgs e) 
            { 
                // Asignar el valor de la trama al textBox 
                textBox_visualizar_mensaje.Text = Recibidos; 
            } 
            private void button_t_Click(object sender, EventArgs e) 
            { 
                byte[] mBuffer = new byte[1]; 
                mBuffer[0] = 0x74; //ASCII letra "t". 
                serialPort1.Write(mBuffer, 0, mBuffer.Length); 
            } 
     
            private void button_b_Click(object sender, EventArgs e) 
            { 
                byte[] miBuffer = new byte[1]; 
                miBuffer[0] = 0x62; //ASCII letra "b". 
                serialPort1.Write(miBuffer, 0, miBuffer.Length); 
            } 
     
            private void button_a_Click(object sender, EventArgs e) 
            { 
                byte[] mBuffer = new byte[1]; 
                mBuffer[0] = 0x61; //ASCII letra "a". 
                serialPort1.Write(mBuffer, 0, mBuffer.Length); 
            } 
     
            private void button_l_Click(object sender, EventArgs e) 
            { 
                byte[] mBuffer = new byte[1]; 
                mBuffer[0] = 0x6C; //ASCII letra "l". 
                serialPort1.Write(mBuffer, 0, mBuffer.Length); 
            } 
     
            private void button_Espacio_Click(object sender, EventArgs e) 
            { 
                byte[] mBuffer = new byte[1]; 
                mBuffer[0] = 0x20; //ASCII letra "Espacio". 
                serialPort1.Write(mBuffer, 0, mBuffer.Length); 
            } 
     
            private void timer1_Tick(object sender, EventArgs e) 
            { 
                statusStrip1.Items[0].Text = DateTime.Now.ToLongTimeString(); 
            } 
        } 


    La verdad no mancha los labios de quien la dice, sino la conciencia de quien la oculta.
    • Marcado como respuesta Metaconta martes, 24 de febrero de 2009 11:27
    martes, 24 de febrero de 2009 11:27