1
\$\begingroup\$

Disclaimer: I am a novice.

I have an RS232 connection with an RFID tag reader which I am monitoring via software on a desktop computer as well as an Arduino. The device is configured with 8E1 parity. The arduino is (to the best of my knowledge) set up for 8N1 parity. Both the computer and arduino connect directly to the reader, and receive the exact same signal.

The arduino is reading a tag as follows:

10 00 62 00 10 29 C0 0F 00 39 12 C0 56 00 8D 0A

The computer is reading the same tag as follows:

30 00 E2 00 30 69 80 0F 00 59 12 80 96 00 0D 0A

With my (limited) understanding of parity, I can't figure out the conversion here. How is the arduino interpreting these bits to obtain those values?

\$\endgroup\$
7
  • 2
    \$\begingroup\$ You need to know what your reader protocol is, and configure the receiver accordingly. The "conversion" is to write everything in binary, draw the corresponding waveform and reinterpret according to each one of the configurations. \$\endgroup\$
    – Eugene Sh.
    Jul 11, 2018 at 21:27
  • \$\begingroup\$ Is the computer same as RFID setup? Parity should not affect results as it is the 9th bit and you are see signal integrity errors, check status bits for parity error. Also scope read signal \$\endgroup\$ Jul 11, 2018 at 22:00
  • \$\begingroup\$ are you sure that there is a parity bit? \$\endgroup\$
    – jsotola
    Jul 11, 2018 at 22:07
  • \$\begingroup\$ Also define how you send Lsb , msb order with parity and how you receive it supremainc.com/en/node/614 \$\endgroup\$ Jul 11, 2018 at 22:22
  • \$\begingroup\$ Have you tried viewing the signal on your scope? N means no parity bit. \$\endgroup\$
    – user253751
    Jul 11, 2018 at 23:09

3 Answers 3

1
\$\begingroup\$

Your tag reader is sending serial data with a parity bit, and the Arduino isn't configured to expect that.

You have two options:

  1. Configure the Arduino to read the parity bit by passing SERIAL_8E1 as the second argument to Serial.begin(). Once you've done this, the data should be received normally.

  2. Configure the device to not send a parity bit. (The manual implies that this is an option.)

The method that you've come up with is nonoptimal. It's likely to result in unpredictable, data-dependent read errors.

\$\endgroup\$
1
  • \$\begingroup\$ Everything in this answer is correct. Unfortunately, i'm using SoftwareSerial, which does not have the second argument, and setting the device to not use parity bits causes significant usability issues when configuring (i.e., it won't changes settings). Ultimately, once I'm more confident in the rest of my program I will probably switch to using Serial.begin() with the setting you've described. \$\endgroup\$ Jul 17, 2018 at 22:26
1
\$\begingroup\$

Thanks for all the help.

After doing some investigation with an oscilloscope, I've figured out what's going on:

Sample pure data from reader (LSB first, spaces added for clarity):

10 0000 11000 10 0000 00000 10 0100 01110 10 1011 00001 10 0101 00000 10
^s 0    ^3  ^p^s ^0   ^0  ^p^s ^2   ^E  ^p^s ^D   ^0  ^p^s ^A   ^0    ^s

For a data value of

0 3 0 0 2 E D 0 A 0  -> 30 00 E2 0D 0A

s is the stop indicator, p is the parity bit, and others are the hex data. What is happening on my arduino is that the parity bit is being read as the most significant bit for the second half of the byte, then the previous least significant bit is used to overwrite the new least significant bit of that half-byte.

Applied to the previous example:

11000 -> 1000
00000 -> 0000
01110 -> 0110
00001 -> 0001
00000 -> 0000

which produces:

0 1 0 0 2 6 D 8 A 0 -> 10 00 62 8D 0A

explaining the conversion that you see in my original example at the start and end bytes:

30 00 E2 0D 0A -> 10 00 62 8D 0A

If for some reason anyone else runs into this incredibly specific problem, I've converted the data back in the arduino logic with these functions (no they're not optimal):

byte fixBits(byte rc) {
    byte five = rc & 0x10;
    byte six = getParity(rc) << 5;
    byte hex1 = (rc & 0xF0) << 1;
    byte hex2 = rc & 0x0F;
    return ((hex2 | hex1) & 0xCF) | five | six; // bit masking
}

byte getParity(byte rc) {
    int sum = 0;
    byte test = rc;
    for (int i = 0; i < 8; i++) {
        sum += test & 1;
        test >> 1;
    }
    return sum & 1;
}

If anyone can describe exactly why this is happening I'd be curious to hear it, but otherwise this issue is solved.

\$\endgroup\$
0
\$\begingroup\$

Parity bit will not be part of data. If you have an oscilloscope or a logic analyzer plugin and monitor the bits one by one. You will understand.

enter image description here Ardiino is not configured to expect parity bit. Presently, arduino will be reporting errors for cases where parity bit is not one. Monitor UART error status registers. Arduino is expecting the location where parity bit is put (by the RFID reader) to be one always.. (STOP bit)

 

How is the computer interpreting these bits to obtain those values?

Computer will not operate on the received data. It will extract data from databits position as is.. And then computes the parity.. If the received parity doesn't match with computed parity, a parity error flag will be set in the error register. It is then task of the program to check it status whenever the data is received from the RFID.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.