Controller Card responding to VB but not C++

Thread Starter

viknesh316

Joined Dec 27, 2010
6
I am controlling the movements of a servo motor via a Controller Card called Servo X8P. I have programmed a GUI in C++ but the servo motor responds not accordingly. But it gets the right command in VB.
The commands are being sent in hexadecimal codes.

Do cards respond differently to different programming language.
Suggestions would be welcomed..

Thanks in advance
 

thatoneguy

Joined Feb 19, 2009
6,359
No, the programming language shouldn't matter, as long as the code essentially does the same thing. e.g. They both compile and result in an .EXE file that calls .DLLs (in M$ Windows based OS)

The one issue may be in the code you can't see, e.g. DLL Libraries. VB may implement a function one way, while VC implements the same function in a different fashion.

Most likely though, it is some glitch/oversight/missing module in the ported code. Triple check it.

More info about the app, source code, number of lines of source code, number of source files, and the output would help narrow it down a bit, other than "different compiler, now 'it' doesn't work".
 

Thread Starter

viknesh316

Joined Dec 27, 2010
6
No, the programming language shouldn't matter, as long as the code essentially does the same thing. e.g. They both compile and result in an .EXE file that calls .DLLs (in M$ Windows based OS)

The one issue may be in the code you can't see, e.g. DLL Libraries. VB may implement a function one way, while VC implements the same function in a different fashion.

Most likely though, it is some glitch/oversight/missing module in the ported code. Triple check it.

More info about the app, source code, number of lines of source code, number of source files, and the output would help narrow it down a bit, other than "different compiler, now 'it' doesn't work".
thank you for the reply,

the problem can be summarised so,
when sent a hexadecimal code to the controller card with C++, the card receives it as a totally different code. This was detected when the value was looped back.

For example, if 0x01 is sent, the card interprets it as 0x04 or so on.
This problem however does not happend in VB.

When contacted, the card supplier was also stunned and confused.
 

thatoneguy

Joined Feb 19, 2009
6,359
When sending the hex digit, are you sending it as 4 ascii characters "0","x",'0","4", or as the hex byte 0x04? Reason I ask is sending the raw hex may be interpreted as a command to the RS232 port to pause/break/etc.

Do you have another serial device, such as a FTDI card to put a logic analyzer on or failing that, a PIC or Arduino to read what the computer is actually sending out?

The way it sounds, when a byte is sent, something is sent over the serial port, so the program "sort of works". Now it is a matter of getting the format of what is being sent correct, as well as verifying the port speeds, etc.

--ETA: Use Hyperterminal or similar terminal program to "talk to" serial port. to send 0xA, hold down ALT and type 010 on the numeric keypad.

You could run a serial null modem cable to a second computer running hyperterminal to see what is being sent as well.
 
Last edited:

Thread Starter

viknesh316

Joined Dec 27, 2010
6
When sending the hex digit, are you sending it as 4 ascii characters "0","x",'0","4", or as the hex byte 0x04? Reason I ask is sending the raw hex may be interpreted as a command to the RS232 port to pause/break/etc.

Do you have another serial device, such as a FTDI card to put a logic analyzer on or failing that, a PIC or Arduino to read what the computer is actually sending out?

The way it sounds, when a byte is sent, something is sent over the serial port, so the program "sort of works". Now it is a matter of getting the format of what is being sent correct, as well as verifying the port speeds, etc.

--ETA: Use Hyperterminal or similar terminal program to "talk to" serial port. to send 0xA, hold down ALT and type 010 on the numeric keypad.

You could run a serial null modem cable to a second computer running hyperterminal to see what is being sent as well.
this is how the hexa codes are being sent :

char strTx [] = {0x01,0x22,0x00,0x0B,0x00,0x64,0x00,0x00,0x03,0xE8,0xFF,0xFF,0xFE,0xFF,0xFF,0x06,0x77};
if(SetOutput(strTx, 0)){
AfxMessageBox("Clockwise rotation!!");
}

else{
AfxMessageBox("No rotation!!");
}

i have tried few variations in sendind the codes..
a) 0x22
b) just 22
c) converting to binary
d)without the comma (,)

but i always hit a dead wall..

if u guys can gimme ur email addresses, i dont mind sending the 4 page spec sheet pdf that the supplier provided me.

thank you
 

spinnaker

Joined Oct 29, 2009
7,830
this is how the hexa codes are being sent :

char strTx [] = {0x01,0x22,0x00,0x0B,0x00,0x64,0x00,0x00,0x03,0xE8,0xFF,0xFF,0xFE,0xFF,0xFF,0x06,0x77};
if(SetOutput(strTx, 0)){
AfxMessageBox("Clockwise rotation!!");
}

else{
AfxMessageBox("No rotation!!");
}

i have tried few variations in sendind the codes..
a) 0x22
b) just 22
c) converting to binary
d)without the comma (,)

but i always hit a dead wall..

if u guys can gimme ur email addresses, i dont mind sending the 4 page spec sheet pdf that the supplier provided me.

thank you
Where is the code for SetOutput(strTx, 0))?

I do not think that is a V++ function?

Please put a code block around your code.
 

Thread Starter

viknesh316

Joined Dec 27, 2010
6
Where is the code for SetOutput(strTx, 0))?

I do not think that is a V++ function?

Please put a code block around your code.
#include "stdafx.h"
#include "CommCtrl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
HANDLE hCOM1= (HANDLE) -1;
HANDLE hCOM2= (HANDLE) -1;
HANDLE *hComDevice;

bool SetPortOpen(int portx, DWORD dwBaudrate)
{
char szPort[ 15 ] ;
DCB dcb ;

if(portx == 0) hComDevice = &hCOM1; else hComDevice = &hCOM2;
if( *hComDevice != (HANDLE) -1) return true; // port is still open

wsprintf( szPort, "%s%d", "COM", portx+1 ) ;

if ((*hComDevice = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, // open COMM device
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL |
NULL, // no overlapped I/O
NULL )) == (HANDLE) -1 ) return ( FALSE ) ;

SetupComm(*hComDevice , 4096, 4096 ) ; // setup device buffers
PurgeComm(*hComDevice, PURGE_TXABORT | PURGE_RXABORT |PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
// purge any information in the buffer
dcb.DCBlength = sizeof( DCB );
GetCommState(*hComDevice, &dcb ) ; // read com properties to dcb
dcb.BaudRate = dwBaudrate; // set baudrate
dcb.ByteSize = 8; // set 8 Bit
dcb.Parity = 0; // no parity
dcb.fParity = 0; // no parity check enable
dcb.StopBits = ONESTOPBIT; // 1 Stop Bit
dcb.fBinary = TRUE; // binary
SetCommState(*hComDevice, &dcb );
return TRUE; // set COM with dcb
} // end of SetPortOpen()


BOOL SetOutput(CString strTx ,int portx)
{
BOOL fWriteStat ;
DWORD dwBytesWritten ;

if(portx == 0) hComDevice = &hCOM1; else hComDevice = &hCOM2;
if( *hComDevice == (HANDLE) -1) return(-1);

fWriteStat = WriteFile(*hComDevice, strTx,(DWORD)strTx.GetLength(),&dwBytesWritten, NULL) ;
return(fWriteStat);
}

//---------------------------------------------------------------------------
// Closes the connection to the port.
//---------------------------------------------------------------------------
BOOL CloseConnection(int portx )
{
if(portx == 0) hComDevice = &hCOM1; else hComDevice = &hCOM2;
if( *hComDevice == (HANDLE) -1) return(-1);

EscapeCommFunction(*hComDevice, CLRDTR ) ;

// purge any outstanding reads/writes and close device handle
PurgeComm(*hComDevice, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
CloseHandle(*hComDevice) ;
*hComDevice = (HANDLE) -1;
return ( TRUE ) ;
}

//---------------------------------------------------------------------------
// Reads a block from the COM port and stuffs it into the provided buffer.
//---------------------------------------------------------------------------
int ReadRs232Input(unsigned char *ptrx, int portx)
{
BOOL fReadStat ;
COMSTAT ComStat ;
DWORD dwErrorFlags;
DWORD dwLength = 0;

if(portx == 0) hComDevice = &hCOM1; else hComDevice = &hCOM2;
if( *hComDevice == (HANDLE) -1) return(-1);

// only try to read number of bytes in queue
ClearCommError( *hComDevice, &dwErrorFlags, &ComStat ) ;
dwLength = min(4096, ComStat.cbInQue ) ;

if (dwLength > 0) fReadStat = ReadFile( *hComDevice,ptrx,dwLength, &dwLength, NULL ) ;

// if (dwLength > 0) { abIn[dwLength]=NULL; *ptrx = (unsigned char*) &abIn;}

return ( dwLength ) ;
} // end of ReadCommBlock()


the above is from a file commctrl
 

thatoneguy

Joined Feb 19, 2009
6,359
When posting code, click the # in the editor to wrap your code in a scrollbox, so it fits easier.

Can you post the Working VB code tx/rx functions?
 

spinnaker

Joined Oct 29, 2009
7,830
I see a couple of problems. First you are passing the CString object to Writefile and you should be passing it's character buffer array. But you should not be using CString at all. You have nulls (0) in your array. The null character marks the end of a string in C so your string ends at the first zero and not where you think.

I would use an array of unsigned chars .


Rich (BB code):
char strTx [] = {0x01,0x22,0x00,0x0B,0x00,0x64,0x00,0x00,0x03,0xE8  ,0xFF,0xFF,0xFE,0xFF,0xFF,0x06,0x77};

BOOL SetOutput(unsigned char  *tx, DWORD len, int portx)
{
BOOL fWriteStat ;
DWORD dwBytesWritten ;

if(portx == 0) hComDevice = &hCOM1; else hComDevice = &hCOM2;
if( *hComDevice == (HANDLE) -1) return(-1);

fWriteStat = WriteFile(*hComDevice, tx,len,&dwBytesWritten, NULL) ;
return(fWriteStat);
}
The problem is you are going to need to know the length of the array being passed. There are classes to avoid this but outside the scope of this post and probably not worth the trouble.


Likewise on your ReadInput function, if you are expecting zeros, do not use a CString. You will have the same problem with a premature end of string.
 
Top