PDA

Ver la Versión Completa : Escribir datos en el puerto serial en windows XP


bill_mg
07-07-2006, 23:57:36
Buenas tardes, como puedo escribir un dato en el puerto serial de XP utilizando delphi 6.0, tengo un circuito electrónico que se conecta al puerto serial de la computadora y al recibir el número "1" como dato de entrada genera un pulso de corriente electrica para abrir una puerta.

seoane
08-07-2006, 00:25:56
Si solo quieres mandar un byte puede que esta funcion te resulte util:

function MandarByte(Puerto: String; B: Byte): Boolean;
var
hPort: THandle;
DCB: TDCB;
Escritos: Cardinal;
begin
Result:= FALSE;
Puerto:= Uppercase(Puerto);
// Cambiar esto si es necesario un puerto diferente
if (Puerto<>'COM1') and (Puerto<>'COM2') then
exit;
hPort:= CreateFile(PChar('\\.\'+Puerto), GENERIC_READ or GENERIC_WRITE,0, nil,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if hPort<>INVALID_HANDLE_VALUE then
begin
DCB.DCBlength:= sizeof(DCB);
if GetCommState(hPort,DCB) then
begin
// Cambiar esto para una configuracion del puerto diferente
with DCB do
begin
BaudRate := CBR_9600;
ByteSize := 8;
Parity := NOPARITY;
StopBits := ONESTOPBIT;
Flags := $01;
end;
if SetCommState(hPort, DCB) then
begin
PurgeComm(hPort, PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or
PURGE_RXCLEAR);
Result := WriteFile(hPort, B, 1, Escritos, nil);
end;
end;
CloseHandle(hPort);
end;
end;


Para usarla, por ejemplo, para mandar un 1:

MandarByte('COM1',1);


Como sugerencia: Puedes usar los pines DTR y RTS para mandar señales sin necesidad de un circuito muy complicado, pero si ya tienes el circuito montado, da lo mismo.

dec
08-07-2006, 02:56:40
Hola,

Seoane, disculpa que me meta en el código de la función que has escrito: no soy yo quién, pero, en fin. Me llamó la atención que la variable "Escritos" no se inicializa en ningún momento. Lo mismo da exactamente igual, pero, como me llamó la atención... ahí queda dicho, por si acaso. :)

seoane
08-07-2006, 13:29:42
La variable "Escritos" se pasa por referencia a la funcion, es la propia funcion la que le asigna un valor. No hay necesidad de inicializarla.

dec
08-07-2006, 13:32:07
Hola,

Bueno, es lo que yo decía, ¿no? :D :D :D

bill_mg
08-07-2006, 17:53:53
Amigo antetodo muchas gracias por la fuente, el codigo compila sin errores pero el circuito no recibe el dato.

Realicé pruebas en hyperterminal fijando la configuración del puerto en 9600 Bits por seg, 8 Bits de datos, paridad: ninguna, 1 Bits de parada y en control de flujo: ninguno, y funciona...

Ahora voy a la configuración de la fuente que enviaste que es la siguiente:
BaudRate := CBR_9600;
ByteSize := 8;
Parity := NOPARITY;
StopBits := ONESTOPBIT;
Flags := $01; Aqui en el Flags, es donde debo especificar la opcion NINGUNO, ya probe con $00, $02, $03 y nada. CUAL SERA EL PARAMETRO???

Ahhhh, me cambiaron el parametro 1 por A es decir, tu me enviaste la función MandarByte('COM1',1); pero debo cambiarla a MandarByte('COM1','A'); te lo comento por si tiene algo que ver, y porsupueto cambien el BYTE por STRING en el parametro B

seoane
08-07-2006, 18:32:09
Para mandar el carácter 'A' (ASCII 65) no hace falta que cambies nada en la función, dejándola tal cual estaba antes utiliza esto:


MandarByte('COM1',Ord('A'));


Si cambias el tipo de parámetro de Byte por un string y dejas el resto de la función igual, no estas mandando un 'A' si no otra cosa. Mejor utiliza el método que te explico arriba.

bill_mg
09-07-2006, 04:16:25
El código corre y no genera error pero no manda el dato. Para que sirve la variable Escritos, el valor de esta en la linea donde aparece
Result := WriteFile(hPort, B, 1, Escritos, nil); es un poco de numeros algo así como 1489274260 porque crees que no manda el dato. Pruebo el circuito con hyperterminal y funciona bien. Que puede estar pasando?

seoane
09-07-2006, 05:13:19
Supongo que como te aconseje mas arriba volviste a dejar el código de la función como estaba, y utilizas la función Ord para convertir un carácter en un Byte. Si no es así corrígeme. Si estas haciendo esto, no se porque no te funciona, solo puedo adivinar.

Comprueba lo siguiente:
- No es lo mismo una 'A' que una 'a'
- Que el circuito no necesite de alguna señal en los pines DTR y RTS
- Comprueba que otro programa no esta usando el puerto serie
- Comprueba que el puerto es el correcto
- Comprueba los parámetros del puerto serie

En cuanto a la variable "Escritos" no le deis mas vueltas, solo la incluyo porque es necesaria para llamar a la función pero su valor antes de llamar a la función no es importante, en cambio su valor después de la función no indica el numero de bytes que realmente se han escrito. Tienes que pensar que esta misma función se utiliza para escribir en muchos lugares (ficheros, discos, pipes, sockets, etc) y en algunos tiene sentido que no se puedan escribir todos los bytes que se quiera, en esos caso la variable nos devuelve el numero de bytes que han sido escritos realmente. En este caso no tiene mucho sentido, solo mando escribir un byte y el puerto serie no tiene porque rehusar mandarlo así que tampoco compruebo su valor después de llamar a la función WriteFile, es una variable inútil en este caso.