leer datos de comunicacion serial (BYTE) de indicador de peso y convertir a int

Iniciado por pedromigl010, 29 Junio 2016, 05:54 AM

0 Miembros y 3 Visitantes están viendo este tema.

MAFUS

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.

pedromigl010

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
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°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: o si el byte es 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

MAFUS

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.

AlbertoBSD

Para depurar un poco tu salida cambia:

putchar(byte);

por

printf("%.2x",byte);

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

Saludos
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

pedromigl010

Bien mafus entonces tu recomendación es que también haga las pruebas con algo asi?:
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 [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?.

AlbertoBSD

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!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

MAFUS

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.

pedromigl010

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:

[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?

AlbertoBSD

Hola posiblemente en algun momento el if no se cumple y simplemente sale

if (!bRes)
{
//Agrega otro alert aqui.
break;
}


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

Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

pedromigl010

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.