Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   API de Windows (https://www.clubdelphi.com/foros/forumdisplay.php?f=7)
-   -   Escribir datos en el puerto serial en windows XP (https://www.clubdelphi.com/foros/showthread.php?t=33495)

bill_mg 07-07-2006 23:57:36

Escribir datos en el puerto serial en windows XP
 
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:
Código Delphi [-]
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:
Código Delphi [-]
  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

cambiar la configuracion del flags
 
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:

Código Delphi [-]
  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

no lee el dato
 
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.


La franja horaria es GMT +2. Ahora son las 00:49:01.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi