PDA

Ver la Versión Completa : Pasar de QBASIC A DELPHI


zugazua2001
12-07-2006, 14:22:19
Hola amigos del foro, tengo que levantar la informacion que provee la balanza en mi computadora.
El codigo esta en qbasic. Les agradeceria si me pudieran dar una mano.

PROCESADOR DIGITAL DE PESO BC5400
TRANSMISION DE DATOS A COMPUTADORA

1 Cableado y especificaciones de transmisión:
Norma RS 232C
7 ---------------------- 5 GND Código ASCII
K3 2 ---------------------- 2 RxD COM Velocidad 9.600 baudios
3 ---------------------- 7 RTS (DB 9) Formato 1 start bit
7 data bits
BC 5400 Computadora 2 stop bits
(El cable se provee junto al indicador) Paridad impar

2 Transmisión a pedido:
La llave 1 de S1 debe ajustarse a la posición ON.
El mensaje transmitido será el siguiente:

LF , CR
"BRUTO xxxxxx kg" (xxxxxx : Peso indicado en el display del BC 5400)
LF , CR
"TARA 000000 kg"
LF , CR
"NETO xxxxxx kg"
LF , CR

Rutina de recepción de datos en lenguaje QBASIC:
OPEN "COM1:9600,O,7,2,CS,DS,CD" FOR INPUT AS #1
nn = 0
b$ = ""
cantidad = 0
inicio:
IF EOF(1) THEN GOTO Espera
A$ = INPUT$(1, 1)
b$ = b$ + A$
IF ASC(A$) = 13 THEN nn = nn + 1
IF nn < 4 THEN GOTO inicio
CLOSE 1
PRINT MID$(b$, 9, 6)
END
Espera:
cantidad = cantidad + 1
FOR esp = 1 TO 30000
IF EOF(1) = 0 THEN GOTO inicio
NEXT esp
IF cantidad = 3 THEN CLOSE 1: PRINT "0": END
GOTO inicio

NOTA: La instrucción OPEN "COM..., provoca que la línea RTS cambie de nivel lógico. Esto actúa como pedido de transmisión al cabezal, que enviará la información antes detallada.
Al finalizar la rutina, la instrucción CLOSE provoca que la línea RTS retorne a su nivel inicial.

ACLARACION: En procesadores con número de serie inferior al 82746000 la llave 1 de S1 se encuentra anulada, no interesando la posición en que se encuentra.

3 Transmisión continua:
La llave 1 de S1 debe ajustarse a la posición OFF

En esta condición el equipo transmite en forma permanente el valor del peso, más un caracter de control:

BOT, X , xxxxxx, CR
(02) (peso) (13)

X = Z Si el peso es cero
X = M Si el peso esta en movimiento
X = N Si el peso es negativo
X = P Si el peso es positivo y estable

Rutina de recepción de datos en lenguaje QBASIC:

OPEN "COM1:9600,O,7,2,CS,DS,CD" FOR INPUT AS #1
b$ = ""
inicio:
A$ = INPUT$(1, #1)
IF A$ <> CHR$(02) THEN GOTO inicio
lee:
A$ = INPUT$(1, #1)
IF A$ = CHR$(13) THEN GOTO final
b$ = b$ + A$
GOTO lee
final:
PRINT b$
CLOSE
END

El punto decimal es transmitido solamente si está presente en el display y en la posición que corresponda.

Desde ya muchisimas gracias.

luisgutierrezb
12-07-2006, 15:42:36
La forma facil, baja un componente para el manejo del puerto serial si buscas en los hilos encontraras varios.

la forma dificil...
este es un pedazo de codigo para una impresora serial, si cambias los "Writes" por "Reads" y algun detallito no creo que tengas problemas para hacer funcionar el codigo ya que creo que lo que es dificil son las rutinas para el puerto.


procedure TPrincipal.HacerTicketVenta;
Var
DescTemp, CantTemp, ImporteTemp, TotalTemp, PagoTemp, CambioTemp:String;
H:HFile;
X:Cardinal;
Str: String;
Buf: Array[1..100] Of char;
DCB: _DCB;
Error, I: Integer;
Begin
SetLastError(0);
Repeat
H := CreateFile(pchar(Puerto),GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
If H = INVALID_HANDLE_VALUE Then
Begin
ShowMessage(SysErrorMessage(GetLastError));
Exit;
End;
DCB.DCBlength := Sizeof(DCB);
GetCommState(H,DCB);
DCB.BaudRate := CBR_9600;
DCB.ByteSize := 8;
DCB.Parity := NOPARITY;
DCB.StopBits := ONESTOPBIT;
SetCommState(H,DCB);

Str := #10;
StrpCopy(@Buf,Str);
WriteFile(H,buf,Length(Str),x,nil);

cualquier funcion que tengas duda, la puedes encontrar en el win32 Programmer's Reference que viene en MS SDK Files de tu instalacion de delphi

zugazua2001
12-07-2006, 17:05:18
Muchisimas gracias por la molestia.
La forma facil, baja un componente para el manejo del puerto serial si buscas en los hilos encontraras varios.

la forma dificil...
este es un pedazo de codigo para una impresora serial, si cambias los "Writes" por "Reads" y algun detallito no creo que tengas problemas para hacer funcionar el codigo ya que creo que lo que es dificil son las rutinas para el puerto.


Código Delphi [-] (http://www.clubdelphi.com/foros/#)
procedure TPrincipal.HacerTicketVenta;
Var
DescTemp, CantTemp, ImporteTemp, TotalTemp, PagoTemp, CambioTemp:String;
H:HFile;
X:Cardinal;
Str: String;
Buf: Array[1..100] Of char;
DCB: _DCB;
Error, I: Integer;
Begin
SetLastError(0);
Repeat
H := CreateFile(pchar(Puerto),GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
If H = INVALID_HANDLE_VALUE Then
Begin
ShowMessage(SysErrorMessage(GetLastError));
Exit;
End;
DCB.DCBlength := Sizeof(DCB);
GetCommState(H,DCB);
DCB.BaudRate := CBR_9600;
DCB.ByteSize := 8;
DCB.Parity := NOPARITY;
DCB.StopBits := ONESTOPBIT;
SetCommState(H,DCB);

Str := #10;
StrpCopy(@Buf,Str);
WriteFile(H,buf,Length(Str),x,nil);




cualquier funcion que tengas duda, la puedes encontrar en el win32 Programmer's Reference que viene en MS SDK Files de tu instalacion de delphi

zugazua2001
16-07-2006, 23:31:36
Hola amigos del foro estoy muy complicado porque tengo que entregar un modulo de una balanza para el miercoles y tengo que levantar la informacion del puerto serial de una balanza rs232 son los conectores. Me pasaron un codigo pero no me funciono me podrian ayudar a pasar el codigo de QBasic.
El sistema operativo que yo utilizo es XP.

Muchisimas gracias por su ayuda.

seoane
17-07-2006, 00:56:34
Puestos a escoger me quedo con el método de transmisión continua. Aquí te queda el código, no esta muy optimizado, pero dada la urgencia que tienes puede servirte para salir del apuro. Comprueba que los parámetros del puerto serie (velocidad, bits de parada, etc) son correctos, si no estas seguro, lo mejor, es utilizar el hypertermial del propio windows, ahí podrás probar diferentes configuraciones del puerto hasta conseguir la correcta.


function Peso(Puerto: String): String;
var
hPort: THandle;
DCB: TDCB;
Leidos: Cardinal;
C: char;
begin
Result:= '';
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);
// Aqui esta la rutina para leer
C:= #0;
// Esperamos el caracter de inicio
repeat
ReadFile(hPort,C,1,Leidos,nil);
until C = #02;
// Leemos el peso
repeat
ReadFile(hPort,C,1,Leidos,nil);
if C <> #13 then
Result:= Result + C;
until C = #13;
// aqui termina
end;
end;
CloseHandle(hPort);
end;
end;

// Un ejemplo de como usar la funcion
ShowMessage(Peso('COM2'));


Pruebalo, sino funciona prueba distintos parámetros con el hyperterminal, y si aun así no funciona a lo mejor tenemos que jugar con los valores del Pin RTS, pero primero vamos a probar así.

seoane
17-07-2006, 01:36:08
Fijándome mejor en los parámetros que utiliza el código de ejemplo, puede que la configuración del puerto que estamos buscando sea la siguiente:


with DCB do
begin
BaudRate := CBR_9600;
ByteSize := 7;
Parity := ODDPARITY;
StopBits := TWOSTOPBITS;
Flags := $03;
end;

zugazua2001
17-07-2006, 12:34:54
Muchas gracias amigo hoy voy a probarlo.

Fijándome mejor en los parámetros que utiliza el código de ejemplo, puede que la configuración del puerto que estamos buscando sea la siguiente:


Código Delphi [-] (http://www.clubdelphi.com/foros/#)
with DCB do
begin
BaudRate := CBR_9600;
ByteSize := 7;
Parity := ODDPARITY;
StopBits := TWOSTOPBITS;
Flags := $03;
end;

zugazua2001
18-07-2006, 00:42:03
Hola amigos del foro, he pasado el codigo este ultimo a mi aplicacion.
Probe con el hiperterminal y me va tirando los pesos perfecto, cuando ejecuto mi aplicacion se queda en la sentencia siguiente, en el ReadFile(hport,....), es mas no intenta seguir leyendo mas caracteres.

repeat
ReadFile(hPort,C,1,Leidos,nil);
until C = #02;

por favor si me pueden ayudar se los agradeceria, la configuracion que anda perfecta en el hiperterminal es:

velocidad:9600
bits: 7
paridad: impar
bits de parada: 2


Gracias por todo nuevamente. Otra cosa yo utilizo el windows XP puede ser por eso que no me funciona?

seoane
18-07-2006, 00:58:00
Vamos por partes. El programa se queda parado en la instrucción ReadFile, o te refieres a que no sale del bucle. Si se queda parado en el ReadFile es que no le esta llegando nada, y si no sale del bucle es que no le manda le carácter #02 como se indicaba en la instrucciones, prueba eliminando ese bucle haber que pasa.

Si por el contrario se queda parado en el ReadFile es que no esta llegando la información al puerto serie, puede ser debido a muchas cosas, pero algo de lo que pone las instrucciones


NOTA: La instrucción OPEN "COM..., provoca que la línea RTS cambie de nivel lógico. Esto actúa como pedido de transmisión al cabezal, que enviará la información antes detallada.


me hace pensar que hay que jugar con el valor de RTS para que todo funcione. Así que activemos la linea RTS y veamos que pasa:


...

if SetCommState(hPort, DCB) then
begin
PurgeComm(hPort, PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or
PURGE_RXCLEAR);
// Aqui esta la rutina para leer
C:= #0;
// Activamos la linea RTS
EscapeCommFunction(hPort,SETRTS);
// Esperamos el caracter de inicio
repeat
ReadFile(hPort,C,1,Leidos,nil);
until C = #02;
// Leemos el peso
repeat
ReadFile(hPort,C,1,Leidos,nil);
if C <> #13 then
Result:= Result + C;
until C = #13;
// aqui termina
end;

...



Tambien seria interesante, ya que dices que con el hyperterminal va bien, que tipo de control de flujo estas usando. Es el unico parametro que me falta por saber.

zugazua2001
18-07-2006, 04:37:24
En efecto se queda colgada en la sentencia ReadFile(...)

Muchisimas gracias por molestarte nuevamente y mañana voy hasta la balanza y lo pruebo.

zugazua2001
18-07-2006, 04:47:57
Te paso la configuracion del hiperterminal que me funciona bien:

configuracion del puerto:

bits x seg: 9600
Bits de datos: 7
Paridad: impar
Bits de parada: 2
Control de flujo: hardware

Gracias nuevamente.

zugazua2001
18-07-2006, 19:33:47
Hola amigo estoy muy complicado, se queda igualmente en el readfile().

No se que cambiar. Gracias nuevamente.

seoane
18-07-2006, 20:09:37
Lo único que se me ocurre es que también tenga que estar activada la linea DTR además de RTS. Vamos a cambiar los Flags de tal modo que estas se activen al abrir el puerto y permanezcan activas. Echo este cambio no abría ninguna diferencia entre lo que estamos haciendo nosotros y lo que hace el hyperterminal.


function Peso(Puerto: String): String;
var
hPort: THandle;
DCB: TDCB;
Leidos: Cardinal;
C: char;
begin
Result:= '';
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 := 7;
Parity := ODDPARITY;
StopBits := TWOSTOPBITS;
// Aqui es donde indicamos que active RTS y DTR
Flags := $1013;
// Si no funciona prueba tambien con este otro valor
// Flags := $1011;
end;
if SetCommState(hPort, DCB) then
begin
PurgeComm(hPort, PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or
PURGE_RXCLEAR);
// Aqui esta la rutina para leer
C:= #0;
// Esperamos el caracter de inicio
repeat
ReadFile(hPort,C,1,Leidos,nil);
until C = #02;
// Leemos el peso
repeat
ReadFile(hPort,C,1,Leidos,nil);
if C <> #13 then
Result:= Result + C;
until C = #13;
// aqui termina
end;
end;
CloseHandle(hPort);
end;
end;


Esperemos que haya suerte de esta vez, ya me quede sin ideas

zugazua2001
20-07-2006, 00:15:49
el unico problema es que en algunos momentos me lo deja de capturar.
Vuelvo a correr el hiperterminal y me lo vuelve a capturar.

Muchisimas gracias, por haberme dedicado tanto tiempo. Estoy muy agradecido.