# Duda programa puerto serie con Dev C++



## Tess16 (May 6, 2016)

Hola!
Soy basicamente una novata en programación , y debo hacer un chat entre dos ordenadores conectados con un cable a puerto serial con el compilador dev c++. Ya he logrado configurar el puerto, solo me falta poder enviar y recibir cadenas de string. Me han aconsejado utilizar writefile() y readfile() pero no he logrado comprender como... me preguntaba si podriais ayudarme con un ejemplo de codigo o si teneis alguna otra idea de qué utilizar para poder crear mi chat, se los agradeceria.

gracias


----------



## TRILO-BYTE (May 6, 2016)

no se que tanto llevas hecho del codigo

el puerto serie en un lenguaje C obsoleto es algo dificil de configurar.

¿ya pudiste mandar un caracter o una cadena?

pega algo de codigo que llevas hecho y el problema que tienes asi no se puede ayudar


----------



## Tess16 (May 7, 2016)

Bueno pues solo tengo el codigo que me han dado para que use de guía. El problema es que no se qué modificarle para que haga lo que necesito 
Lo que busco es poder escribir una cadena y mandarla y que el otro escriba y yo pueda recibirlo

El codigo es este:

```
#include<windows.h>
#include<string.h>
#include<conio.h>
#include<iostream>
using namespace std;
// Initialize the serial port variable and parameters
HANDLE hPort = CreateFile("COM1",
GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
DCB dcb; // Create a DCB struct variable
/* Sending Data*/
bool writebyte(char* data)
{
DWORD byteswritten;
if (!GetCommState(hPort,&dcb))
{
cout<<"\nSerial port cant b opened\n";
return false;
}
dcb.BaudRate = CBR_9600; //9600 Baud
dcb.ByteSize = 8; //8 data bits
dcb.Parity = NOPARITY; //no parity
dcb.StopBits = ONESTOPBIT; //1 stop
if (!SetCommState(hPort,&dcb)) //If Com port cannot be configured accordingly
return false;
bool retVal = WriteFile(hPort,data,1,&byteswritten,NULL); //Write the data to be sent to Serial port
return retVal; // return true if the data is written
}
int ReadByte()
{
int Val;
BYTE Byte;
DWORD dwBytesTransferred;
DWORD dwCommModemStatus;
if (!GetCommState(hPort,&dcb))
return 0;
SetCommMask (hPort, EV_RXCHAR | EV_ERR); //receive character event
WaitCommEvent (hPort, &dwCommModemStatus, 0); //wait for character
if (dwCommModemStatus & EV_RXCHAR)
ReadFile (hPort, &Byte, 1, &dwBytesTransferred, 0);
Val = Byte;
return Val;
}
int main()
{
cout<<"This is a loopback test..The Tx & Rx pins of serial port are shorted here...\n\n";
char data=2; // Enter any data to b sent
if(writebyte(&data)) // if the function returns non-zero value
cout<<" Data Sent.. "<<(int)data<<"\n";
cout<<" Data Received.. "<<ReadByte();
CloseHandle(hPort); // Close the Serial port handler
getch();
return 0;
}
```


----------



## Dr. Zoidberg (May 7, 2016)

Lo primero que tenes que hacer es partir ese programa en dos, uno para que transmita y el otro para que reciba.
Tene en cuenta que ese programa es una prueba en modo loop-back y asi es posible probar la transmision y recepcion en un programa unico y en la misma PC. Cuando tengas dos programas diferentes vas a necesitar dos puertos serie interconectados en la PC o usar dos computadoras diferentes.

PD: ningun C es obsoleto... otra historia es que les guste una API que haga todo por ustedes sin que tengan que saber o pensar...


----------



## Tess16 (May 7, 2016)

Gracias, ya probaré hacerlo... Una duda mas que me surgió..
En el caso de que sean dos ordenadores diferentes conectados... el programa ejecutado tendria que ser el mismo en ambos ordenadores, verdad? o debe diferir en algo?


----------



## TRILO-BYTE (May 7, 2016)

asi es 

digamos que escribes el mismo programa para que corra en la otra computadora.

o hacer lo mas facil que todo perezoso en programacion hace:

1.-usar un puerto serie virtual , haci abrimos 2 veces el programa dentro de la computadora y vemos si funciona o no

2.- hacer uso de puerto serie virtual. correr nuestro programa 
*¿que pasa si nuestro programa no funciona , como lo pruebo?*
facil usamos una terminal puede ser PUTTY o hiperterminal , yo recomiendo PUTTY
en el putty envio texto y mi programa debe recibir texto , envio texto y en mi programa debo recibir texto
tan simple como eso.



otra cosa que se me olvidaba mencionar.

yo tube problemas al enviar y recibir una cadena en C++ asi que lo que hacia era enviar caracter a caracter ejemplo.

digamos que:

 HANDLE *h*; /* handler, sera el descriptor del puerto */

mi descritor lo llame h en el codigo que pusistessss lo tienes como : *hPort*

ahi no hay problema.

hacemos una rutina que busque el puerto y verificar si existe si no existe mensaje de error , clasico.

ahora enviaremos *1* caracter 


> char tecla;
> char caracter;
> 
> while(tecla!='N')
> ...



como se puede apreciar en el humilde codigo hasta que no pisemos N mayuscula pero lo estoy atorando con un getche, es decir si yo quito el getche y pulo un poco mas el codigo

puedo escribir hasta que pise digamos ESC ó ENTER

lo puse asi para que puedas ver como medio funciona el codigo

si estoy mal que el Dr Zoidber que corrija


----------



## Tess16 (May 7, 2016)

Gracias! tengo el hyperterminal asi que probaré con ese..
Muchas graciasssss!!!! ya lo pruebo 

Tengo otra pregunta ... tengo este codigo para configurar el puerto serie pero no me compila... me da el error que dice "expected unqualified-id before "if" " alguna idea de porque?
Lo he comparado con el codigo anterior que tiene bools pero no se si será eso lo que hace que el error salte


```
HANDLE h
       DCB dcb; 
       DWORD dwEventMask; 
       h=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); 
 
       if(h == INVALID_HANDLE_VALUE) {
       /* ocurrio un error al intentar abrir el puerto */
       }
 
       if(!GetCommState(h, &dcb)) {
        /* error: no se puede obtener la configuracion */
        }

        dcb.BaudRate = 9600;
        dcb.ByteSize = 8;
        dcb.Parity = NOPARITY;
        dcb.StopBits = ONESTOPBIT;
        dcb.fBinary = TRUE;
        dcb.fParity = TRUE;
 

        if(!SetCommState(h, &dcb)) {
        /* Error al configurar el puerto */
        }


        COMMTIMEOUTS timeouts;

        timeouts.ReadIntervalTimeout = 50;
        timeouts.ReadTotalTimeoutMultiplier = 1;
        timeouts.ReadTotalTimeoutConstant = 1;
        timeouts.WriteTotalTimeoutMultiplier = 1;
        timeouts.WriteTotalTimeoutConstant = 1;
        if(!SetCommTimeouts(h, &timeouts))
              printf("Error al intentar abrir el puerto.");
```


----------



## Dr. Zoidberg (May 7, 2016)

Tess16 dijo:


> Gracias, ya probaré hacerlo... Una duda mas que me surgió..
> En el caso de que sean dos ordenadores diferentes conectados... el programa ejecutado tendria que ser el mismo en ambos ordenadores, verdad? o debe diferir en algo?


Te dije que partas el programa que te dieron de ejemplo en dos nuevos programas: uno que transmita y otro que reciba. De esa forma podes probar cada uno por separado en la misma PC, y luego ejecutas cada uno de ellos en una computadora diferente y verificas que lo que una envia la otra lo recibe.

Claro, esto exige estudiar el codigo del ejemplo y las funciones de la API de Windows para entender que parte va en cada programa, pero eso ya es parte del estudio que vos debes hacer.


----------



## cosmefulanito04 (May 7, 2016)

En el TurboC en windows me acuerdo que te podías "apropiar" del puerto y de su rutina de interrupción, ahora con un GCC de por medio creo que eso ya no se puede hacer.

De todas formas, no está bien hacer eso de "apropiarse" de algo sin pasar primero por el SO. En linux tenés las funciones open (según el device), read y write que te permite trabajar con cualquier cosa, esa es la magia de linux, pensar todo como si fuera un archivo.


----------



## TRILO-BYTE (May 7, 2016)

bueno yo casi tampoco me acuerdo yo una vez llegue a enviar texto y recibir texto, como un chat.
y luego tenia problemas asi que decidi por enviar caracter a caracter.

bueno te paso un codigo que me funciono, por que la verdad ya tienen tanto que no me acuerdo al 75%

mira lo use para el control de una jeringa mecanica hace años:

```
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <conio>
#include <dir.h>
#include <fstream>
#include <stdlib.h>
#include <math.h>
#include <windows.h>
#include <stdlib.h>



int main (void)
{
 HANDLE h; /* handler, sera el descriptor del puerto */
 DCB dcb; /*  aqui se meten los parametros del puerto */

 DWORD dwEventMask,nil; /* mascara de eventos */
 COMMTIMEOUTS timeouts;

 char COM[5]="COM1";
 int COMnum=0;
 int estado=0;


 while(estado!=1) //estado del puerto
 {
 //configuracion del puerto serie
 h=CreateFile(COM,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);


	if(h == INVALID_HANDLE_VALUE)
   	{
		/* ocurrio un error al intentar abrir el puerto */

      COMnum++;
      COM[3]=49+COMnum;

      if(COMnum>=15)
      	{
         	cout<<"no hay puerto serie!!"<<endl;
            getch();
      		exit(0);
      	}
      estado=0;
		}
      	else
         	{
               estado=1;
            }

 }//while()
 cout<<"el puerto encontrado fue: "<<COM<<endl;






    /* obtenemos la configuracion actual */
	if(!GetCommState(h, &dcb))
   	{
		/* error: no se puede obtener la configuracion */
      cout<<"Error al configurar el puerto "<<endl;
      getch();
		}

    /* Configuramos el puerto */
	dcb.BaudRate = 9600;
	dcb.ByteSize = 8;
	dcb.Parity = NOPARITY;
	dcb.StopBits = ONESTOPBIT;
	dcb.fBinary = TRUE;
	dcb.fParity = TRUE;

	/* Establecemos la nueva configuracion */
	if(!SetCommState(h, &dcb))
   	{
		cout<<"Error al configurar el puerto "<<endl;
      getch();
		}

   timeouts.ReadIntervalTimeout = 1;
	timeouts.ReadTotalTimeoutMultiplier = 0;
	timeouts.ReadTotalTimeoutConstant = 0;

	SetCommTimeouts(h, &timeouts);



   char caracter; //--------------------------------------------------------------------------es el caracter a usar
   int velocidad;
   char tecla;


   while(tecla!='N')
   	{
         caracter='2';
   		WriteFile(h, &caracter, 1, &nil, NULL);

         cout<<"delay en ms"<<endl;
         cin>>velocidad;
   		WriteFile(h, &velocidad, 1, &nil, NULL);

      	WaitCommEvent(h, &dwEventMask, NULL);
    		ReadFile(h, &caracter, 1, &nil, NULL);
         cout<<endl<<"llego ECO:"<<caracter<<endl;

         cout<<"ajustando!!"<<endl;

         caracter='1';
   		WriteFile(h, &caracter, 1, &nil, NULL);

         cout<<"delay en ms"<<endl;
         cin>>velocidad;
   		WriteFile(h, &velocidad, 1, &nil, NULL);

         WaitCommEvent(h, &dwEventMask, NULL);
    		ReadFile(h, &caracter, 1, &nil, NULL);
         cout<<endl<<"llego ECO:"<<caracter<<endl;


         cout<<"repetir otra vez? S/N"<<endl;
         tecla=getche();
         tecla = toupper(tecla);

         clrscr();


      }

}
```

quiero que lo revises, quites lo que no te sirve , compilalo y ve que errores te saca.

NOTA:

esta escrito en Borland C5 hay que hacer ligeritas ligeritas modificaciones para el DEV C++


----------



## Tess16 (May 7, 2016)

Gracias TRILO-BYTE me has sido de mucha ayuda!  Creo que he hecho algun progreso con el codigo que me has dado teniendolo como otra guia.

Dr. Zoidberg perdon, no habia entendido lo que me habias querido decir. Gracias tambien por la ayuda.


----------

