Receiving Information from a Serial Port

I am communicating with a device through a serial port. I have successfully sent a message to the device “0xC1, 0xD2, 0x21” which tells the device to wake up, make a measurement, and send the results back. My issue now is receiving the results of the message. The devices manuaul indicates that the response is in the following format “0x02 0x00 (Data Lowbyte) 0x00 (Data Highbyte).”
How do I capture this response information and then convert it into 16 bits?

The following is a segment of my code, top section works, bottom section does not.
//Sending data works so far
static const char data[]={0xC1, 0xD2, 0x21};
int size = strlen(data);
DWORD dwWritten, dwReading;
WriteFile(Resipod,data,size,&dwWritten,NULL);

//Receiving data does not work. Not really sure what I’m doing here
char data2[3];
ReadFile(Resipod,data2,size,&dwReading,NULL);


Thank you for the help!!!
Did you open the COM port with GENERIC_READ access rights? If yes, try to get one byte at a time from the device

1
2
3
4
ReadFile(Resipod,data2[0],1,&dwReading,NULL);
// printf or MessageBox "byte received"
ReadFile(Resipod,data2[0],1,&dwReading,NULL);
// ... 
Last edited on
Thank you, that helped a lot! Now an new issue. I'm not sure what I'm doing with the data that I've received from the Resipod. Here is my code so far;

static const char data[]={0xC1, 0xD2, 0x21};
int size = strlen(data);
DWORD dwWritten, dwReading;
WriteFile(Resipod,data,size,&dwWritten,NULL);

int data2[1];
int data3[1];
int data4[1];

ReadFile(Resipod,data2,1,&dwReading,NULL);
ReadFile(Resipod,data3,1,&dwReading,NULL);
ReadFile(Resipod,data4,1,&dwReading,NULL);

cout << data2;
cout<<"\n";
cout<< data3;
cout<<"\n";
cout<<data4;
cout<<"\n";


here is the following output from each

data2 = 0028F95C
data3 = 0028F950
data4 = 0028F944

I'm not sure how to take this output and make it look like what the owners manual for the devise says.

Below is information from the owners manual;

“0x02 0x00 (Data Lowbyte) 0x00 (Data Highbyte).”
Readout data is 16 bits:
Bit 0..10 0..1999kohm*cm
Bit 11 decimal point (0:1999 kohm*cm, 1:199.9 kohm*cm)
Bit 12 derivated
Bit 13..15 0=OL, 1-5= 10-50 micro-Amps, 6=200 microamps


How do I turn "0028F95C, 0028F950, 0028F944" into this 16 bit information that provides me with the results?

Thank you so much for any help!!
You are printing address of the array instead of the data. What you should do is
1
2
3
4
5
6
cout << data2[0];
cout<<"\n";
cout<< data3[0];
cout<<"\n";
cout<<data4[0];
cout<<"\n";


but you can read everything into a single array:
1
2
3
4
5
6
7
8
9
10
11
12
int data_recv[3];

ReadFile(Resipod,&data_recv[0],1,&dwReading,NULL);
ReadFile(Resipod,&data_recv[1],1,&dwReading,NULL);
ReadFile(Resipod,&data_recv[2],1,&dwReading,NULL);

cout << hex<<(int)data_recv[0];
cout<<"\n";
cout<< (int)data_recv[1];
cout<<"\n";
cout<<(int)data_recv[2];
cout<<"\n";


and I just now noticed that in your first post data is declared as const. That might be reason why you couldn't read data.
Null,

Thank you a ton, this is great help.

The code now looks like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
	static const char data[]={0xC1, 0xD2, 0x21};
	int size = strlen(data);
	DWORD dwWritten, dwReading;

	WriteFile(Resipod,data,size,&dwWritten,NULL);

        int datarecv[3];

	ReadFile(Resipod,&datarecv[0],1,&dwReading,NULL);
	ReadFile(Resipod,&datarecv[1],1,&dwReading,NULL);
	ReadFile(Resipod,&datarecv[2],1,&dwReading,NULL);
	
	cout <<hex<<(int) datarecv[0];
	cout<<"\n";
	cout<<(int) datarecv[1];
	cout<<"\n";
	cout<<(int) datarecv[2];
	cout<<"\n";


my new output is



datarecv[0] = cccccc02
datarecv[1] = ccccccad
datarecv[2] = cccccc4c



This output now looks like the output indicated by the operators manual. The last step is to covert it to this 16 information so that I can read the data.

How would I go about that?

“0x02 0x00 (Data Lowbyte) 0x00 (Data Highbyte).”
Readout data is 16 bits:
Bit 0..10 0..1999kohm*cm
Bit 11 decimal point (0:1999 kohm*cm, 1:199.9 kohm*cm)
Bit 12 derivated
Bit 13..15 0=OL, 1-5= 10-50 micro-Amps, 6=200 microamps

Thank you!!!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        static const char data[]={0xC1, 0xD2, 0x21};
	int size = sizeof(data)/sizeof(data[0]); // get array length; do not use strlen for binary data
	DWORD dwWritten, dwReading;

	WriteFile(Resipod,data,size,&dwWritten,NULL);

        char datarecv[3]; // my mistake; data type should be char because you are reading one byte at a time

// you can try to read all bytes at once
	ReadFile(Resipod,&datarecv[0],1,&dwReading,NULL);
	ReadFile(Resipod,&datarecv[1],1,&dwReading,NULL);
	ReadFile(Resipod,&datarecv[2],1,&dwReading,NULL);
	
	cout <<hex<<(int) datarecv[0];
	cout<<"\n";
	cout<<(int) datarecv[1];
	cout<<"\n";
	cout<<(int) datarecv[2];
	cout<<"\n";


As I understand, the device sends data like this: 0x02 16-bits-of data. Assuming 0xad 0x4c is the data that you need, you can can manipulate bits directly with &, >>, << operators or use union and struct:

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
  
#pragma pack(1)
 // in 'union' all variables share the same space in RAM
  union data_u
  {
      char data[2];
      struct
      {
          short resistance:11; // 11 bits for resistance
          char dec_point:1; // 1 bit for decimal point
          char derivated:1; // 1 bit for derivated.. whatever that means
          char amp_value:3;
      }devdata;
  };
  #pragma pack(0)

// ...

  data_u data_recv;
  char byte_status;


  // read first byte (status byte ?)
  ReadFile(Resipod,&byte_status,1,&dwReading,NULL);
  // read 2 data bytes
  ReadFile(Resipod,&data_recv,2,&dwReading,NULL);

  // access data you need
  cout <<data_recv.devdata.resistance; // or dec_point, derivated... 



And one more thing: before reading data from serial port, you can check whether there is data in queue
1
2
3
4
5
6
7
8
9
  COMSTAT status;
  DWORD errors;

  ClearCommError(Resipod, &errors, &status);

 if(cb.cbInQue>0)
 {
     // read data from serial port
 }

Last edited on
This last part lost me a bit. I tried this but I'm not sure it is working correctly.

This might help, I'm making measurements on a calibration device, the values should be

resistivity = 16.0 kohm*cm
amp = 200 microamp

so the readout should be

bit 0..10 should be 160
bit 11 should be 1
bit 12 I have no idea what derivated is
bit 13--15 should be 6


for this code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        static const char data[]={0xC1, 0xD2, 0x21};
	int size = sizeof(data)/sizeof(data[0]);
	DWORD dwWritten, dwReading;

	WriteFile(Resipod,data,size,&dwWritten,NULL);

	char datarecv[3];

	ReadFile(Resipod,&datarecv[0],1,&dwReading,NULL);
	ReadFile(Resipod,&datarecv[1],1,&dwReading,NULL);
	ReadFile(Resipod,&datarecv[2],1,&dwReading,NULL);
	
	cout <<hex<<(int) datarecv[0];
	cout<<"\n";
	cout<<(int) datarecv[1];
	cout<<"\n";
	cout<<(int) datarecv[2];
	cout<<"\n";


output for this code is

2
ffffffa0
ffffffc8


for this code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        static const char data[]={0xC1, 0xD2, 0x21};
	int size = sizeof(data)/sizeof(data[0]);
	DWORD dwWritten, dwReading;

	WriteFile(Resipod,data,size,&dwWritten,NULL);

	int datarecv[3];

	ReadFile(Resipod,&datarecv[0],1,&dwReading,NULL);
	ReadFile(Resipod,&datarecv[1],1,&dwReading,NULL);
	ReadFile(Resipod,&datarecv[2],1,&dwReading,NULL);
	
	cout <<hex<<(int) datarecv[0];
	cout<<"\n";
	cout<<(int) datarecv[1];
	cout<<"\n";
	cout<<(int) datarecv[2];
	cout<<"\n";


output for this code is

cccccc02
cccccca0
ccccccc8


for 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
	static const char data[]={0xC1, 0xD2, 0x21};
	int size = sizeof(data)/sizeof(data[0]);
	DWORD dwWritten, dwReading;

	WriteFile(Resipod,data,size,&dwWritten,NULL);

       #pragma pack(1)
        // in 'union' all variables share the same space in RAM
        union data_u
       {
      char data[2];
      struct
      {
          short resistance:11; // 11 bits for resistance
          char dec_point:1; // 1 bit for decimal point
          char derivated:1; // 1 bit for derivated.. whatever that means
          char amp_value:3;
      }devdata;
  };
  #pragma pack(0)

// ...

  data_u data_recv;
  char byte_status;

  // read first byte (status byte ?)
  ReadFile(Resipod,&byte_status,1,&dwReading,NULL);
  // read 2 data bytes
  ReadFile(Resipod,&data_recv,2,&dwReading,NULL);

  // access data you need
  cout <<data_recv.devdata.resistance; // or dec_point, derivated... 
  cout<<"\n";
  cout <<data_recv.devdata.dec_point;
  cout<<"\n";
  cout <<data_recv.devdata.amp_value;
  cout<<"\n";


output for this code is

160
(blank)
(heart symbol)



Thank you for the continued help
dec_point is of type char, so cout treats it as a printable character.
1
2
3
4
5
6
7
  // access data you need
  cout <<data_recv.devdata.resistance; // or dec_point, derivated... 
  cout<<"\n";
  cout <<(int)data_recv.devdata.dec_point; // cast to int
  cout<<"\n";
  cout <<(int)data_recv.devdata.amp_value; // same here
  cout<<"\n";
Topic archived. No new replies allowed.