[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Serial Port Communication

Posted on 2005-04-17
17
Medium Priority
?
809 Views
Last Modified: 2013-11-20
Hello,

I am building a program that is going to communicate with an actuator controller via "command strings" over the 9 pin serial port. I am using the CreateFile, ReadFile, and WriteFile functions. Here are the specifications of the controller

Electrical Specifications      EIA RS485
Synchronization Method      Asynchronous
Connection Method      Differential Line
Connector      6 pole modular
Strings Fromat      ASCII
Baud Rate      38.4kbps (Standard).  9.6kbps, 19.2kbps (Can be set as a factory default)
Data length      Eight bits
Stop bit      One bit
Parity check      None
Communication Method      Half-Duplex

Here is my implementation so far:

CString  m_sComPort;
      m_sComPort = "Com1";

      m_hCom = CreateFile (m_sComPort, // Port Name (Unicode compatible)
                                                GENERIC_READ | GENERIC_WRITE, // Open for Read-Write
                                                0, // COM port cannot be shared
                                                NULL, // Always NULL for Windows CE
                                                OPEN_EXISTING, // For communication resource
                                                0, // Non-overlapped operation only
                                                NULL); // Always NULL for Windows CE
      COMMTIMEOUTS ct;
      ct.ReadIntervalTimeout = 100;
      ct.ReadTotalTimeoutMultiplier = 10;
      ct.ReadTotalTimeoutConstant = 10;
      ct.WriteTotalTimeoutMultiplier = 10;
      ct.WriteTotalTimeoutConstant = 1000;
      if(!SetCommTimeouts(m_hCom, &ct))
      {
            MessageBox(NULL,(_T("Setting comm. timeouts.")), (_T("Error")), MB_OK);
            DWORD tmp = GetLastError();
            return false;
      }
      
      DCB dcb;
      dcb.DCBlength = sizeof(DCB);
      if(!GetCommState(m_hCom, &dcb))
      {
            MessageBox(NULL,(_T("Getting Comms. State.")), (_T("Error")), MB_OK);
            return false;
      }
      dcb.BaudRate = 9600; // set baud rate to what we want
      dcb.fOutxCtsFlow = TRUE;
      dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
      dcb.fDtrControl = DTR_CONTROL_ENABLE;
      dcb.fOutxDsrFlow = FALSE;
      dcb.fOutX = FALSE; // no XON/XOFF control
      dcb.fInX = FALSE;
      dcb.ByteSize = 8;
      dcb.Parity = NOPARITY;
      dcb.StopBits = ONESTOPBIT;

      if(!SetCommState(m_hCom, &dcb))
      {
            MessageBox(NULL,(_T("Setting Comms. State.")), (_T("Error")), MB_OK);
            return false;
      }
      return true;

My other functions are just the ReadFile and WriteFile using the 16 character commands.
example -> WriteFile(m_hCom, "02BaFFFF167A000603",16,&iBytesWritten,NULL);

Breakdown of Example According to Controller Manual:
STX                        02                             Start Transmission Character
Axis No.                   B                               (HEX) Axis 11(decimal)
Command                a                               Character for command
Position Data            FFFF167A                  Position in HEX as converted by algorithm
Zero's                     00                              String Filler (string must contain 16 characters)
BCC                        06                              Block Check Calculation - Value of String (HEX)
ETX                        03                              End Transmission Character

Nothing happens when I run this code, and in the debug window I notice that the BytesWritten data remains at '0', indicating to me that nothing is being written to the controller.

I have also tried using the ActiveX Controller "Microsoft Communications" and have had equal bad luck. I would prefer using the ReadFile and WriteFile functions though. But a solution is a solution.

-Cheers
0
Comment
Question by:galneweinhaw
17 Comments
 
LVL 3

Expert Comment

by:jeremyeadamich
ID: 13803641
Hello,

I notice in your comments here that you state Windows CE...

m_hCom = CreateFile (m_sComPort, // Port Name (Unicode compatible)
                                        GENERIC_READ | GENERIC_WRITE, // Open for Read-Write
                                        0, // COM port cannot be shared
                                        NULL, // Always NULL for Windows CE
                                        OPEN_EXISTING, // For communication resource
                                        0, // Non-overlapped operation only
                                        NULL); // Always NULL for Windows CE

Is this a CE project or a Win32 project?

IF it is a CE project are you running your code on the emulator or on a device?

Jeremy
0
 
LVL 86

Expert Comment

by:jkr
ID: 13806440
>>Nothing happens when I run this code, and in the debug window I notice that the BytesWritten data remains at '0'

Check if 'WriteFile()' returns 'FALSE' and evaluate 'GetLastError()' in this case.
0
 

Author Comment

by:galneweinhaw
ID: 13809600
When I call GetLastError(),

it returns a 6
which means there is an INVALID HANDLE,

More to this, when I try to shut down the program, there is a first chance exception talking about an Invalid handle
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 86

Expert Comment

by:jkr
ID: 13809645
So, have you verified that your handle is valid? E.g.

m_hCom = CreateFile (...);

if (!m_hCom) {

  dwError = GetLastError();
}

What port name are you using with 'CreateFile()'?
0
 
LVL 86

Expert Comment

by:jkr
ID: 13809719
BTW, according to the docs, there's a suble little difference for CE, such as the name has to be 'COM1:' instead of 'COM1' - NOTE the trailing colon:

http://msdn.microsoft.com/library/en-us/fileio/fs/createfile.asp states "The CreateFile function can create a handle to a communications resource, such as the serial port COM1"

http://msdn.microsoft.com/library/en-us/wceobjst/html/cerefCreateFile.asp says "When lpFileName points to a COM port to open, you must include a colon after the name. For example, specify COM1: to open that port. When using IrCOMM, specify COM3:. "

0
 

Author Comment

by:galneweinhaw
ID: 13810237
Okay just to clarify, I am working on with Visual Studios 6.0, on an Windows XP computer. I pulled that code from a website (they are not my comments) sorry for the miscommunication.

I have fixed (at least for testing purposes) the invalid handle. It know does not create any errors, but still the string format does not seem to be valid, for the controller still does nothing
0
 
LVL 86

Expert Comment

by:jkr
ID: 13810319
Are you sure about the DCB settings? I'd suggest to

     DCB dcb;
    dcb.DCBlength = sizeof(DCB);
    if(!GetCommState(m_hCom, &dcb))
    {
         MessageBox(NULL,(_T("Getting Comms. State.")), (_T("Error")), MB_OK);
         return false;
    }

    // set that according to your specs
    BuildCommDCB("baud=9600 parity=N data=8 stop=1", &dcb);

     if(!SetCommState(m_hCom, &dcb))
    {
         MessageBox(NULL,(_T("Setting Comms. State.")), (_T("Error")), MB_OK);
         return false;
    }

Apart from that, according to your specs, you'll need to set ETX at the end of the string, e.g.

"02BaFFFF167A000006X\003"

The '\003' is the escape sequnce for ETX, the 'X' represents the BCC value that *you* have to calculate.
    return true;
0
 

Author Comment

by:galneweinhaw
ID: 13810520
Could it possibly be that I'm setting the incorrect amount of memory (currently 16 bytes) in the WriteFile function? I tried the above and there is no progress.

Could it be an improper format? Should I send you the "serial protocol manual."
0
 
LVL 86

Expert Comment

by:jkr
ID: 13810539
>>Could it be an improper format?

That's what I tried to point out - according to the table you posted above, the last char has to be 0x03 (and not the character '3') which I corrected above. But, I don't know how to calculate the BCC byte...
0
 

Author Comment

by:galneweinhaw
ID: 13810790
Here is information provided in the manual regarding the BCC byte, let me know if any more info will be of use

BCC:      
Two characters ’00-FF’ showing hexadecimal number digits for block check characters. It is calculated by using the 12 data characters (excluding STX, ETX and BCC).  It’s calculated by taking last 2 characters of the one's complement of the sum of the ASCII codes of those 12 characters.

Example of calculating BCC

[STX]1a1234567800[BCC][ETX]

First, add all ASCII codes for the 12 data characters:
      sum = 31H+61H+31H+32H+33H+34H+35H+36H+37H+38H+30H+30H = 296H
Second, take the last 2 characters of the 1’s complement:
       [BCC] = "6A"
0
 
LVL 1

Expert Comment

by:s_satheesh
ID: 13813274
Hello,

   Insted of Read/Write to file.... directly send data to com port....
http://sourceforge.net/projects/comport/  (this is in pascal.....)

Rgds
0
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 13815293
OK, that makes it a little clearer - so, to calculate the BCC value, you could

void CalcBCC ( char* pBuf) {

short nSum = 0;
short nCompl;
char acBCC[5];
for ( int i = 1; i < 13; ++i) { // start at '1', since '0' is 'STX'

nSum += (short) pBuf[i];
}

nCompl = ~nSum;
sprintf(acBCC, "4.4hd",nCompl);

memcpy((void*)&pBuf[13], acBCC[2], 2);
}

In your case, the string should be set up like


char acCmd[] = "\002BaFFFF167A0006X\003";

WriteFile(m_hCom, acCmd,16,&iBytesWritten,NULL);
0
 

Author Comment

by:galneweinhaw
ID: 13819938
Thank you for the help on the BCC bit, I haven't gotten there yet because I still can't communicate with the controller. But thank you for the assistance.

I don't know if it means anything, but the manual seems to want the command strings in hexadecimal ASCII values. And when I look at the
char acCmd[] = "\002BaFFFF167A0006X\003" value in Debug mode. It does not seem to match up, for instance

the manual says '0' should have a value of '30', whereas the actual value for '0' in the program is '48'

could this be a problem
0
 
LVL 86

Expert Comment

by:jkr
ID: 13825110
>>the manual says '0' should have a value of '30'

Um which '0' are you referring to?
0
 

Author Comment

by:galneweinhaw
ID: 13827475
0 (Zero the number)
0
 
LVL 86

Expert Comment

by:jkr
ID: 13828369
Ah, now I got you - that's OK, '48' is the ASCII code for '0'. BTW, have to correct myself, the command string should be

"\002BaFFFF167A0006\003"
0
 

Author Comment

by:galneweinhaw
ID: 13828994
Its over, the actuator is going back to the company, after grinding the tech support for 3 days, I got talking to their communications "expert" and they told me I would be crazy to program it in VC++ 6.0, saying that it would take over a 1000 lines of code (don't ask why, cause he didn't know). Apparently it is easier to program it in VB, but I would still have to know the "handshake procedure," which they were unsure of. After downloading a trail version of a com spy and turning on their software, there was a ton going on that was way out of the scope of the documentation they gave me.

Thus, this horse is dead, and there is no sense flogging it. If they are not going to tell me the command procedure then its all for nothing.

jkr, thanks for sticking with this train wreck, all points and props go to you........
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
this video summaries big data hadoop online training demo (http://onlineitguru.com/big-data-hadoop-online-training-placement.html) , and covers basics in big data hadoop .
Suggested Courses
Course of the Month19 days, 12 hours left to enroll

873 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question