How to simulate RS232 communication

Aug 10, 2016 at 10:12am
Hello,

I want to communicate with a pump using RS232 communictaion. To do this I have this code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
        std::string comport = "COM1";

        HANDLE file;
        COMMTIMEOUTS timeouts;
        DWORD read, written;
        DCB port;

        char init[] = ""; // e.g., "ATZ" to completely reset a modem.

        // Convert std:string to std::wstring
        std::wstring wComport;
        for(unsigned int i = 0; i < comport.length(); ++i)
        {
            wComport += wchar_t( comport[i] );
        }
        // open the comm port.
        file = CreateFileW( wComport.c_str(), //port_name, e.g. COM1
            GENERIC_READ | GENERIC_WRITE,
            0,
            nullptr,
            OPEN_EXISTING,
            0,
            nullptr);

        if ( INVALID_HANDLE_VALUE == file)
        {
            // system_error("opening file");
            return;
        }

        // get the current DCB, and adjust a few bits to our liking.
        memset(&port, 0, sizeof(port));
        port.DCBlength = sizeof(port);
        if ( !GetCommState(file, &port))
        {
            // system_error("getting comm state");
        }
        if (!BuildCommDCB("baud=9600 parity=n data=8 stop=1", &port))
        {
            // system_error("building comm DCB");
        }
        if (!SetCommState(file, &port))
        {
            // system_error("adjusting port settings");
        }
        // set short timeouts on the comm port.
        timeouts.ReadIntervalTimeout = 1;
        timeouts.ReadTotalTimeoutMultiplier = 1;
        timeouts.ReadTotalTimeoutConstant = 1;
        timeouts.WriteTotalTimeoutMultiplier = 1;
        timeouts.WriteTotalTimeoutConstant = 1;
        if (!SetCommTimeouts(file, &timeouts))
        {
            // system_error("setting port time-outs.");
        }

        if (!EscapeCommFunction(file, CLRDTR))
        {
            // system_error("clearing DTR");
        }

        Sleep(200);
        if (!EscapeCommFunction(file, SETDTR))
        {
            // system_error("setting DTR");
        }

        if (!WriteFile(file, init, sizeof(init), &written, NULL))
        {
            // system_error("writing data to port");
        }
        if (written != sizeof(init))
        {
            // system_error("not all data written to port");
        }

        // First get the static data (serial number, model, software versions, etc)
        std::string commandoList[] = {"c", "V", "{", "h"};
        unsigned int asciiCode;
        for (unsigned int index=0; index < (sizeof(commandoList)/sizeof(commandoList[0])) ; index++)
        {       // ask for static information once
            {   // limits the scope of variables
                // send the request to the pump
                std::stringstream sendstream;
                sendstream << (char) 0x02 << "001?" ;                       // start single datablock query command
                sendstream << commandoList[index].c_str() ;                 // specifies the desired parameter
                sendstream << (char) 0x03 ;
                std::string theCommandString = sendstream.str();
                char* theCommand = new char [theCommandString.length()+1];
                strcpy(theCommand, theCommandString.c_str());

                char checkSum = (char) 0xFF;
                for (unsigned int checkSumIndex=0; checkSumIndex < theCommandString.length()+1; checkSumIndex++) // sizeof(theCommand) ; checkSumIndex++)
                {
                    checkSum = checkSum ^ theCommand[checkSumIndex]; // ^ is a bitwise xor operation
                }

                sendstream << checkSum;
                WriteFile(file, sendstream.str().c_str(), strlen(sendstream.str().c_str()), &written, nullptr);
            }
	}


Now I would like to test the software that uses this code even when I am not connected to the pump.

Since I am basically reading and writing to a File-handle, I wonder if it would be possible to create another thread or an external program that would do the opposite with the same file handle and that way simulates the pump?

If this is possible, how could I do this? I guess the first issue would probably be to direct the handle somewhere else like:
1
2
3
4
5
#ifdef __system_is_under_test__
        std::string comport = "pump_communication_test_file.txt";
#else
        std::string comport = "COM1";
#endif 

And then opening the file should not block another thread or application from opening the same file, which it typically would.

Is there anyone with tips, tricks, hints, advice or other ways to accomplish this?

Kind regards, Nico
Aug 10, 2016 at 11:01am
closed account (48bpfSEw)
What do you think about the idea to write your own RS232 driver?
Aug 10, 2016 at 11:05am
I think it is freighting, because I have absolutely no idea how to do something like that.
But if there is some kind of guideline I would like to give it a try.

Kind regards, Nico
Aug 10, 2016 at 12:19pm
closed account (48bpfSEw)
http://stackoverflow.com/questions/1023181/rs-232-serial-snoop-tools-for-protocol-development-debugging


com0com
http://com0com.sourceforge.net/


and this is the development kit for windwos driver from microsoft:
https://msdn.microsoft.com/en-us/library/windows/hardware/ff557573(v=vs.85).aspx



a lot of stuff,
good luck! ^^
Aug 10, 2016 at 12:32pm
Now I would like to test the software that uses this code even when I am not connected to the pump.

If you have two serial ports on the computer you can possibly setup a program that mimics the pump that uses the second serial port. Then write a program that mimics the pump on the second port. Lastly connect the two ports using a null modem cable and start both programs.

Another option might be something like:
http://www.serialporttool.com/CommEcho.htm
Topic archived. No new replies allowed.