PDA

View Full Version : HEX addition, subtraction LRC ASCII

phakorr
28th April 2014, 10:12
Trying to do ASCII LRC calculation, so I have hex values stored in a QByteArray, something in the lines of 01050500FF00, I need to add these values together, then subtract the result from FF, and add 1 to get the LRC..

in short :
1- Step1 = Sum Hex bytes of given QByteArray
2- Step2 = "FF" - Step1 (take the right part)
3- Step3 = Step2 + 1

Example :

1 - "01050500FF00", LRC should be F6
0+1+0+5+0+5+0+0+F+F+0+0 = 010A
FF - 0A = F5
F5 +1 = F6

2 - "010505000000", LRC should be F5
ie 0+1+0+5+0+5+0+0+0+0+0+0 = 0B
FF - 0B = F4
F4 + 1 = F5

My question is there an easy way to do Hex addition and subtraction in QT? if so how? or do I convert to decimal... case 'A' : a[i] = 11;break;... and so on..

tnx for any help..

p.s. C++

Lesiok
28th April 2014, 11:45
Did You have in QByteArray characters ('0'..'9', 'A'..'F') or bytes (0..0xf) ? This is not the same.

phakorr
28th April 2014, 16:24
Supposed to have bytes..

The QByteArray crcWord is formed as such.. where ;

ui->lineEdit->text() is '01' (slave id)
functioncode is '05' (modbus function code)
ui->lineEdit_2->text() is '0500' (Register address hex)
ui->lineEdit_3->text() is '0000' (or 'FF00' from the examples I gave) (data)

QByteArray crcWord = QString(ui->lineEdit->text() + functionCode + ui->lineEdit_2->text() + ui->lineEdit_3->text()).toLatin1();

I later write to the port, it all works when I manually add the LRC manually (i.e. replace the crc.toUpper() with "F5" (or whatever the LRC value of the word is) )

..

QString sendWord = ":" + crcWord + crc.toUpper() + "\r\n";

QByteArray sndwrd = sendWord.toLatin1();
const char *cstr = sndwrd.data();

serial->write(cstr);
serial->close();

sulliwk06
28th April 2014, 17:00
Is this what you are trying to implement?

http://en.wikipedia.org/wiki/Longitudinal_redundancy_check

If so, you'll need to take your byte array which contains a string, and pull 2 characters out of it at a time to convert them to bytes. Then do your calculations on the bytes.

Lesiok
28th April 2014, 17:39
So in QByteArray You have ASCII characters (string) not binary data. You can convert them to binary data with QByteArray::fromHex method and then simply add byte by byte.

ChrisW67
29th April 2014, 01:04
Your description of the process is wrong but you have given the correct result in both cases.

1 - "01050500FF00", LRC should be F6
0+1+0+5+0+5+0+0+F+F+0+0 = 010A // wrong working, right answer
0x01 + 0x05 + 0x05 + 0x00 + 0xFF + 0x00 = 0x010A // this is the correct working
FF - 0A = F5
F5 +1 = F6

Steps 2 and 3 are a description of negating a number in Two's-complement (http://www.wikipedia.org/wiki/Two%27s_complement). Your computer will do this for you. Here is your example with the LRC appended to the input:

QByteArray input("01050500FF00");

// Convert to binary
QByteArray work = QByteArray::fromHex(input);
// Step 1, sum bytes (relies on char losing any overflow)
char sum = 0;
foreach (char c, work)
sum += c;
// steps 2 and 3: negate result
sum = -sum;

qDebug() << "Input =" << work.toHex().toUpper();
work.append(sum);
qDebug() << "With LRC =" << work.toHex().toUpper();

phakorr
29th April 2014, 03:57
Your description of the process is wrong but you have given the correct result in both cases.

..
0+1+0+5+0+5+0+0+F+F+0+0 = 010A // wrong working, right answer
0x01 + 0x05 + 0x05 + 0x00 + 0xFF + 0x00 = 0x010A // this is the correct working
...

Steps 2 and 3 are a description of negating a number in Two's-complement (http://www.wikipedia.org/wiki/Two%27s_complement). Your computer will do this for you. Here is your example with the LRC appended to the input:
....

Thanks for the reply, all is working now. I wrote the calculation wrong partially on purpose as oddly enough it still calculates the LRC correctly for all the samples that I tried it on..