TODOPIC

Lenguajes de programación para PC => C, C#, C++ => Mensaje iniciado por: migsantiago en 16 de Mayo de 2009, 16:50:21

Título: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 16 de Mayo de 2009, 16:50:21
Acabo de hacer un pequeño programa que recibe una imagen tomada por Bluetooth a través de un COM virtual usando C#. Este programa funciona de la misma manera con cualquier otro COM, incluso con nuestros PICs. Se necesita tener Visual C# 2008 instalado pero también debe funcionar con versiones anteriores. Les comparto los pasos que hay que llevar a cabo para que manejen el suyo.

Para usar el puerto COM es más fácil que nunca.

- Ir al cuadro de Herramientas y tomar un SerialPort y dibujarlo en cualquier parte de la ventana principal.

- En su ventana de propiedades hay que detallar sus características. Las principales son:
  + Name. Cualquier nombre que te guste. El mío se queda en serialPort1.
  + BaudRate. Velocidad en bps. Solo útil si el puerto es físico y no virtual.
  + PortName. El nombre del puerto COM. Si usas los físicos serán COM1 o COM2. Si usas virtuales serán números mayores.
  + ReadBufferSize. Tamaño máximo del buffer. Si dejas que se llene perderás datos.

(http://img38.imageshack.us/img38/4859/28163452.jpg)

- Para monitorear cuando llegan los datos deberás implementar una función detonada por evento. Da click en el serialPort1 y después en el iconito con forma de rayo en la ventana Propiedades.

- Da doble click en DataReceived y se creará una función que se va a ejecutar cada que se recibe cualquier dato en el puerto.

- En esta función podrás indagar cuántos bytes tienes pendientes en el buffer y recolectarlos en un arreglo de bytes:
Código: [Seleccionar]
  int bytes = serialPort1.BytesToRead;
  byte[] buffer = new byte[bytes];
  serialPort1.Read(buffer, 0, bytes);

- Para iniciar el funcionamiento del puerto solo debes usar:
Código: [Seleccionar]
  serialPort1.Open();
- Para cerrarlo:
Código: [Seleccionar]
  serialPort1.Close();
- Para enviar bytes por el puerto:
Código: [Seleccionar]
  serialPort1.Write(byte[] buffer, offset, count);  Donde offset es un byte inicial y count es el máximo de bytes que quieres enviar del arreglo buffer
  Esa función tiene otras sobrecargas.

Les dejo un ejemplo para recibir un número desconocido de bytes y guardarlos en un archivo binario.

Código: [Seleccionar]
        //////////////////////////////
        //Variable global
        List<byte> recibido = new List<byte>();

        //////////////////////////////
        //Abrir puerto COM14
        private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            recibido.Clear();
        }

        //////////////////////////////
        //Datos en el buffer
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            int bytes = serialPort1.BytesToRead;

            byte[] buffer = new byte[bytes];

            serialPort1.Read(buffer, 0, bytes);
            foreach(byte elem in buffer)
            {
                recibido.Add(elem);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
           
            //Guarda todo en archivo
            if (File.Exists("Prueba.jpg"))
                File.Delete("Prueba.jpg");
            FileStream archivoP = new FileStream("Prueba.jpg",
                FileMode.OpenOrCreate, FileAccess.Write);
            BinaryWriter escribirP = new BinaryWriter(archivoP);
            foreach(byte elem in recibido)
            {
                escribirP.Write(elem);
            }
            escribirP.Close();
            archivoP.Close();
            Process.Start("Prueba.jpg");
        }
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: scientist en 20 de Mayo de 2009, 02:06:31
excelente ejemplo, muchas gracias, me viene de perlas este ejemplo, saludos
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: scientist en 20 de Mayo de 2009, 04:00:56
una pregunta, tengo que incluir alguna libreria para poder probarlo, me da error al poner file o filestream, como si no lo reconociera, saludos
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 20 de Mayo de 2009, 11:51:03
Hola

Tienes que agregar la clase IO.

Código: [Seleccionar]
using System.IO;                        //Requerido para manejar archivos
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: scientist en 20 de Mayo de 2009, 17:45:03
muchas gracias, me fui a ayuda y lo encontre, tambien hay que incluir el system.diagnostics
saludos
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 20 de Mayo de 2009, 18:21:55
No necesariamente, el System.Diagnostics sirve para abrir el archivo que recién creaste. Puedes comentar la instrucción Process.Start("archivo.txt");
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: scientist en 20 de Mayo de 2009, 22:37:01
a mi me salia error y pense que tambien incluyendo un archivo mas, se terminaria, la verdad no soy nada bueno en c#, ni ninguna suite de visual studio, o delphi, o lo que sea, jejeje, saludos
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 21 de Mayo de 2009, 14:10:22
Si has programado Java o C, C# te parecerá súper fácil.

Lo que más me gusta de la Express Edition es que al estar escribiendo un programa te presenta ayudas contextuales. Por ejemplo, para el puerto serie...

(http://img20.imageshack.us/img20/3391/85926917.jpg)

Y además compila mientras escribes. Antes de que acabes una línea ya te está marcando los errores de sintaxis, funciones, e incluso ámbito de variables locales, privadas, globales, etc.

A mi me gustó mucho y la curva de aprendizaje de este lenguaje es exponencial  8)
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: scientist en 22 de Mayo de 2009, 01:32:00
eso si es cierto, me gusta mucho esta suite, y es por eso que estoy empezando a aprender a manejarlo decentemente, talvez despues me meta con sql, pero todo lento y seguro, saludos
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: AKENAFAB en 22 de Mayo de 2009, 06:08:33
Me viene de 10 (dieceses)  :mrgreen:

Aunque no le agarro bien el rollo , a mi parecer xD por ahora similar a vb y qu ebueno eso que de ahi vengo xD.

Pero no le agarro el hilo , qu eno pueod ni cambiar el contenido de los labels ni botones >_<

Será con más tiempo.

Muchismias gracias y un saludoski!
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 22 de Mayo de 2009, 12:23:15
Akena, cómo crees...  :D

Hay una ventanita de Propiedades y se llama Text y Name ahí sale todo.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: AKENAFAB en 22 de Mayo de 2009, 14:30:31


Si , eso si lo he visto xD no soy tan tan xD un poco nada más xD

Pero digo amm cambiarlo al preisonar un boton etc...

Es que en VB xD le daba creo recordar button1.text= Botoncito y ya me cambiaba el titulo del boton xD

Cosas asi.

Es que ando de noob xD

^^

Ya que entre más en acción espero colaborar con algo , por lo mientras de chismoson xD
Saludos!
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 22 de Mayo de 2009, 16:21:20
jjajajaj  :D

Es bien fácil Akena...

Código: [Seleccionar]
btnBotoncito.Text="Apriétame";

Bueno, nos avisas cuando te atores en otro programa.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: AKENAFAB en 22 de Mayo de 2009, 22:31:55
Ya veo el error xD

No lo puse entre comillas!!

Y Cuando daba click , me safloa FORM1  xD

Gracias MIg!!
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: jhozate en 17 de Agosto de 2009, 12:21:39
apenas me vengo iniciando en el C# y me a parecido de lo mas facil este cuento del puerto serie, pero su sintaxis si me parece alguito complicada.

ya pude visualizar en un textbox lo q recibo por el puerto serie, pero yo recibo dos datos, uno de temperatura que viene entre dos 'T', es decir 'T30T' y uno de nivel q viene entre dos 'N', es decir 'N20N', como hago para discriminar estas letras, deberia primero guardar el dato en algun buffer y despues recorrerlo para encontrar esas letras??

saludos
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 17 de Agosto de 2009, 12:36:42
Puedes separar los datos bien fácil usando la función split. Le das el string completo y split divide en substrings de acuerdo a algún char que le indiques.

Código: [Seleccionar]
            string fila;
            string[] datos;

datos = fila.Split(",".ToCharArray()); //Separa por comas
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: jhozate en 17 de Agosto de 2009, 13:30:56
encontre esto (http://msdn.microsoft.com/es-es/library/ms228388%28VS.80%29.aspx) segun eso le indico las N y las T y me devuelve el dato..pero ese dato sigue siendo string..para utilizarlo en alguna operacion matematica debo pasarlo a otro tipo?
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 17 de Agosto de 2009, 14:34:22
Ah, solo hazle un parsing.

Código: [Seleccionar]
String cadena;
float flota;
flota = float.Parse(cadena);
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 24 de Agosto de 2009, 17:35:03
migsantiago una pregunta...primero pues no se nada de C# por eso pregunto de forma generalizada...

Cuando llega un dato al puerto, ¿el programa atiende al guardado del dato como si de una interrupción se tratase o hay que llamar la función del puerto cada X tiempo y así guardar los datos?
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 24 de Agosto de 2009, 18:08:27
Hola Sauron

Cuando llega un dato al buffer del puerto serial se detona un evento que VC# administra automáticamente. Cuando ocurre el evento se ejecuta una función en donde uno puede revisar si recibió el dato y leer el buffer. Una vez habiendo leído el buffer, éste es vaciado y está listo para recibir más datos.

Los 2 eventos útiles que se pueden monitorear son DataReceived y ErrorReceived.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 24 de Agosto de 2009, 18:29:26
Hola Sauron

Cuando llega un dato al buffer del puerto serial se detona un evento que VC# administra automáticamente. Cuando ocurre el evento se ejecuta una función en donde uno puede revisar si recibió el dato y leer el buffer. Una vez habiendo leído el buffer, éste es vaciado y está listo para recibir más datos.

Los 2 eventos útiles que se pueden monitorear son DataReceived y ErrorReceived.

Ok, entonces es como una interrupción pero el VC# lo maneja de forma automática, entonces ¿con inicializar y configurar el puerto basta para que el evento (cuando llega un dato al buffer) se ejecute?
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 24 de Agosto de 2009, 20:39:31
Mmhh, debes vincular el evento con la función que llamará.

Si creas el objeto puertoserie usando las herramientas, es decir, sin escribir código, puedes activar el evento siguiendo los pasos de arriba:

- Para monitorear cuando llegan los datos deberás implementar una función detonada por evento. Da click en el serialPort1 y después en el iconito con forma de rayo en la ventana Propiedades.

- Da doble click en DataReceived y se creará una función que se va a ejecutar cada que se recibe cualquier dato en el puerto.

Desconozco el código para vincular el evento con la función, pero por eso me gusta C#, porque no tengo que andarlo buscando... solo doy click y listo  :D
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 25 de Agosto de 2009, 00:02:27
Desconozco el código para vincular el evento con la función, pero por eso me gusta C#, porque no tengo que andarlo buscando... solo doy click y listo  :D

Ya estoy descargando el express edition y según lo que describes se parece entonces al labview, que se trabaja muy poco con códigos y todas las funciones es con bloques. Lo pruebo y les cuento.

Gracias migsantiago
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 25 de Agosto de 2009, 12:49:09
Sí, es muy amigable como LabView.

Y si eres de los que les gusta escribir código sin asistentes también puedes hacerlo, solo que es más tardado.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 02 de Octubre de 2009, 13:10:18
Hola nuevamente!

Como dije anteriormente, estoy totalmente nuevo en C#, así que partiendo de eso, está este código, dónde se tiene la ventana, dos cuadros de texto (uno donde el usuario puede ingresar datos y otro donde muestra un string que llega por puerto serial), y el botón "Enviar"

Código: C#
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.IO;                        //Requerido para manejar archivos
  10.  
  11. namespace Prueba1
  12. {
  13.     public partial class Form1 : Form
  14.     {
  15.         public Form1()
  16.         {
  17.             InitializeComponent();
  18.         }
  19.  
  20.         //////////////////////////////
  21.         //Variable global
  22.         List<byte> recibido = new List<byte>();
  23.  
  24.         //////////////////////////////
  25.         //Abrir puerto COM14
  26.         private void button1_Click(object sender, EventArgs e)
  27.         {
  28.             PuertoSerie1.Open();
  29.             recibido.Clear();
  30.         }
  31.  
  32.         //////////////////////////////
  33.         //Datos en el buffer
  34.  
  35.         private void PuertoSerie1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
  36.         {
  37.             int bytes = PuertoSerie1.BytesToRead;
  38.  
  39.             byte[] buffer = new byte[bytes];
  40.  
  41.             PuertoSerie1.Read(buffer, 0, bytes);
  42.             foreach (byte elem in buffer)
  43.             {
  44.                 recibido.Add(elem);
  45.             }
  46.         }
  47.     }
  48. }
  49.  

Una duda es, ¿como puedo manipular cada elemento?, por ejemplo, que el cuadro de texto muestre lo que llega por el puerto, que el usuario al escribir y al darle al botón, se guarde el string y se envíe por puerto serial......para así entonces poder entender como manejar cada función.

Gracias!
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 02 de Octubre de 2009, 13:33:53
Hola, para que el cuadro de texto muestre el string debes armar un string y pasárselo a la propiedad .Text.

Código: [Seleccionar]
String cadena = "Datos: " + dato;
txtCadena.Text = cadena;

Si tienes dudas con lo básico de C# talvez sea mejor que estudies algún tutorial sencillo de C# en la web  ;-)
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: alexysar en 06 de Diciembre de 2009, 01:56:54
Hola, antes que nada quería agradecer a migsantiago por la info útil que subió.
Ahora, a ver si me pueden dar una manito con algo que soy principiante en c#. Cuando recibo datos por el puerto serie salto al handler de recepción pero si quiero modificar un textbox me salta una excepción, correspondiente a que varios hilos (thread) tratan de modificar el mismo textbox.
Si controlo las excepciones con try-catch no salta la excepción pero el textbox no se actualiza hasta que no paso el mouse por arriba.

 

Código: C#
  1.         private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
  2.         {
  3.             int bytes = serialPort1.BytesToRead;
  4.             byte[] buffer = new byte[bytes];
  5.             serialPort1.Read(buffer, 0, bytes);
  6.             bool box16;
  7.  
  8.  
  9.             try
  10.             {
  11.        
  12.  
  13.                 switch ((char)buffer[0])
  14.                 {
  15.                     case '0':
  16.                         if (checkBox16.Checked == true) box16 = false;
  17.                         else
  18.                         {
  19.  
  20.                             box16 = true;
  21.  
  22.  
  23.                         }
  24.                         //serialPort1.DiscardInBuffer();
  25.                         if (box16 == true) checkBox16.Checked = true;
  26.                         else checkBox16.Checked = false;
  27.                        
  28.  
  29.                         break;
  30.  
  31.  
  32.                 }
  33.             }
  34.             catch (Exception ex)
  35.             {
  36.                 //MessageBox.Show("hola".ToString());
  37.                
  38.                 //checkBox16.Checked = true;
  39.  
  40.        
  41.                 return;
  42.             }
  43.  
  44.         }
  45.  

abrazo.-
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 06 de Diciembre de 2009, 10:31:01
Hola, leo tu código pero no encuentro nada que hable de una textbox, solo de una checkbox.  :huh:

Si declaraste varios threads entonces deberás mantener la textbox con una variable global o algún semáforo que te permita escribirla solo cuando otro no esté manipulándola.

Código: [Seleccionar]
//Variable global
Boolean semaforo = false;

//Código en thread1
while(semaforo==true)
   Thread.Sleep(10); //Espera 10ms a que thread2 pierda control de textbox
   semaforo=true;
   textbox.Text = "Thread1 bajo control de textbox";
   semaforo = false;



//Código en thread2 que imagino es la atención al event serialport_DataReceived
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            int bytes = serialPort1.BytesToRead;
            byte[] buffer = new byte[bytes];
            serialPort1.Read(buffer, 0, bytes);
            
while(semaforo==true)
   Thread.Sleep(10); //Espera 10ms a que thread1 pierda control de textbox
   semaforo=true;
   textbox.Text = "Thread1 bajo control de textbox";
   semaforo = false;
        }

Algo así podrías hacer.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: alexysar en 06 de Diciembre de 2009, 15:15:36
Gracias migsantiago,
no lees nada de textbox porque me equivoque, quise poner checkbox en su lugar. Disculpa, lamento el error.
De todas formas entiendo lo que me decís de los semáforos y creo que lo voy a poder solucionar por ese lado.

Nuevamente te estoy muy agradecido, sos un groso.
Abrazo.-


Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 06 de Diciembre de 2009, 15:22:42
jeje

A ver si cuando quede nos ayudas con el asunto de los threads porque quiero aprender a usarlos.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: Tisco en 06 de Diciembre de 2009, 17:34:45
jeje

A ver si cuando quede nos ayudas con el asunto de los threads porque quiero aprender a usarlos.

Pues aqui te presento una forma de hacerlo  ;-)

Código: C#
  1.  
  2. /* EN EL PROGRAMA PRINCIPAL */
  3.  
  4.  
  5. private void Form1_Load(object sender, EventArgs e)
  6.         {
  7.             Thread_RS232 hilo1 = new Thread_RS232(serialPort1);
  8.         }
  9.  
  10. private void Form1_FormClosed(object sender, FormClosedEventArgs e)
  11.         {
  12.             if (hilo1 != null) hilo1._idTh.Interrupt();
  13.         }
  14.  
  15.  
  16. /* EN LA CLASE DEL THREAD  */
  17.  
  18.  
  19. class Thread_RS232
  20. {
  21.     public Thread _idTh;
  22.     SerialPort _canalserie;
  23.     bool Terminated = false;
  24.  
  25.     public Thread_RS232(SerialPort canalserie)
  26.     {
  27.         _canalserie = canalserie;
  28.         _idTh = new Thread(new ThreadStart(Execute));
  29.         _idTh.Name = "TH_RS232";
  30.         _idTh.Start();
  31.     }
  32.    
  33.  
  34.     void Execute()
  35.     {
  36.  
  37.         if (!_canalserie.IsOpen)
  38.         {
  39.             _canalserie.Open(); // Abrimos canal de comunicaciones
  40.         }
  41.        
  42.         while (!Terminated)
  43.         {
  44.             try
  45.             {
  46.                 // Tratado del RS232
  47.             }
  48.             catch (ThreadInterruptedException)
  49.             {
  50.                 Terminated = true;
  51.             }
  52.         } // while (!Terminated)
  53.         _canalserie.Close();    // Cerramos canal de comunicaciones
  54.     } // Execute
  55. } // CLASS

Espero que te sirva  ;-)
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 06 de Diciembre de 2009, 20:18:30
jeje

A ver si cuando quede nos ayudas con el asunto de los threads porque quiero aprender a usarlos.

Pues aqui te presento una forma de hacerlo  ;-)



Gracias, lo leo y aún tego mucho que estudiar.  :mrgreen:
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: Tisco en 06 de Diciembre de 2009, 20:37:54
jejeje. pues si, es una de las de cosas de C#, por mucho que crees que sabes siempre te queda por aprender, yo cada dia me percato mas de ello (por lo menos ese es mi caso :mrgreen: :mrgreen:).
;-)
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 07 de Diciembre de 2009, 00:38:32
jejeje. pues si, es una de las de cosas de C#, por mucho que crees que sabes siempre te queda por aprender, yo cada dia me percato mas de ello (por lo menos ese es mi caso :mrgreen: :mrgreen:).
;-)

También el mío jeje
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 22 de Febrero de 2010, 03:28:26
Hola compañeros.

Este post ya tiene un par de meses inactivo, pero quiero seguir con el tema.

Ya me instruí al menos en lo básico de C# y ya se identificar (de nuevo en lo básico) los códigos.

Tengo un par de dudas:

1) Compa migsantiago, en el código de tu ejemplo, usas un List<byte>, pero el compilador no lo reconoce, ¿hay que declarar un namespace específico o donde está el detalle?, he buscado en la web pero no aparece información al respecto. Claro está, es un modo entre otros de guardar el byte en el array, pero para que no me quede la duda.

2) Quiero exponerles el siguiente caso: Supongan dos PC, de la PC1 se envía un dato al PC2, se necesita verificar que el dato que llegó al PC2, es el mismo (sin algún tipo de error) que se envió del PC1, ahora, de que forma creen ustedes compañeros, que se puede hacer esto?

He pensado en convertir todos los caracteres ASCII en decimal y realizar una suma de esos valores, entonces este valor se transmite en la trama junto con el dato y el PC receptor hace la misma conversión ASCII a decimal y compara su valor con el enviado y si es igual, la transmisión fue correcta.....no se si se puede hacer ésto, pero qué otra manera puede haber?

Gracias por sus respuestas.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 22 de Febrero de 2010, 13:18:20
Hola, usé VS 2008 Express Edition. Talvez estés usando una versión anterior o no sé. Danos más datos sobre el error dado.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: Franc749 en 22 de Febrero de 2010, 14:00:15
Muy bueno el post. me re-interesa.

Disculpen mi total ingnoracia en  C#.  PEro es posible hacer un programa que se ejecute solo sin tener intalado el VS 2008 Express?

Tengo que hacer una muy pequeña aplicacion de recepcion de datos por puerto serie. Y quiero que el usuario final lo ejecute simplemente haciendo click con el mouse.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 22 de Febrero de 2010, 14:10:17
Muy bueno el post. me re-interesa.

Disculpen mi total ingnoracia en  C#.  PEro es posible hacer un programa que se ejecute solo sin tener intalado el VS 2008 Express?

Tengo que hacer una muy pequeña aplicacion de recepcion de datos por puerto serie. Y quiero que el usuario final lo ejecute simplemente haciendo click con el mouse.

No, debes instalar el net framework 3.5 para que la aplicación corra en la máquina del cliente.

http://www.microsoft.com/downloads/details.aspx?FamilyId=AB99342F-5D1A-413D-8319-81DA479AB0D7&displaylang=en

O debes crear un instalador para que se descargue el framewrok.

http://electrolinks.blogspot.com/2009/06/auto-instalador-de-proyectos-visual.html
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 22 de Febrero de 2010, 14:17:09
Disculpen mi total ingnoracia en  C#.  PEro es posible hacer un programa que se ejecute solo sin tener intalado el VS 2008 Express?

Al compilar el código te da el .EXE que es el que interesa y puedes ejecutar en cualquier computadora, PERO, tienes que instalar las librerías .NET Framework, por ejemplo si compilas con el C# 2008, en la máquina dónde quieres ejecutar el programa, instalas la versión 3.5 de .NET Framework.

Hola, usé VS 2008 Express Edition. Talvez estés usando una versión anterior o no sé. Danos más datos sobre el error dado.

Compañero migsantiago, estoy usando la versión 2008 express también y voy a usar la versión pro para usar unas características que la express no tiene y allí probaré, y que opinan sobre la lógica que comenté al final?.....


2) Quiero exponerles el siguiente caso: Supongan dos PC, de la PC1 se envía un dato al PC2, se necesita verificar que el dato que llegó al PC2, es el mismo (sin algún tipo de error) que se envió del PC1, ahora, de que forma creen ustedes compañeros, que se puede hacer esto?

He pensado en convertir todos los caracteres ASCII en decimal y realizar una suma de esos valores, entonces este valor se transmite en la trama junto con el dato y el PC receptor hace la misma conversión ASCII a decimal y compara su valor con el enviado y si es igual, la transmisión fue correcta.....no se si se puede hacer ésto, pero qué otra manera puede haber?

Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: alexysar en 22 de Febrero de 2010, 14:27:19
No estoy completamente seguro de lo que voy a decir, pero creo que el protocolo RS232 ya tiene incluido el chequeo de errores mediante un checksum.-
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 22 de Febrero de 2010, 14:35:39
No estoy completamente seguro de lo que voy a decir, pero creo que el protocolo RS232 ya tiene incluido el chequeo de errores mediante un checksum.-


¿El checksum no es para los archivos?, aunque si es así, podría guardar el dato a enviar en un archivo temporal y en el receptor que lea el archivo y haga el checksum.....hablo en teoría, si alguien sabe algo sobre checksum...?
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 22 de Febrero de 2010, 14:37:17
2) Quiero exponerles el siguiente caso: Supongan dos PC, de la PC1 se envía un dato al PC2, se necesita verificar que el dato que llegó al PC2, es el mismo (sin algún tipo de error) que se envió del PC1, ahora, de que forma creen ustedes compañeros, que se puede hacer esto?

He pensado en convertir todos los caracteres ASCII en decimal y realizar una suma de esos valores, entonces este valor se transmite en la trama junto con el dato y el PC receptor hace la misma conversión ASCII a decimal y compara su valor con el enviado y si es igual, la transmisión fue correcta.....no se si se puede hacer ésto, pero qué otra manera puede haber?

Gracias por sus respuestas.

Es la manera más fácil. Está bien.

No estoy completamente seguro de lo que voy a decir, pero creo que el protocolo RS232 ya tiene incluido el chequeo de errores mediante un checksum.-


Sí, es seguro que desde el hardware se hagan revisiones físicas de las señales recibidas. Hay un evento vinculado al objeto SerialPort llamado ErrorReceived. Seguro que ahí puedes meter mano y revisar exactamente qué pasó, pero talvez sea más complicado que el checksum que propone Sauron.

El checksum es un simple algoritmo matemático en donde se meten los datos recibidos y se obtiene uno de salida. Si el dato de salida es idéntico al esperado entonces la cadena de datos llegó bien.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 22 de Febrero de 2010, 14:47:35
Es la manera más fácil. Está bien.

Ok gracias por tu respuesta, puedo intentar ese método.

Ya que comentas sobre el evento ErrorReceived del puerto, encontré éste método vinculado a ese evento, con los siguientes casos:

Código: C#
  1. void Método_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
  2.         {
  3.            
  4.             switch (e.EventType)
  5.             {
  6.                 case SerialError.Frame:
  7.                     MessageBox.Show("Error de trama...");
  8.                     break;
  9.                 case SerialError.Overrun:
  10.                     MessageBox.Show("Saturación de buffer...");
  11.                     break;
  12.                 case SerialError.RXOver:
  13.                     MessageBox.Show("Desbordamiento de buffer de entrada");
  14.                     break;
  15.                 case SerialError.RXParity:
  16.                     MessageBox.Show("Error de paridad...");
  17.                     break;
  18.                 case SerialError.TXFull:
  19.                     MessageBox.Show("Buffer lleno...");
  20.                     break;
  21.  
  22.             }
  23.  

Creo que se podría agregar al programa para darle mayor seguridad a la transmisión.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 23 de Febrero de 2010, 00:35:59
Siguiendo con el tema.....

Estoy intentando convertir el texto que el usuario ingresa por un TextBox a un entero, pero me tira una excepción, pongo el código a ver que estoy haciendo mal.

Código: C#
  1. private void BtnEnviar_Click(object sender, EventArgs e)
  2.         {
  3.             string ParaEnviar;
  4.             ParaEnviar = StringEnviar.Text;
  5.  
  6.             //Convierte el string ParaEnviar en entero
  7.             int Check;
  8.             Check = Convert.ToInt32(StringEnviar.Text);
  9.           //Check = int.Parse(StringEnviar.Text);
  10.  

He intentado varias formas, cambiar el tipo de dato, usar el int.Parse, etc....y siempre me da la excepción en esa línea, ¿en dónde me estaré equivocando?
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: Geo en 23 de Febrero de 2010, 01:56:19
¿Qué excepción?
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 23 de Febrero de 2010, 02:10:25
¿Qué excepción?

Vale, no se trabajar con las excepciones, pero depuré el código y cuando salta el error, sale para detallar la excepción y ésto me arrojó...

Código: [Seleccionar]
No se controló System.FormatException
  Message="La cadena de entrada no tiene el formato correcto."
  Source="mscorlib"
  StackTrace:
       en System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
       en System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
       en System.Convert.ToInt32(String value)
       en SoftwarePC_Beta.SoftwarePC_Beta.BtnEnviar_Click(Object sender, EventArgs e) en D:\Mis documentos\Visual Studio 2008\Projects\SoftwarePC_Beta\SoftwarePC_Beta\SoftwarePC_7450_(Beta).cs:línea 73
       en System.Windows.Forms.Control.OnClick(EventArgs e)
       en System.Windows.Forms.Button.OnClick(EventArgs e)
       en System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       en System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       en System.Windows.Forms.Control.WndProc(Message& m)
       en System.Windows.Forms.ButtonBase.WndProc(Message& m)
       en System.Windows.Forms.Button.WndProc(Message& m)
       en System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       en System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       en System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       en System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       en System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       en System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       en System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       en System.Windows.Forms.Application.Run(Form mainForm)
       en SoftwarePC_Beta.Program.Main() en D:\Mis documentos\Visual Studio 2008\Projects\SoftwarePC_Beta\SoftwarePC_Beta\Program.cs:línea 18
       en System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       en System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       en Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       en System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       en System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       en System.Threading.ThreadHelper.ThreadStart()
  InnerException:


Agrego algo: En el TextBox ingreso cualquier cadena, desde simplemente "Hola" hasta "forihforhgoghroighroghorighriorrgrg" y siempre salta la excepción. Como dije en mi comentario anterior, he cambiado los tipos de datos de int, a long, etc...., vuelvo a escribir el código del error:

Código: C#
  1. private void BtnEnviar_Click(object sender, EventArgs e)
  2.        {
  3.            string ParaEnviar;
  4.            ParaEnviar = StringEnviar.Text;                        //StringEnviar es el nombre del TextBox
  5.           //Convierte el string ParaEnviar en entero
  6.            int Check;
  7.            Check = Convert.ToInt32(StringEnviar.Text);    //Aquí se da la excepción
  8.         //Check = int.Parse(StringEnviar.Text);               //Aquí TAMBIÉN se da la excepción
  9.  
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 23 de Febrero de 2010, 13:36:00
Lo estás haciendo mal, estás convirtiendo una cadena de texto en enteros y eso no se puede.

Debes convertir cada caracter del string en una variable char o byte, busca la función apropiada para convertir un String a un Char Array.

string.ToCharArray()

Una vez convertido pásala a byte.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 23 de Febrero de 2010, 19:31:27
Lo estás haciendo mal, estás convirtiendo una cadena de texto en enteros y eso no se puede.

Ok, gracias por la aclaración, me estaba guiando por ésta ayuda de MSDN, allí dicen que se puede aplicar así pero bueno...
http://msdn.microsoft.com/es-es/library/1aey0kb6.aspx (http://msdn.microsoft.com/es-es/library/1aey0kb6.aspx)

Probé de ésta manera y funcionó:

Código: C#
  1. //Cambia el StringBinario en un entero
  2. UInt32 Checksum = BitConverter.ToUInt32(BinarioEnviar, 0);  //BinarioEnviar es un byte array
  3.  

Ahora, quiero analizar como es la conversión que hace, éstos son los datos que arroja:

Ingreso en el TextBox          Convierte al entero
12345                                   875770417
1234                                     875770417
1234568                                875770417
87654321                              892745528
asdf                                      1717859169
asdfghj                                  1717859169
jhgfdsa                                  1718052970

¿Al ser cada cadena diferente no debería convertir a números diferentes también?
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: Geo en 24 de Febrero de 2010, 02:05:26
¿Qué es lo que deseas hacer?

La excepción te indicó el problema, al intentar convertir una cadena a un número, puedes convertir sin problemas cadenas como "123" o "345345", porque son números enteros expresados como cadenas de texto, pero ¿a qué número entero convertirías "zzxx" o "todopic"? La función ToInt32 de la clase Convert espera un cierto formato en la cadena de texto que recibirá para convertirla, al introducir caracteres no convertibles te lanza la excepción.

Lo estás haciendo mal, estás convirtiendo una cadena de texto en enteros y eso no se puede.
Si se puede, mientras se respete cierto formato.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 24 de Febrero de 2010, 02:30:35
¿Qué es lo que deseas hacer?

La idea compañero, es pasar un dato por puerto serial, pero quiero agregarle una comprobación o checksum de que el dato recibido es el mismo que el enviado. En los post más arriba, comentaba un método que pensé sobre la posibilidad de pasar el dato a un número, luego ese número se pasa al receptor y éste a su vez realiza la conversión (DatoRecibido a un número) y compara los números. Si son iguales pues el dato es correcto. Por eso mostré esas conversiones de los datos a números, pero no comprendo esa conversión.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: Geo en 24 de Febrero de 2010, 05:19:32
Ya entendí :). Se trata de obtener el equivalente decimal de cada caracter, no lo conseguirás de la forma que estás intentando. La clase String permite obtener cada letra que contenga como un Char utilizando los operadores [], de ahí con un "cast" a int obtienes el equivalente decimal del caracter.

Con esto lo consigues:

Código: C#
  1. String cadena = txtTexto.Text;
  2.  
  3. int suma = 0;
  4. for (int c = 0; c < cadena.Length; c++)
  5. {
  6.     MessageBox.Show( cadena[ c ] + " = " + c.ToString() );
  7.     suma += (int)cadena[c];
  8. }
  9. MessageBox.Show("La suma de los caracteres convertidos a decimal es: " + suma.ToString());
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 24 de Febrero de 2010, 05:49:38
Ya entendí :). Se trata de obtener el equivalente decimal de cada caracter, no lo conseguirás de la forma que estás intentando. La clase String permite obtener cada letra que contenga como un Char utilizando los operadores [], de ahí con un "cast" a int obtienes el equivalente decimal del caracter.

Con esto lo consigues:

 :mrgreen: Excelente compañero Geo, funciona perfecto, se puede hacer un CheckSum con esa función, muchas gracias!
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: Geo en 24 de Febrero de 2010, 14:39:59
:mrgreen: Excelente compañero Geo, funciona perfecto, se puede hacer un CheckSum con esa función, muchas gracias!
De nada. Ya contarás cómo avanza el proyecto :).
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: sauron en 26 de Febrero de 2010, 06:30:53
De nada. Ya contarás cómo avanza el proyecto :).

Bueno compañero, ya el programa envía, recibe, realiza la verificación del checksum, y guarda los datos que van y vienen en un archivo, además de un registro de los errores, también se agrega la fecha del dato......creo que ya casi está listo.

Ahora, estaba pensando en agregar otra funcionalidad: De que el usuario elija que puerto serial usar, ésto quiere decir, que al usuario elegir, se debe verificar que ese puerto no esté en uso.

Con un ListBox, obtengo y muestro al usuario la lista de puertos disponibles, pero estoy enredado en como verificar que el puerto esté abierto, me explico:

Código: C#
  1. SerialPort port = new SerialPort();
  2. .
  3. .
  4. .
  5. private void ElegirPuerto1_SelectedIndexChanged(object sender, EventArgs e)
  6.         {
  7.             string puerto = (string)ElegirPuerto1.SelectedItem;      //ElegirPuerto1 es el nombre del ListBox
  8.             this.port.PortName = puerto;                              //AQUI OCURRE UNA EXCEPCION
  9.             if (port.IsOpen)
  10.                 MessageBox.Show("Puerto Serial EN USO");
  11.             else
  12.                 this.port.Open();
  13.         }
  14.  

Luego, en this.port.PortName = puerto, ocurre una excepción cuando el puerto elegido está en uso.
Lo ideal sería colocar el if (port.IsOpen) pero como le asigno a port el puerto a verificar.

Finalmente la pregunta es, ¿cómo puedo hacer para que cuando el usuario, al elegir del listbox un puerto, se verifique que esté o no en uso?

Gracias compañeros.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: Mando31 en 12 de Mayo de 2010, 16:35:18
Hola, primeramente el chksum que realizas al convertir el string a su equivalente decimal realizar una suma y enviarlo no es conveniente, no aseguras en verdad el dato, ya que en decimal es sumamente facil que se altere tu estas enviando por ejemplo HOLA y digamos que te genera un CHeksum de 65 ese numero tmb lo envias y puede sufrir una modificacion en el PC receptor puedes recibir 64 en lugar de 65 y aunque la palabra este bien el numeor con el que compraras esta mal, luego hay una infinidad de porque no usar decimal como comprovador de erores, te recomiendo más una implementacion de paridad o de imparidad, un CRC o Codigo Hamming, investigalos y ya notaras que es más seguro usar este tipo de tecnicas para comprobacion de errores, no de los más usados es el CRC, solo tendiras que realiza una conversion del string que envias a su codigo ascii de este pasarlo a binario y aplicarle aguna de las tecnicas que te menciono.

Cualquier cosa que te pueda ayudar con gusto lo hare.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: jdnichollsc en 18 de Mayo de 2010, 22:26:30
bueno....esta gente tiene mucho conocimiento....pero necesito sabe como hago para comunicar 2 pc por bluetooth....en la cual yo no se en q momento el otro me mande un mensaje....
hasta ahora tengo esto

Código: [Seleccionar]
BluetoothDeviceInfo[] bdi;
        string BTMAC;
        string BTName;
        OpenNETCF.Net.BluetoothAddress btaddress;
        OpenNETCF.Net.Sockets.BluetoothClient client;
        OpenNETCF.Net.BluetoothEndPoint endpoint;
        NetworkStream stream;
        OpenNETCF.Net.Sockets.BluetoothListener lis;
       
       

       


        //Looking for devices in the area
        private void discover()
        {
            //discover devices
            addtolog("Discovering Devices...");

            BluetoothClient bc = new BluetoothClient();
            bdi = bc.DiscoverDevices(5);
           
            comboBox1.DataSource = bdi;
            comboBox1.DisplayMember = "DeviceName";

            addtolog("Done, " + bdi.Length + " Device(s) found");
        }
private void addtolog(string msg)
        {
            txtmessage.Text = txtmessage.Text + msg + "\r\n";
            Application.DoEvents(); // update display
        }

        //DISCOVER
        private void button1_Click(object sender, EventArgs e)
        {
            AXWS.URL = abc1;
            AXWS.Ctlcontrols.play();
            txtmessage.Visible = true;
            comboBox1.Visible = true;
            discover();
        }

        //TEXT BOX
        private void textBox2_TextChanged(object sender, EventArgs e)
        {
        }

        //COMBO BOX
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            BTMAC = bdi[comboBox1.SelectedIndex].DeviceID.ToString();
            BTName = bdi[comboBox1.SelectedIndex].DeviceName.ToString();

            Application.DoEvents(); // update display
        }

        //CONNECT BUTTON
       
        private void button2_Click(object sender, EventArgs e)
        {
            AXWS.URL = ab;
            AXWS.Ctlcontrols.play();
            BTMAC = bdi[comboBox1.SelectedIndex].DeviceID.ToString();
            BTName = bdi[comboBox1.SelectedIndex].DeviceName.ToString();
           

            if (OBEXOpenStream(BTMAC))
            {

                if (OBEXConnect())
                {
                    addtolog("Connected To: "+BTMAC);
                    //stream = client.GetStream();                   
                    //receiver();
                }
                else
                {
                    txtmessage.Text = txtmessage.Text + "Unable to connect\r\n";
                }

                OBEXCloseStream();
            }
            else
            {
                addtolog("Failed to connect to OBEX Server");
                AXWS.Ctlcontrols.play();
                AXWS.URL = abc2;
            }
        }

        private void addtolog2(string msg)
        {
            textBox1.Text = textBox1.Text + msg + "    ";
           
            Application.DoEvents(); // update display
        }
        //SEND BUTTON
        private string mens;
        public int cont=0;
        public string funcion;
        private string fil="";
        private void button3_Click(object sender, EventArgs e)
        {
            if (textBox2.Text != "")
            {
                cont = cont + 1;
                int art = 0; int brt = 0; int xrt = 0;//a, x y b
                funcion = "(" + Convert.ToString(art) + Convert.ToString(xrt) + "+" + Convert.ToString(brt) + ")%104";
                string a = textBox2.Text;
                string envio="";
                for (int m = 0; m< textBox2.TextLength; m++)
                {
                    string b = a.Substring(m,(textBox2.Text.Length+1)-(textBox2.Text.Length));     
                    char sHex1 = Convert.ToChar(b);                   
                    for (int x = 0; x < 104; x++)
                    {
                       
                        string sHex = Cript[x];
                        byte newByte = byte.Parse(sHex, System.Globalization.NumberStyles.AllowHexSpecifier);
                        int i = Convert.ToInt32(newByte.ToString());
                        Char schar = Convert.ToChar(i);

                        if (schar == sHex1)
                        {
                            envio= envio+ " "+ Cript[x];
                            x = 105;
                           
                        }
                    }

                }
                textBox1.Text += envio +"\n";
                mens = envio;
               
                string min=Convert.ToString(DateTime.Now.Minute);
                FileStream ab = File.Create(Application.StartupPath + "\\Mensajes\\" + cont.ToString() + ".txt");
                fil = Convert.ToString(cont) + ".txt";
                string todo = funcion + " " + min + " " + envio;
                byte[] by = Encoding.Default.GetBytes(todo);
                foreach(byte b in by)
                {
                    ab.WriteByte(b);
                }
                ab.Flush();
                ab.Close();
                string strConexion, strOrden;
                OleDbDataAdapter dtaMor = new OleDbDataAdapter();
                DataTable dTable = new DataTable();
                DataSet dtsC = new DataSet();
                string conex = Application.StartupPath + "\\mensajes.mdb";
                strConexion = "Provider = Microsoft.jet.OLEDB.4.0; Data Source =" + conex;
                strOrden = "INSERT INTO Mensajes (Id,Encriptado, Descencriptado) Values ('"+ cont+"','" + mens + "', '" + textBox2.Text + "')";
                dtaMor = new OleDbDataAdapter(strOrden, strConexion);
                dtaMor.Fill(dtsC);
                dataGridView1.DataSource = dtsC.Tables["'+Mensajes+'"];
                if (dtsC.HasChanges())
                {
                    dtaMor.Update(dtsC);
                   
                }
            }
            else
                MessageBox.Show("NO HA INGRESADO UN MENSAJE TODAVÍA");
           

            if (txtmessage.Visible == true)
            {
                //Send a file
                addtolog("Sending File...");

                if (OBEXOpenStream(BTMAC))
                {
                    if (OBEXConnect())
                    {
                        //send client request, start put
                        string tName = "HelloWorld.txt";
                        string tType = "";
                        // string tFileContent = "Hi this is a test!!";
                        string tFileContent = OpenFile();

                        int result = OBEXRequest("PUT", tName, tType, tFileContent);//mensaje, minuto, funcion

                        switch (result)
                        {
                            case 160: // 0xa0
                                addtolog("OK");
                                break;

                            case 197: // 0xc5
                                addtolog("Method not allowed");
                                break;

                            case 192: // 0xc0
                                addtolog("Bad Request");
                                break;

                            default:
                                addtolog("Other Error");
                                break;
                        }
                    }

                    OBEXCloseStream();
                }
                else
                {
                    addtolog("Failed to connect to OBEX Server");
                }
            }
        }

        /*************************************************************************************/
        private bool OBEXOpenStream(string BTMAC)
        {
            // serial port UUID
            Guid spguid = OpenNETCF.Net.Bluetooth.BluetoothService.ObexObjectPush;
            btaddress = OpenNETCF.Net.BluetoothAddress.Parse(BTMAC);
            client = new OpenNETCF.Net.Sockets.BluetoothClient();
           
            // define endpoint
            endpoint = new OpenNETCF.Net.BluetoothEndPoint(btaddress, spguid);
            lis = new OpenNETCF.Net.Sockets.BluetoothListener(endpoint);
            try
            {
                //open socket
                client.Connect(endpoint);
            }
            catch (System.Exception e)
            {
                //unable to connect (server not listening on spguid)
                return false;
            }

            //connect socket
            stream = client.GetStream();
            return true;
        }

        private void OBEXCloseStream()
        {
            stream.Close();
            client.Close();
        }

        private bool OBEXConnect()
        {
            //send client request
            byte[] ConnectPacket = new byte[7];

            ConnectPacket[0] = 0x80; // Connect
            ConnectPacket[1] = 0x00; // Packetlength Hi Byte
            ConnectPacket[2] = 0x07; // Packetlength Lo Byte
            ConnectPacket[3] = 0x10; // Obex v1
            ConnectPacket[4] = 0x00; // no flags
            ConnectPacket[5] = 0x20; // 8k max packet size Hi Byte
            ConnectPacket[6] = 0x00; // 8k max packet size Lo Byte

            stream.Write(ConnectPacket, 0, ConnectPacket.Length);

            //listen for server response
            byte[] ReceiveBufferA = new byte[3];
            stream.Read(ReceiveBufferA, 0, 3);

            if (ReceiveBufferA[0] == 160) // 0xa0
            {

                //success, decode rest of packet
                int plength = (0xff * ReceiveBufferA[1]) + ReceiveBufferA[2]; //length of packet is...

                //listen for rest of packet
                byte[] ReceiveBufferB = new byte[plength - 3];
                stream.Read(ReceiveBufferB, 0, plength - 3);
                //serialPort1.Read(ReceiveBufferB, 0, plength - 3);
                int obver = ReceiveBufferB[0]; //server obex version (16 = v1.0)
                int cflags = ReceiveBufferB[1]; //connect flags
                int maxpack = (0xff * ReceiveBufferB[2]) + ReceiveBufferB[3]; //max packet size

                return true;
            }
            else
            {
                return false;
            }
        }

        private int OBEXRequest(string tReqType, string tName, string tType, string tFileContent)
        {
            //send client request

            int i;
            int offset;
            int packetsize;
            byte reqtype = 0x82;

            int tTypeLen = 0x03;
            int typeheadsize;
            int typesizeHi = 0x00;
            int typesizeLo = 0x03;


            if (tReqType == "GET")
            {
                reqtype = 0x83; // 131 GET-Final
            }

            if (tReqType == "PUT")
            {
                reqtype = 0x82; // 130 PUT-Final
            }

            packetsize = 3;

            //Name Header
            int tNameLength = tName.Length;
            int nameheadsize = (3 + (tNameLength * 2) + 2);
            int namesizeHi = (nameheadsize & 0xff00) / 0xff;
            int namesizeLo = nameheadsize & 0x00ff;
            packetsize = packetsize + nameheadsize;

            if (tType != "")
            {
                //Type Header
                tTypeLen = tType.Length;
                typeheadsize = 3 + tTypeLen + 1;
                typesizeHi = (typeheadsize & 0xff00) / 0xff;
                typesizeLo = typeheadsize & 0x00ff;
                packetsize = packetsize + typeheadsize;
            }

            //Body
            int fileLen = tFileContent.Length;
            int fileheadsize = 3 + fileLen;
            int filesizeHi = (fileheadsize & 0xff00) / 0xff; ;
            int filesizeLo = fileheadsize & 0x00ff; ;

            packetsize = packetsize + fileheadsize;

            int packetsizeHi = (packetsize & 0xff00) / 0xff;
            int packetsizeLo = packetsize & 0x00ff;

            byte[] tSendByte = new byte[packetsize];

            //PUT-final Header
            tSendByte[0] = reqtype; // Request type e.g. PUT-final 130
            tSendByte[1] = Convert.ToByte(packetsizeHi); // Packetlength Hi
            tSendByte[2] = Convert.ToByte(packetsizeLo); // Packetlength Lo

            offset = 2;

            //Name Header
            tSendByte[offset + 1] = 0x01; // HI for Name header
            tSendByte[offset + 2] = Convert.ToByte(namesizeHi); // Length of Name header (2 bytes per char)
            tSendByte[offset + 3] = Convert.ToByte(namesizeLo); // Length of Name header (2 bytes per char)

            // Name+\n\n in unicode
            byte[] tNameU = System.Text.Encoding.BigEndianUnicode.GetBytes(tName);
            tNameU.CopyTo(tSendByte, offset + 4);

            offset = offset + 3 + (tNameLength * 2);
            tSendByte[offset + 1] = 0x00; // null term
            tSendByte[offset + 2] = 0x00; // null term

            offset = offset + 2;

            if (tType != "")
            {
                //Type Header
                tSendByte[offset + 1] = 0x42; // HI for Type Header 66
                tSendByte[offset + 2] = Convert.ToByte(typesizeHi); // Length of Type Header
                tSendByte[offset + 3] = Convert.ToByte(typesizeLo); // Length of Type Header

                for (i = 0; i <= (tTypeLen - 1); i++)
                {
                    tSendByte[offset + 4 + i] = Convert.ToByte(Convert.ToChar(tType.Substring(i, 1)));
                }
                tSendByte[offset + 3 + tTypeLen + 1] = 0x00; // null terminator

                offset = offset + 3 + tTypeLen + 1;
            }

            //Body
            tSendByte[offset + 1] = 0x49; //HI End of Body 73
            tSendByte[offset + 2] = Convert.ToByte(filesizeHi); //
            tSendByte[offset + 3] = Convert.ToByte(filesizeLo); //1k payload + 3 for HI header

            for (i = 0; i <= (fileLen - 1); i++)
            {
                tSendByte[offset + 4 + i] = Convert.ToByte(Convert.ToChar(tFileContent.Substring(i, 1)));
            }
            //tSendByte[offset+4+fileLen] = 0x00; // null terminator

            offset = offset + 3 + fileLen;

            stream.Write(tSendByte, 0, tSendByte.Length);

            //listen for server response

            //TODO: can hang here forever waiting response...

            bool x = stream.DataAvailable; // changed bluetoothclient - public NetworkStream GetStream()

            byte[] tArray4 = new byte[3];
            stream.Read(tArray4, 0, 3);

            x = stream.DataAvailable;

            if (tArray4[0] == 160) // 0xa0
            {
                int plength = (tArray4[1] * 256) + tArray4[2] - 3;
                byte[] tArray5 = new byte[plength];
                if (plength > 0)
                {
                    stream.Read(tArray5, 0, plength);
                    //TODO: data in returned packet to deal with
                }
                return 160;
            }

            if (tArray4[0] == 197) // 0xc5 Method not allowed
            {
                return 197;
            }

            if (tArray4[0] == 192) // 0xc0 Bad Request
            {
                return 192;
            }

            return 0;
        }

        /************************************************************************************/


        public String OpenFile()
        {
            StreamReader sr = new StreamReader(Application.StartupPath+"\\Mensajes\\"+fil);
            String line = sr.ReadLine();
            return line;
        }

tengo la aplicacion como un trabajo de criptografia...pero quiero saber como recibir un txt o string....en tiempo de ejecucion sin saber en q momento me mandara el mensaje el otro pc.....si algo me piden....y les paso el trabajo hecho en visual c# 2010....por si no lo entienden ahi...jejejej  :D
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 19 de Mayo de 2010, 11:06:39
Este tema es sobre el puerto serie y no se usa para la comunicación bluetooth que estás publicando.

Es mejor que abras un nuevo tema en este subforo.
Título: Como interactuar visual C# con el pic 18f2550
Publicado por: Lucy en 06 de Junio de 2010, 10:56:18
Hola por favor me pueden ayudar estoy haciendo un programa en el que deseo enviar una letra de encendido y otra de apagado por el serial port del pc  que vaya al pic 18f2550 y se prenda y apague un led, esto mediante visual C# desde el pc y con Micro C programar para el pic.

He estado buscando informacion pero no tengo claro aun por favor ayudenme como abrir y cerrar el portico serial del pc y como enviar la informacion.

Gracias de antemano. Estaré esperando su ayuda.
Título: Re: Como interactuar visual C# con el pic 18f2550
Publicado por: migsantiago en 06 de Junio de 2010, 13:04:38
Hola por favor me pueden ayudar estoy haciendo un programa en el que deseo enviar una letra de encendido y otra de apagado por el serial port del pc  que vaya al pic 18f2550 y se prenda y apague un led, esto mediante visual C# desde el pc y con Micro C programar para el pic.

He estado buscando informacion pero no tengo claro aun por favor ayudenme como abrir y cerrar el portico serial del pc y como enviar la informacion.

Gracias de antemano. Estaré esperando su ayuda.

Hola, lee el primer mensaje de este tema.  ;-)

Sobre mikroC puedes publicar tus avances en el subforo de C para micros pic y respecto a tus avances se te proporcionará ayuda.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: bib22jason en 29 de Julio de 2010, 17:01:33
Hola!!!

Soy nuevo en foro, tengo algunas dudas sobre como trabajar en el puerto serial, gracias a ustedes puedo comprender un poco sobre esto.

mi problematica es la siguiente: Recibo datos a la Pc por el puerto serial (esto ya no es problema) , se guardan en un string (tampoco es problema), este string lo meto en un text file y termine.

esta es la rutina que debe seguir mi programa, pero el problema es que cuando supuestamente debe guardar la segunda cadena en el text file el programa se cierra y ya no hace nada, les pongo el codigo con el qu estoy trabajando. les agradeceria q me ayudaran con este problema. (disculpen el desorden de la escrtura)


public Form1()
        {
            InitializeComponent();
        }
        int bandera = 1;   //  igual y esto no es necesario, pero lo puse para indagar en mi problema de que se cierra el programa

        StreamWriter ARCHI = new StreamWriter(@"c:\\archivos1\\paso.txt", true);    // abre archivo

        private void Form1_Load(object sender, EventArgs e) // se abre el puerto automaticamente cuando ejecuto el programa
        {
            if (bandera == 1)
            {
                serialPort1.Open();
            }

            recibido.Clear(); // limpia el puerto
        }



        string numeros; // guardo los datos recibidos aqui

        List<byte> recibido = new List<byte>();
        private void button1_Click(object sender, EventArgs e)  // estas lineas son las que usa para el que envio del dato necesario para poder comenzar a recibir datos
        {
            byte[] miBuffer = new byte[1];

            miBuffer[0] = 0xDA; // Letra "simbolo raro" del ASCII.

            this.serialPort1.Write(miBuffer, 0, miBuffer.Length);
            //Abrir puerto COM1
           
        }

        DateTime x = DateTime.Now; // necesito colocar la hora despues de imprimirlo en el text file

        string hora; // el string para la hora
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
           
            ////Datos en el buffer
            int bytes = serialPort1.BytesToRead;
            if (bytes<16) // recibo 16 datos, si recibo menos no hace nada
            {
                return;
            }
            byte[] buffer = new byte[bytes];



            serialPort1.Read(buffer, 0, bytes);

            foreach (byte elem in buffer) // guardo los datos recibidos
            {
                recibido.Add(elem);
            }
           
           
            for (int i = 0; i < bytes; i=i+2) // con este for lo que hago es darle un orden a los datos recibidos y se meten dentro de la variable numeros
            {
                int aux = 0;
                string auxs;
                aux = recibido * 256 + recibido[i + 1];
                auxs = aux.ToString();
                numeros = numeros + "" + auxs + ";";
            }
       
           
            hora = "" + x; // guardo la hora en este string
           
            ARCHI.WriteLine(numeros + "   " + hora); // escribe en el archivo de texto los datos recibidos y la hora
            numeros = ""; // limpia el string
            hora = ""; // limpia el string
           
            recibido.Clear(); // limpia el bufer
            ARCHI.Close(); // cierra archivo... aqui es donde tengo dudas dado que al comienzo de estas llaves (mayor gerarquia de recepcion de datos) habia colocado la linea para abrir el  ARCHI y cerrarlo a qui al final para poder seguir escribiendo en el, pero no importando como le haga, solo lo hace una vez y el ejecutable se cierra. si me hicieran el favor de revisar estas lineas y  decirme donde esta mi error.
           
        }
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: alexysar en 29 de Julio de 2010, 19:20:34
Puede ser que cerras el archivo, pero despues no lo volves a abrir. Por ahi te puede convenir abrir el archivo en el metodo de resepción del port serie.

Código: C
  1.  
  2. private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
  3. {
  4.   StreamWriter ARCHI = new StreamWriter(@"c:\\archivos1\\paso.txt", true);    // abre archivo
  5.   .
  6.   .
  7.   .
  8.  ARCHI.close();
  9. }
  10.  
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: bib22jason en 30 de Julio de 2010, 14:39:21
Hola de nuevo!!!

alexysar, mira que me di cuenta que mi problema no es el guardado de datos en un archivo de texto, mi problema se basa en que despues de que recibo una trama de byte, y luego recibo otra trama de bytes, en ese momento se cierra el programa y esa partes es la que no entiendo el por que, ni como solucionarlo, si puedieran echarme la mano se los agradeceria.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: jhozate en 30 de Septiembre de 2010, 23:54:05
hola a todos, no se si la pregunta esta en el hilo correcto, lo q pasa es que en este momento no tengo entrenadora y no tengo nada de hard para ensayar y retomar a c#, entonces lo que quiero saber es si el siow o algun otro programa me serviría para emular o hacer puertos COM virtuales (escribir y recibir) en el portatil mientras corro mi programa en c#?
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: alexysar en 01 de Octubre de 2010, 08:46:24
el siow no lo conozco. Yo uso el Virtual Com para eso. La idea es que este programita te genera dos com virtuales que tienen una conexión de loop back interna. Por ejemplo genera el com 10 y 20 que son virtuales y estan conectados por loop back. Entonces el software que hago en c# lo conecto al com 10, y el com 20 lo conecto al hyperterminal. Asi, todo lo que mandamos desde c# al com 10 sale por el hyperterminal, y todo lo que mandemos por el hyperterminal lo recibe C#.
Espero que te sea útil.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 01 de Octubre de 2010, 10:37:29
hola a todos, no se si la pregunta esta en el hilo correcto, lo q pasa es que en este momento no tengo entrenadora y no tengo nada de hard para ensayar y retomar a c#, entonces lo que quiero saber es si el siow o algun otro programa me serviría para emular o hacer puertos COM virtuales (escribir y recibir) en el portatil mientras corro mi programa en c#?

Hola. Mientras esté enlistado en el administrador de dispositivos de Windows podrás usarlo como cualquier puerto COM sin importar si es real o virtual.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: jhozate en 01 de Octubre de 2010, 14:08:19
gracias, efectivamente he podido enviar datos desde C# hacia el programa Terminal de Bray,  no he podido visualizar en c# lo que recibo desde Terminal de Bray. Con el virtual serial port driver he creado un par de puertos el COM4 y COM5 en loop back.  COM4 para C# y COM5 para Terminal. Entonces lo que trato de hacer es poner en un label lo que reciba del COM5, asi:
Código: [Seleccionar]
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            string dato;
            int bytes = serialPort1.BytesToRead;
            byte[] buffer = new byte[bytes];
            serialPort1.Read(buffer, 0, bytes);
           
            dato = Convert.ToString(buffer[0]);
            label1.Text(dato);
       
        }


Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 01 de Octubre de 2010, 16:55:44
La última línea:

Código: [Seleccionar]
label1.Text = dato;
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: jhozate en 01 de Octubre de 2010, 22:39:18
ya corregi pero sigue sigue igual... :huh: :huh:
aparece "Operación no válida a través de subprocesos: Se tuvo acceso al control 'label1' desde un subproceso distinto a aquel en que lo creó."
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 02 de Octubre de 2010, 14:43:43
Prueba guardando el dato recibido en un string de acceso global.

Después con un timer refresca la label de la form leyendo el contenido del string global.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: jhozate en 02 de Octubre de 2010, 18:14:34
si, gracias, asi quedó bien, aunque me venia confundiendo en cómo declarar una variable global en c# porque encontré que hay que hacer una clase y declarlas ahi, pero las declare en este clase y funciona
Citar
public partial class Form1 : Form
    {
        string dato;
        int bytes;
        public byte[] buffer;

en la ayuda me indica que debo declarar las variables asi
Citar
namespace YourNamespace
{
    class YourClass
    {
    }
pero asi no me funciona  :huh:

entonces, ya logré visualizar lo que envio desde el COM5 en el label, a lo mejor estoy confundido, pero si envio desde mi COM5(Termina de bray) el 1 lo que veo en el label es el 49 (ASCII 1) y No el 1...y no se supone que con hacer
Código: [Seleccionar]
label1.text=convert.tostring(dato);deberia ver el 1??  :huh:
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 02 de Octubre de 2010, 20:25:50
Sí, debes familiarizarte más con la prog. orientada a objetos.

Sobre la conversión, así la puedes hacer:

Código: [Seleccionar]
String s = System.Text.ASCIIEncoding.ASCII.GetString(buffer);
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: jhozate en 02 de Octubre de 2010, 23:16:24
nada  :? :oops: :( este es el codigo que tengo
me sale que no se puede convertir string a byte, y que la instruccion de conversion a ASCII  tiene argumentos no validos

Código: [Seleccionar]
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        string dato;
        int bytes;
        byte[] buffer;
        string numero;
    
        public Form1()
        {
            InitializeComponent();
        }
            
        private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.Write(textBox1.Text);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
            this.Close();
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
        
            bytes = serialPort1.BytesToRead;
            byte[] buffer = new byte[bytes];
            serialPort1.Read(buffer, 0, bytes);
            dato = Convert.ToString(buffer[0]);
                      
        }

        private void button4_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
            button4.Enabled = false;
            button3.Enabled = true;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            button3.Enabled = false;
            button4.Enabled = true;

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            numero = System.Text.ASCIIEncoding.ASCII.GetString(dato);
            label1.Text = numero;
              
        }

      
    }
}



es que supongo yo que dato deberia ser un array y entonces deberia darle la direccion del array que quiero convertir...??
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: migsantiago en 03 de Octubre de 2010, 10:17:35
Estás poniendo mal el dato de la función ASCII.

Te pondré más detalle en el código para que tú mismo identifiques y corrijas el error.

Código: [Seleccionar]
Byte[] buffer = new byte[] {49};

String s = System.Text.ASCIIEncoding.ASCII.GetString(buffer);

No sólo copies y pegues... analiza el código, lee la sintaxis de las funciones que te pasé y escribe tu propio código.
Título: Re: Ejemplo - Puerto serie y C# 2008
Publicado por: Omar266 en 20 de Febrero de 2015, 23:04:38
Hola, mi pregunta es si hay una manera de que el programa detecte los puertos disponibles en ese momento. Ya que deseo utilizar comunicación Bluetooh y cada vez que agrego un nuevo dispositivo me cambia el puerto. Como deseo correr el Omar232.exe., o de que otra manera lo pudiera hacer.
Este es parte de mi código. gracias


       #region Cambio de PUERTO, VELOCIDAD Y BITS DE PARADA
        private void combo_COM_SelectedIndexChanged(object sender, EventArgs e)
        {
            serialPort1.Close();   //Cerrar puerto
            int selectIndex = comboBox_COM.SelectedIndex;
            Object SelectedItem = comboBox_COM.SelectedItem;
            serialPort1.PortName = SelectedItem.ToString();
            ///////////////////////////////////////////////////
            // Abrir puerto mientrase ejecute la aplicación
            if (!serialPort1.IsOpen)
            {
                try
                {
                    serialPort1.Open();
                    pto_temp = selectIndex;
                }
                //catch (System.Exception ex)
                catch (System.Exception )
                {
                    if(pto_temp == 0){
                    serialPort1.PortName = "COM1";
                    comboBox_COM.Text = "COM1";
                    }
                    if (pto_temp == 1)
                    {
                        serialPort1.PortName = "COM9";
                        comboBox_COM.Text = "COM9";
                    }
                    if (pto_temp == 2)
                    {
                        serialPort1.PortName = "COM5";
                        comboBox_COM.Text = "COM5";
                    }
                    if (pto_temp == 3)
                    {
                        serialPort1.PortName = "COM6";
                        comboBox_COM.Text = "COM6";
                    }
                    if (pto_temp == 4)
                    {
                        serialPort1.PortName = "COM7";
                        comboBox_COM.Text = "COM7";
                    }
                    if (pto_temp == 5)
                    {
                        serialPort1.PortName = "COM8";
                        comboBox_COM.Text = "COM8";
                    }
                    if (pto_temp == 6)
                    {
                        serialPort1.PortName = "COM10";
                        comboBox_COM.Text = "COM10";
                    }
                    MessageBox.Show("Se ha denegado acceso al puerto. \n\n" +
                    "Si la conexión es Bluetooth, asegúrate de que el MODULO este conectado. \n" , "Aviso:",
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);

                }
               
            }
            //serialPort1.Open();  // Abrir puerto
        }