Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Como podéis ver aquí los datos llegan y además correctamente, pero a veces se desalinean:
No veo la necesidad de poner correctores de bits. Además no consigo mejorarlo nada poniendo timeouts distintos al puerto serie.
Este es el codigo C++ que he usado para la recepción:
#include <windows.h>
#include <stdio.h>
#include <time.h>
#define TIEMPO 40 //segundos
#define IMPRIME 1
int main()
{
HANDLE
hCom1=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,0),
hCom2=CreateFile("COM6",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,0);
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 1;
timeouts.ReadTotalTimeoutMultiplier = 1;
timeouts.ReadTotalTimeoutConstant = 2; //250ms Windows!!!!!!!
timeouts.WriteTotalTimeoutMultiplier = 1;
timeouts.WriteTotalTimeoutConstant = 1;
if (!SetCommTimeouts(hCom1, &timeouts)) { printf("nError timeout puerto-1 con error: %d", GetLastError());getchar();getchar(); return-1;}
if (!SetCommTimeouts(hCom2, &timeouts)) { printf("nError timeout puerto-2 con error: %d", GetLastError());getchar();getchar(); return-1;}
SetupComm(hCom1,4048,4048);
SetupComm(hCom2,4048,4048);
DCB dcb;
ZeroMemory(&dcb,sizeof(dcb));
dcb.DCBlength=sizeof(dcb);
dcb.BaudRate = CBR_38400; // baud rate
dcb.ByteSize = 8; // data size, xmit and rcv
dcb.Parity = NOPARITY; // parity bit
dcb.StopBits = ONESTOPBIT; // stop bit
if (SetCommState(hCom1,&dcb)) printf("nAbierto puerto-1");
else { printf ("nFalla SetCommState en puerto-1 con error: %d", GetLastError());getchar();getchar(); return-1;}
if (SetCommState(hCom2,&dcb)) printf("nAbierto puerto-2");
else { printf ("nFalla SetCommState en puerto-2 con error: %d", GetLastError());getchar();getchar(); return-1;}
DWORD res;
unsigned char dato2[4048];
long paquetes,bytes,bitsfail;
long i,j;
for (i=0;i<5;i++)
{
long ini=clock();
long fin=ini+(long) (CLOCKS_PER_SEC*TIEMPO),tiempo=0;
printf("nEsperar %li segundos",TIEMPO);
paquetes=bytes=bitsfail=0;
while (tiempo<fin)
{
tiempo=clock();
ReadFile( hCom2,dato2,11,&res,NULL);
bytes+=res;
if (bytes>=5)
{
paquetes+= bytes / 5;bitsfail+= bytes % 5;bytes=0;
}
if ((res>0)&&IMPRIME)//>0
{
printf("n");
for (j=0;j<res;j++) printf("%02X ", dato2[j]);
}
}
printf("nRecibidos %li paquetes",paquetes);
printf("nTiempo de llegada= %lg ms",(1.0*CLOCKS_PER_SEC*TIEMPO/paquetes));
printf("nRecibidos %li bits mal",bitsfail);
}
CloseHandle(hCom1);
CloseHandle(hCom2);
printf("n===FIN===");
getchar();
getchar();
return 0;
}
¿Como puedo evitar el error del desalineamiento?
saludos
Sólo una pregunta, e igual es un poco tonta.
Con el hyperterminal/putty y demás, también lo recibes mal? Porque entiendo que lo que está mal es el programa en C no? ❓ ❓
Generalmente eso es problema de windows que no es en tiempo real... se te cuela algún proceso por medio y te retrasa la recepción haciendole creer que es otro paquete.
Solución, haz paquetes del tipo: SOH | LEN | DATA
Donde:
- SOH Byte o Bytes que marcan el inicio del paquete
- LEN te dará la longitud total del paquete
- DATA datos...
Así no recibes por tiempo sino por datos enviados (timeout por si algún paquete llega cortado).
S2
Ranganok Schahzaman
El problema lo tenía con labview y por eso he hecho un programa en C++ que es el que me ha dicho cual es el problema.
Ya uso cabecera y no tengo que poner longitud pues siempre trasmito 5 bytes (el último es el CRC). El problema es que si uno de los datos es igual a la cabecera se puede confundir con ésta, lo cual "he arreglado" de una manera un poco chapucera y es que como los datos que trasmito son analógicos sumo o resto un bit para no coincidir con la cabecera. Lo mismo hago con el CRC: sumo o resto un bit al dato analógico y así cambia el CRC.
Me ayudaría saber si además del ReadFile() y WriteFile() C++ tiene alguna función para que me diga cuantos bytes hay en el buffer antes de leerlos.
Lo lees así, porque el buffer lo rediriges a un fichero.
Échale un ojo a:
http://www.codeproject.com/Articles/3061/Creating-a-Serial-communication-on-Win32 " onclick="window.open(this.href);return false;
Ya que ahí usa y explica tu código, pero utiliza diferentes parámetros.
Sino, mira http://forums.codeguru.com/showthread.php?442634-Serial-port-program-in-c-language " onclick="window.open(this.href);return false;
que ahí también ponen varios ejemplos y son todos muy parecidos a lo que tú haces, igual comparando consigues alguna idea.
Sea como fuera, para qué quieres el programa en C++? Quiero decir, ¿Qué tiene que hacer? Me imagino que no sólo mostrar los datos por pantalla no? 😀