Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: pedromigl010 en 29 Junio 2016, 05:54 am



Título: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: pedromigl010 en 29 Junio 2016, 05:54 am
Buenas soy nuevo en el foro.

Mi problema es el siguiente estoy intentando leer los datos que recibo de un indicador digital de peso vía serial a mi pc. Los datos son interpretados por el dato tipo BYTE. El codigo que estoy utilizando es uno que encontre en la web es el siguiente:
 
Código
  1. #ifndef serie_h
  2. #define serie_h
  3.  
  4. #include <windows.h>
  5.  
  6. // Open Serial port
  7. HANDLE OpenSerialPort( char *psPort, // "COM1","COM2"
  8. DWORD bBaudRate, // CBR_9600, CBR_19200. CBR_56000
  9. BYTE bByteSize, // 7,8
  10. BYTE bParity, // NOPARITY, EVENPARITY, ODDPARITY
  11. BYTE bStopBits, // ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS
  12. DWORD ReadTimeout   // Programmable Read Timeout
  13. );
  14.  
  15. // Send a byte
  16. BOOL SerialSendByte(HANDLE hPort, BYTE byte);
  17. // return TRUE: Send OK
  18.  
  19. // Receive a byte
  20. BOOL SerialReceiveByte(HANDLE hPort, BYTE *pbyte, BOOL *pTimeout);
  21. // return TRUE & *pTimeout TRUE Send OK
  22. // return TRUE & *pTimeout FALSE Timeout
  23. // return FALSE Receive Error
  24.  
  25. // Close Serial Port
  26. BOOL CloseSerialPort(HANDLE hPort);
  27.  
  28. // Write&Read strings from serial port using standard file I/O functions
  29.  
  30. /*BOOL ReadFile(
  31.     HANDLE hFile, // handle of file or serial port to read
  32.     LPVOID lpBuffer, // address of buffer that receives data  
  33.     DWORD nNumberOfBytesToRead, // number of bytes to read
  34.     LPDWORD lpNumberOfBytesRead, // address of number of bytes read
  35.     LPOVERLAPPED lpOverlapped // NULL  
  36.    );
  37. */
  38.  
  39. /*
  40. BOOL WriteFile(
  41.  
  42.     HANDLE hFile, // handle to file or serial port to write to
  43.     LPCVOID lpBuffer, // pointer to data to write to file
  44.     DWORD nNumberOfBytesToWrite, // number of bytes to write
  45.     LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
  46.     LPOVERLAPPED lpOverlapped // NULL
  47.    );
  48. */
  49.  
  50. #endif
  51.  
  52. ///Archivo cpp
  53. #include "serie.h"
  54.  
  55. HANDLE OpenSerialPort( char *psPort, // "COM1","COM2"
  56. DWORD dwBaudRate, // CBR_9600, CBR_19200. CBR_56000
  57. BYTE bByteSize, // 7,8
  58. BYTE bParity, // NOPARITY, EVENPARITY, ODDPARITY
  59. BYTE bStopBits, // ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS
  60. DWORD Timeout       // Timeout
  61. ) {
  62.  
  63. HANDLE hPort; // port handler
  64. DCB dcbPort; // Port configuration
  65. COMMTIMEOUTS commTimeouts; // Port Timeouts
  66. DWORD dwError; // Error code
  67.  
  68. // Open Serial Port
  69. hPort=CreateFile(
  70. psPort, // pointer to name of the file
  71. GENERIC_READ | GENERIC_WRITE, // access (read-write) mode
  72. 0, // share mode: 0 the object cannot be share
  73. NULL, // pointer to security attributes: NULL the handle cannot be inherited
  74. OPEN_EXISTING, // how to create: Comx exist
  75. 0, // file/port attributes
  76. NULL); // handle to file/port with attributes to copy  
  77.  
  78. // If the function fails, the return value
  79. //is INVALID_HANDLE_VALUE
  80. if ( hPort == INVALID_HANDLE_VALUE ) {
  81. dwError = GetLastError (); // Flush error code
  82. return hPort;
  83. }
  84.  
  85. // Set Port Configuration
  86.  
  87. // Delete DCB configuration
  88. FillMemory(&dcbPort, sizeof(dcbPort), 0);
  89. dcbPort.DCBlength = sizeof(dcbPort);
  90.  
  91. // Current DCB in use for the communications port
  92. GetCommState (hPort, &dcbPort);
  93.  
  94. // Update DCB with new parameters
  95. dcbPort.BaudRate = dwBaudRate;        
  96. dcbPort.ByteSize = bByteSize;                
  97. dcbPort.Parity = bParity;            
  98. dcbPort.StopBits = bStopBits;        
  99.  
  100. // Fixed parameters (Disable XON-XOFF and modem handshake)
  101. dcbPort.fBinary = TRUE;               // Binary mode; no EOF check
  102. dcbPort.fParity = TRUE;               // Enable parity checking
  103. dcbPort.fOutxCtsFlow = FALSE;         // No CTS output flow control
  104. dcbPort.fOutxDsrFlow = FALSE;         // No DSR output flow control
  105. dcbPort.fDtrControl = DTR_CONTROL_ENABLE;
  106. // DTR flow control type
  107. // Raises the DTR line when the device is opened
  108. dcbPort.fDsrSensitivity = FALSE;       // DSR sensitivity
  109. dcbPort.fTXContinueOnXoff = TRUE;     // XOFF continues Tx
  110. dcbPort.fOutX = FALSE;                 // No XON/XOFF out flow control
  111. dcbPort.fInX = FALSE;                 // No XON/XOFF in flow control
  112. dcbPort.fErrorChar = FALSE;           // Disable error replacement
  113. dcbPort.fNull = FALSE;                 // Disable null stripping
  114. dcbPort.fRtsControl = RTS_CONTROL_ENABLE;
  115. // RTS flow control
  116. // Raises the RTS line when the device is opened
  117. dcbPort.fAbortOnError = FALSE;         // Do not abort reads/writes on
  118. // error
  119. // Set new configuration
  120. if (!SetCommState (hPort, &dcbPort)) {
  121. dwError = GetLastError (); // Flush error code
  122. CloseSerialPort(hPort);
  123. hPort = INVALID_HANDLE_VALUE;
  124. return hPort;
  125. }
  126.  
  127. // Set Port Timeouts
  128. // Timeouts preparation  MORE INFORMATION IN WIN32 API: COMMTIMEOUTS
  129. commTimeouts.ReadIntervalTimeout = 0;   // Specifies the maximum time, in milliseconds, allowed to elapse between the arrival
  130. // of two characters on the communications line
  131. // A value of zero indicates that interval time-outs are not used.
  132. commTimeouts.ReadTotalTimeoutMultiplier = 50;   // Specifies the multiplier, in milliseconds, used to calculate
  133. // the total time-out period for read operations.
  134. // For each read operation, this value is multiplied
  135. // by the requested number of bytes to be read.
  136. commTimeouts.ReadTotalTimeoutConstant = Timeout;// Specifies the constant, in milliseconds, used to calculate the total
  137. // time-out period for read operations
  138. //
  139. commTimeouts.WriteTotalTimeoutMultiplier = 10;  // Specifies the multiplier, in milliseconds, used to calculate the
  140. // total time-out period for write operations.
  141. // For each write operation, this value is multiplied
  142. // by the number of bytes to be written.
  143. commTimeouts.WriteTotalTimeoutConstant = 1000;  // Specifies the constant, in milliseconds, used to calculate the total time-out period
  144. // for write operations
  145. // See de win32 api for more information
  146. // Set Timeouts
  147. if (!SetCommTimeouts (hPort, &commTimeouts)) {
  148. dwError = GetLastError (); // Flush error code
  149. CloseSerialPort(hPort);
  150. hPort = INVALID_HANDLE_VALUE;
  151. return hPort;
  152. }
  153. return hPort;
  154. }
  155.  
  156. BOOL SerialSendByte(HANDLE hPort, BYTE byte){
  157. BOOL bRes;
  158. DWORD dwError, dwNumBytesWritten=0;
  159.  
  160. bRes=WriteFile(
  161. hPort, // handle to file or serial port to write to
  162. &byte, // pointer to data to write to file
  163. 1, // number of bytes to write
  164. &dwNumBytesWritten, // pointer to number of bytes written
  165. NULL // NULL
  166. );
  167.  
  168.  
  169. if ((!bRes)||(dwNumBytesWritten!=1)){
  170. dwError = GetLastError (); // Flush error code
  171. }
  172. return bRes;
  173. }
  174.  
  175. BOOL SerialReceiveByte(HANDLE hPort, BYTE *pbyte, BOOL *pTimeout){
  176. BOOL bRes;
  177. DWORD dwError, lpNumberOfBytesRead=0;
  178.  
  179. *pTimeout=FALSE;
  180. bRes=ReadFile( hPort, // handle of file or serial port to read
  181. pbyte, // address of buffer that receives data  
  182. 1, // number of bytes to read
  183. &lpNumberOfBytesRead, // address of number of bytes read
  184. NULL // NULL  
  185. );
  186.  
  187. if (!bRes) {
  188. dwError = GetLastError (); // Flush error code
  189. }
  190. if ((bRes)&&(lpNumberOfBytesRead==0)){
  191. *pTimeout = TRUE;
  192. }
  193. return bRes;
  194. }
  195.  
  196. BOOL CloseSerialPort(HANDLE hPort){
  197. BOOL bRes;
  198. DWORD dwError;
  199.  
  200. bRes=CloseHandle(hPort);
  201. if (!bRes) {
  202. dwError = GetLastError (); // Flush error code
  203. }
  204. return bRes;
  205. }
  206. ///////////////////////////////////////////////////////////////////////////////////////////////////
  207.  
  208. #include "serie.h"
  209. #include "windows.h"
  210. #include "stdio.h"
  211. #include <stdint.h>
  212.  
  213. int main(){
  214. HANDLE hPort;
  215. BOOL bRes;
  216. BYTE byte;
  217. BOOL timeout;
  218.  
  219. hPort=OpenSerialPort("COM1",CBR_9600,8,NOPARITY,TWOSTOPBITS,5000);
  220.  
  221. if (hPort==INVALID_HANDLE_VALUE){
  222. printf("Error abriendo puerto com1");
  223. return 1;
  224. }
  225.  
  226. while(1){
  227. bRes=SerialReceiveByte(hPort,&byte,&timeout);
  228. if (!bRes) {
  229. break;
  230. }
  231.  
  232. if (timeout){
  233. printf("\n--->timeout\n");
  234. }
  235.  
  236. else
  237. {
  238.        putchar(byte);
  239. }
  240.  
  241. }
  242.  
  243. if (!bRes) {
  244. printf("Error leyendo de puerto com1");
  245. return 1;
  246. }
  247.  
  248. CloseSerialPort(hPort);
  249. return 0;

bien lo que obtengo de salida  en la pantalla de la pc es lo siguiente:C°xxCx° Cx°Cx xxx° xCx x°xC C C C C C C C°xxCx° y este patron se repite constantemente. En este caso esos valores simbolizan el numero 0 que muestra el indicador digital de peso quisiera saber como puedo convertir esos valores del tipo BYTE al valor 0 Kg que muestra el indicador digital de peso pero en la pc.

Gracias de antemano por la ayuda


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: AlbertoBSD en 29 Junio 2016, 06:09 am
Hola que marca es tu indicador digital? ¿Bascula?

La cadena

Código:
C°xxCx° Cx°Cx xxx° xCx x°xC C C C C C C C°xxCx°
No indica nada sobre la salida real.
Cuando las x salen, ¿Mueves el dispositivo?

la instruccion que esta imprimiendo eso es:

Código
  1. putchar(byte);

El cual solo imprime un caracter de lo leído en el puerto serie... significa que la cadena que leiste es lo que mando la maquina.

Tal vez la marca nos indique el formato de  la cadwna leída

Saludos



Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: pedromigl010 en 29 Junio 2016, 14:33 pm
Si bueno la marca del indicador digital de peso es: virtual measurement & control mod. VC 210.

Te cuento que ese patrón de caracteres
Código:
C°xxCx° Cx°Cx xxx° xCx x°xC C C C C C C C°xxCx°
es el que se repite constantemente cuando la bascula esta indicando el valor 0 kg absolutamente todos esos codigos, sin mover nada simplemente la bascula de mantiene en 0, porque lo digo, porque cuando cambia el valor por ejemplo 200 kg se representan otros símbolos que no poseo en este momento. Cuando vuelve a 0 kg vuelve a indicar el valor
Código:
C°xxCx° Cx°Cx xxx° xCx x°xC C C C C C C C°xxCx°
completo es un patron que se repite constantemente claro siempre y cuando este en 0 kg cuando cambia a otro peso cambian los codigos.
Espero que me puedan ayudar lo otro que estoy pensando es si en el codigo que estoy utilizando los parámetros de la función main son los indicados si la sincronizacion es de 9600 o en el valor de paridad esta bien, la verdad es que no se realmente. Espero que puedan ayudarme a interpretar estos codigos a valores en Kg saludos amigo


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: AlbertoBSD en 29 Junio 2016, 14:53 pm
Hola.

Tienes que encontrar  el manual, lo busque y es una pesadilla, Paginas donde te tienes que registrar y paginas diversas dondw tiens que bajar alguna app solo para el j0did0 PDF.

Baja el manual de ese modelo y tal ve ahi venga algo sobre el formato.

Saludos


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: pedromigl010 en 29 Junio 2016, 15:49 pm
AlbertoBSD no es necesario descargar el manual con el nombre de la marca, tengo el codigo de la placa base del indicador digital de pes es de la serie LP7510E, de todas formas el link para descargar el manual esta aca: http://www.awtscale.com/attachments/89-LP7510_indicator_manual.pdf (http://www.awtscale.com/attachments/89-LP7510_indicator_manual.pdf) te agradezco por la ayuda ofrecida


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: pedromigl010 en 29 Junio 2016, 16:16 pm
disculpa que te envié este otro link sobre el manual es casi igual al anterior solo que este me parece que algunas cosas en la sección de comunicación presenta mejor la información http://www.vestildocs.com/manuals/scale-s_1209.pdf (http://www.vestildocs.com/manuals/scale-s_1209.pdf) saludos


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: AlbertoBSD en 29 Junio 2016, 16:16 pm
En la pagina 24 de ese link que pusiste (El primero) esta el formarto que buscas, se requiere  capturar varios valores para despues ajustarlo al formato descrito en ese documento.


Dame unos minutos y te publico un codigo para procesar la salida.

por cierto u a pregunta el patron que pones, te lo pone uno por linea?

Saludos!!


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: pedromigl010 en 29 Junio 2016, 18:26 pm
AlbertoBSD ¿como puedo adjuntar por acá una imagen? que tome a la pantalla para que puedas observar bien el patrón.


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: pedromigl010 en 29 Junio 2016, 18:58 pm
y el patrón que te indique se repite aproximadamente dos veces por linea, digo aproximado porque no llega a completarse el segundo patrón en la linea. Lo que si observo es que el patrón esta compuesto de la siguiente forma:

C°xxCx°     Cx°Cx      xxx°     xCx      x°xC     C    C    C    C    C   C

Yo logro distinguir que este patrón esta compuesto de 6 a 11 valores lo cual no estoy seguro, porque digo esto, por como los caracteres están mostrados y luego viene la separación por los espacios:

C°xxCx°     Cx°Cx      xxx°     xCx      x°xC     C    C    C    C    C   C
    1                2            3          4          5                        6

y la otra forma seria:

C°xxCx°     Cx°Cx      xxx°     xCx      x°xC     C    C    C    C    C   C
    1                2            3          4          5         6    7     8    9    10  11

¿si existe la posibilidad de mostrar la imagen por este medio? si es asi mejor.

Y de verdad muchas gracias!!! si puedes publicar el código para procesar la salida del valor del indicador, de verdad me ha costado interpretar esos valores que me arroja el código,  no sabes cuanto te lo agradecería!

Saludos


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: pedromigl010 en 30 Junio 2016, 21:51 pm
Los últimos 6 valores, es decir las 6 C que aparecen, en la pantalla:
Código:
C°xxCx°     Cx°Cx   xxx°   xCx      x°xC     C    C    C    C    C   C
representan el valor del peso de la balanza en 0 Kg. Lo menciono porque cuando el valor incremento a 4400 kg este es el resultado que me arrojo:
Código:
C°xxCx°     Cx°Cx      xxx°     xCx      x°xC     C    C   C   °C   °CC   °C
variando en las ultimas 3 C. Debo extraer cada uno de esos valores y convertirlos en formato de int o char para mostrarlo en mi programa, habrá alguien que pueda ayudarme con este problema? no se cada cuantos caracteres representan un byte o si cada carácter representa un byte la verdad es que no lo se.
Saludos


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: MAFUS en 30 Junio 2016, 23:01 pm
Estás seguro que la configuración para hablar con la balanza es esa?
A ver si va a resultar que la balanza trabaja con otra configuración en el puerto serie.

Pon marca y modelo, a ver si podemos encontrar información.

Imagínate que no se comunica con texto entendible por humanos, sino que envía enteros en grupos de bytes, o reales, u otro tipo de dato que solo podrás conocer viendo el datasheet.


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: pedromigl010 en 1 Julio 2016, 00:09 am
MAFUS la marca y el modelo los publique en un anterior comentario son: Virtual measurement & control modelo: vc210. Debido a que es complicado tener el manual que ofrece la marca, le mencione a AlbertoBSD que tengo referencia de la placa base de dicha balanza es un modelo que esta estandarizado y es de la serie LP7510. Ese manual si aparece en la web, se puede descargar con estos link:http://www.awtscale.com/attachments/89-LP7510_indicator_manual.pdf  (http://www.awtscale.com/attachments/89-LP7510_indicator_manual.pdf)
http://www.awtscale.com/attachments/89-LP7510_indicator_manual.pdf  (http://www.awtscale.com/attachments/89-LP7510_indicator_manual.pdf)
el primer link AlbertoBSD mencionó que en la pagina 24, sale la explicación de como se recibe la trama de datos. He tratado de analizar la semejanza con lo descrito en la pagina 24 del prime manula con los datos que recibo por ejemplo en 0 kg:
Código:
C°xxCx°    Cx°Cx   xxx°   xCx      x°xC     C    C    C    C    C   C
y como mencione anteriormente los ultimos valores que me muestra, especificamente las 6 C pude observar que son los valores que en el manual especifica que es la data. Ahora lo que no se cuanto representa cada bytes si cada caracter, cada dos caracteres o si inclusive hasta los espacios representen un espacio en el byte.
Por otra parte si el codigo que utilizo lo publique al comienzo de este tema, y es un codigo para recibir byte a byte la data, yo se que lo que recibo esta en formato de byte luego debo traducirlo a un tipo de dato char o int para que el usuario pueda entenderlo, lo primero que requiero saber es que representa un byte en el patron que me muestra la pantalla si:
Código:
o si el byte es
Código:
C°xxCx°
. por ejemplo yo se que las 6 C representan mi valor en peso, lo que no se es si cada C representa un byte o 2 C todas las C hay esta el detalle, luego de saber eso puedo extraer y convertir el caracter a lo que quiero.
saludos


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: MAFUS en 1 Julio 2016, 09:59 am
No recibes bien la cadena, según el manual no deberías recibir eso. No veo la configuración del puerto serie por ningún lado,  eso es un fallo del manual.

Veo que usas dos bits de parada. Cámbialo a 1: suele ser una configuración muy usada.

Por otra parte, si la configuración 8N1 no te funciinara cámbiala a 7N1. Veo en el manual de la comunicación con el sengundo display usa caracteres de 7 bits, pero esa no suele ser usada en comunicación con PCs.

También es común recibir caracteres extraños por no coincidir la velocidad de transmisión en los dos equipos.
Deberás realizar ensayos con diferentes configuraciones hasta obtener una cadena legible.


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: AlbertoBSD en 1 Julio 2016, 11:10 am
Para depurar un poco tu salida cambia:

Código
  1. putchar(byte);

por

Código
  1. printf("%.2x",byte);

Solo para validar que  no estes recibiendo algun otro caracter basura.

Saludos


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: pedromigl010 en 1 Julio 2016, 16:44 pm
Bien mafus entonces tu recomendación es que también haga las pruebas con algo asi?:
Código:
hPort=OpenSerialPort("COM1",{1200, 2400, 4800, 9600},7,NOPARITY,ONESTOPBIT,5000);
, Entonces según el manual ¿como debería recibir la cadena? dame un ejemplo para tener una referencia y saber como voy con las pruebas, disculpen es que soy nuevo en la configuración de estos indicadores.
Ok AlbertoBSD voy hacer lo que me indicas, si coloco
Código:
[code]printf("%.2x",byte);
[/code] pero como puedo evidenciar que estoy recibiendo algún carácter basura, que debo observar en la variedad de los caracteres mostrados?.


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: AlbertoBSD en 1 Julio 2016, 17:01 pm
El codigo que te puse solo muestra el valor en hexadecimal de los caracteres que muestras, agrega la salida en tu respuesta, igualemente como se repite el patron anterior este se repetira, solo que en esta no dara salto de linea.

Saludos!


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: MAFUS en 1 Julio 2016, 18:33 pm
Sigue las instrucciones de LP7510 USER MANUAL pág. 23
C27 -> 1 (continuous sending)
C28 -> 3 (9600)
C29 -> 0 (8 bits por caracter sin paridad)

Configura la aplicación con las misma configuración de puerto serie: 9600 baudios, 8 bits por caracter sin paridad. Empieza con 1 bit de parada.

La cadena que debes leer aparece al final de la página 9 e inicio de la página 10 del mismo manual.


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: pedromigl010 en 2 Julio 2016, 01:19 am
Ok perfecto amigos gracias.

pero ahora me surge otro problema y tiene que ver con lo que estoy haciendo, pero no tanto con este tema, lo mas seguro es que cometa un error al comentarlo en este tema, lo siento pero bueno aquí va.

El código serial que coloque al comienzo como se puede observar se ejecuta en ms dos, pero requiero implementar el mismo para un proyecto con interfaz grafica a lo cual estoy usando wxwidgets especificamente la gui wxformbuilder, pero cuando aplico el código serial en mi ventana se guinda a los 5 segundos, cuando trato de incorporar un string proveniente del codigo serial en un ctrtext. Lo que asumo es que la comunicación del código con ms dos se establece en forma mas directa que por medio de wxwidgets.

El codigo que utilizo es el siguiente:

Código:
[code]#ifndef VPRINCIPAL_H
#define VPRINCIPAL_H

#include <stdint.h>
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <stdint.h>
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <cstring>
#include <ctime>
#include <wx/timer.h>
#include <wx/datetime.h>
#include <wx/menu.h>
#include <wx/wx.h>
#include <wx/app.h>
#include <wx/msgdlg.h>

#include "Ventanas.h"

using namespace std;

class VPrincipal:public VentanaPrincipal{
private:

//void comenzar_tiempo(wxTimerEvent&);
protected:

public:
VPrincipal(wxWindow *parent);
//void OnBotonCerrar(wxEvent &evt);

HANDLE OpenSerialPort( char *psPort, // "COM1","COM2"
DWORD bBaudRate, // CBR_9600, CBR_19200. CBR_56000
BYTE bByteSize, // 7,8
BYTE bParity, // NOPARITY, EVENPARITY, ODDPARITY
BYTE bStopBits, // ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS
DWORD ReadTimeout   // Programmable Read Timeout
);

// Send a byte
BOOL SerialSendByte(HANDLE hPort, BYTE byte);
// return TRUE: Send OK

// Receive a byte
BOOL SerialReceiveByte(HANDLE hPort, BYTE *pbyte, BOOL *pTimeout);
// return TRUE & *pTimeout TRUE Send OK
// return TRUE & *pTimeout FALSE Timeout
// return FALSE Receive Error

// Close Serial Port
BOOL CloseSerialPort(HANDLE hPort);
};

#endif

//////////////////////////////////////////////////////////////////////////////

#include "VPrincipal.h"

VPrincipal::VPrincipal(wxWindow* parent):VentanaPrincipal(parent){


Show();

HANDLE hPort;
BOOL bRes;
BYTE byte;
BOOL timeout;

string muestra="espera";

hPort=serieOpenSerialPort("COM1",CBR_9600,8,NOPARITY,ONESTOPBIT,1000);

if (hPort==INVALID_HANDLE_VALUE)
{
wxMessageBox("Error abriendo puerto com1");
//return 1;
}

while(1){

bRes=SerialReceiveByte(hPort,&byte,&timeout);

if (!bRes)
{
break;
}

if (timeout)
{
m_textCtrl1->Clear();
m_textCtrl1->SetValue("espera");
//i++;
}

else
{
putchar(byte);
}

}


if (!bRes)
{
wxMessageBox("Error leyendo de puerto com1");
//return 1;
}

CloseSerialPort(hPort);

}


HANDLE VPrincipal::OpenSerialPort(char *psPort, // "COM1","COM2"
DWORD dwBaudRate, // CBR_9600, CBR_19200. CBR_56000
BYTE bByteSize, // 7,8
BYTE bParity, // NOPARITY, EVENPARITY, ODDPARITY
BYTE bStopBits, // ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS
DWORD Timeout       // Timeout
) {

HANDLE hPort; // port handler
DCB dcbPort; // Port configuration
COMMTIMEOUTS commTimeouts; // Port Timeouts
DWORD dwError; // Error code

// Open Serial Port
hPort=CreateFile(
psPort, // pointer to name of the file
GENERIC_READ | GENERIC_WRITE, // access (read-write) mode
0, // share mode: 0 the object cannot be share
NULL, // pointer to security attributes: NULL the handle cannot be inherited
OPEN_EXISTING, // how to create: Comx exist
0, // file/port attributes
NULL); // handle to file/port with attributes to copy 

// If the function fails, the return value
//is INVALID_HANDLE_VALUE
if ( hPort == INVALID_HANDLE_VALUE ) {
dwError = GetLastError (); // Flush error code
return hPort;
}

// Set Port Configuration

// Delete DCB configuration
FillMemory(&dcbPort, sizeof(dcbPort), 0);
dcbPort.DCBlength = sizeof(dcbPort);

// Current DCB in use for the communications port
GetCommState (hPort, &dcbPort);

// Update DCB with new parameters
dcbPort.BaudRate = dwBaudRate;         
dcbPort.ByteSize = bByteSize;               
dcbPort.Parity = bParity;           
dcbPort.StopBits = bStopBits;       

// Fixed parameters (Disable XON-XOFF and modem handshake)
dcbPort.fBinary = TRUE;                // Binary mode; no EOF check
dcbPort.fParity = TRUE;                // Enable parity checking
dcbPort.fOutxCtsFlow = FALSE;          // No CTS output flow control
dcbPort.fOutxDsrFlow = FALSE;          // No DSR output flow control
dcbPort.fDtrControl = DTR_CONTROL_ENABLE;
// DTR flow control type
// Raises the DTR line when the device is opened
dcbPort.fDsrSensitivity = FALSE;      // DSR sensitivity
dcbPort.fTXContinueOnXoff = TRUE;      // XOFF continues Tx
dcbPort.fOutX = FALSE;                // No XON/XOFF out flow control
dcbPort.fInX = FALSE;                  // No XON/XOFF in flow control
dcbPort.fErrorChar = FALSE;            // Disable error replacement
dcbPort.fNull = FALSE;                // Disable null stripping
dcbPort.fRtsControl = RTS_CONTROL_ENABLE;
// RTS flow control
// Raises the RTS line when the device is opened
dcbPort.fAbortOnError = FALSE;        // Do not abort reads/writes on
// error
// Set new configuration
if (!SetCommState (hPort, &dcbPort)) {
dwError = GetLastError (); // Flush error code
CloseSerialPort(hPort);
hPort = INVALID_HANDLE_VALUE;
return hPort;
}

// Set Port Timeouts
// Timeouts preparation  MORE INFORMATION IN WIN32 API: COMMTIMEOUTS
commTimeouts.ReadIntervalTimeout = 0;  // Specifies the maximum time, in milliseconds, allowed to elapse between the arrival
// of two characters on the communications line
// A value of zero indicates that interval time-outs are not used.
commTimeouts.ReadTotalTimeoutMultiplier = 50;   // Specifies the multiplier, in milliseconds, used to calculate
// the total time-out period for read operations.
// For each read operation, this value is multiplied
// by the requested number of bytes to be read.
commTimeouts.ReadTotalTimeoutConstant = Timeout;// Specifies the constant, in milliseconds, used to calculate the total
// time-out period for read operations
//
commTimeouts.WriteTotalTimeoutMultiplier = 10;  // Specifies the multiplier, in milliseconds, used to calculate the
// total time-out period for write operations.
// For each write operation, this value is multiplied
// by the number of bytes to be written.
commTimeouts.WriteTotalTimeoutConstant = 1000;  // Specifies the constant, in milliseconds, used to calculate the total time-out period
// for write operations
// See de win32 api for more information
// Set Timeouts
if (!SetCommTimeouts (hPort, &commTimeouts)) {
dwError = GetLastError (); // Flush error code
CloseSerialPort(hPort);
hPort = INVALID_HANDLE_VALUE;
return hPort;
}
return hPort;
}

BOOL VPrincipal::SerialSendByte(HANDLE hPort, BYTE byte){
BOOL bRes;
DWORD dwError, dwNumBytesWritten=0;

bRes=WriteFile(
hPort, // handle to file or serial port to write to
&byte, // pointer to data to write to file
1, // number of bytes to write
&dwNumBytesWritten, // pointer to number of bytes written
NULL // NULL
);


if ((!bRes)||(dwNumBytesWritten!=1)){
dwError = GetLastError (); // Flush error code
}
return bRes;
}

BOOL VPrincipal::SerialReceiveByte(HANDLE hPort, BYTE *pbyte, BOOL *pTimeout){
BOOL bRes;
DWORD dwError, lpNumberOfBytesRead=0;

*pTimeout=FALSE;
bRes=ReadFile( hPort, // handle of file or serial port to read
pbyte, // address of buffer that receives data 
1, // number of bytes to read
&lpNumberOfBytesRead, // address of number of bytes read
NULL // NULL 
);

if (!bRes) {
dwError = GetLastError (); // Flush error code
}
if ((bRes)&&(lpNumberOfBytesRead==0)){
*pTimeout = TRUE;
}
return bRes;
}



BOOL VPrincipal::CloseSerialPort(HANDLE hPort){
BOOL bRes;
DWORD dwError;

bRes=CloseHandle(hPort);
if (!bRes) {
dwError = GetLastError (); // Flush error code
}
return bRes;
}

[/code]

La venta abre sin problema y me muestra por uno segundos el mensaje "espera" pero luego se guinda el programa como comente anteriormente. Como puedo solucionar esto?


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: AlbertoBSD en 2 Julio 2016, 01:36 am
Hola posiblemente en algun momento el if no se cumple y simplemente sale

Código
  1. if (!bRes)
  2. {
  3. //Agrega otro alert aqui.
  4. break;
  5. }

Sobre lo que comentas que la comunicacion es mas directa con msdos y eso, no es cierto y no tiene nada que ver.

Saludos!


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: pedromigl010 en 2 Julio 2016, 03:08 am
Gracias por la respuesta
Como que agregue otro alert? eso si no lo entendi AlbertoBSD, disculpa.
Y si puede ser que si pero si en algun momento no se cumpliera el if en ms dos me debería dar igualmente el mismo problema y no sucede corre perfectamente en ms dos.


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: AlbertoBSD en 2 Julio 2016, 03:43 am
Es que veo que fuera del while tiends un if con un alert en caso de que falle.

Código
  1. if (!bRes)
  2. {
  3. wxMessageBox("Error leyendo de puerto com1");
  4. //return 1;
  5. }

Pero ese alert no lo tienes en el if que está dentro del while.

Y reitero no tiene nada que ver si esta en msdos o en una ventana.

Saludos


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: pedromigl010 en 2 Julio 2016, 13:45 pm
Gracias por el consejo AlbertoBSD, ya hice lo del alert, pero nada no entiendo porque se guinda, me estoy cayendo en algo aparentemente tan tonto.

Saludos


Título: Re: leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int
Publicado por: pedromigl010 en 3 Julio 2016, 17:42 pm
Ya vi el problema que tengo, el mismo se asocia al bucle while(1) que tengo, ya que prácticamente al estar conectado a un puerto serial es infinito, constantemente esta leyendo por eso se guinda. Lo digo porque cuando coloco una condición para el cierre del mismo el programa corre sin ningún problema pero pierdo continuidad en la secuencia de los datos. Como puedo solucionar esto? el problema que corre en ms dos sin ningún problema y en una aplicación con interfaz gráfica se guinda debido al while?