Go Down

Topic: serialWrite(255) (Read 613 times) previous topic - next topic

horchi

Mar 10, 2008, 11:54 pm Last Edit: Mar 10, 2008, 11:54 pm by horchi Reason: 1
hello,

i have some trouble using serialWrite(), i write a 4 byte structure with the loop below, all works file if no value reaches 255. If a value is exact 255 one ore two more bytes received on pc side.

Code: [Select]


struct AnalogInput   // 4 byte
{
  byte protocol;
  byte command;

  byte u;
  byte i;
};

void serialPrint(const unsigned char buf[], byte size)
{
  for (int i = 0; i < size; i++)
     serialWrite(buf[i]);
}

void send()
{
  AnalogInput data;

  data.protocol = protocoll;
  data.command = cAnalogIn;
  data.u = 255;
  data.i = 255;

  serialPrint((byte*)&data, sizeof(AnalogInput));
}


I checked the sizeof(AnalogInput) and the alignment (pack) all looks fine. The effect is independent of the baud rate.

If all members are less than 255 i receive exact 4 bytes on pc side, if i and u is 255 (as in the example above) i receive 6 bytes.

Does i have to initialize the device on the PC side (for binarie data) in other way than the code below?

Code: [Select]

  if ((fd = open(device, O_RDWR | O_NOCTTY)) < 0)
  {
     perror(device);
     return fail;
  }

  theEloquence = eloDebug;

  // configure serial line

  tcgetattr(fd, &oldtio);
  bzero(&newtio, sizeof(newtio));
  newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
  newtio.c_iflag = IGNPAR | PARMRK;
  newtio.c_oflag = 0;
  newtio.c_lflag = 0;
  tcflush(fd, TCIFLUSH);
  tcsetattr(fd, TCSANOW, &newtio);


Regards
horchi

horchi

#1
Mar 11, 2008, 07:39 am Last Edit: Mar 11, 2008, 09:49 am by horchi Reason: 1
The solution was to remove PARMRK from the flags:

Code: [Select]

  tcgetattr(fd, &oldtio);
  bzero(&newtio, sizeof(newtio));
  newtio.c_cflag = B57600 | CS8 | CLOCAL | CREAD;
  newtio.c_iflag = IGNPAR; //
  newtio.c_oflag = 0;
  newtio.c_lflag = 0;
  tcflush(fd, TCIFLUSH);
  tcsetattr(fd, TCSANOW, &newtio);


now it's working fine  :)

If someone is interested, heres what i found about this:

Quote

Macro: tcflag_t PARMRK
If this bit is set, input bytes with parity or framing errors are marked when passed to the program. This bit is meaningful only when INPCK is set and IGNPAR is not set.

The way erroneous bytes are marked is with two preceding bytes, 0xFF and 0. Thus, the program actually reads three bytes for one erroneous byte received from the terminal.
If a valid byte has the value 0xFF, and ISTRIP (see below) is not set, the program might confuse it with the prefix that marks a parity error. So a valid byte 0xFF is passed to the program as two bytes, 0xFF 0xFF, in this case.


Regards
Jörg

Go Up