PDA

View Full Version : Sending over UDP - Binary Manipulation



Cotlone
7th June 2010, 04:10
Hi everyone,

I am communicating with a microcontroller through UDP, this microcontroller in turn sends data to an ASIC. The ASIC receives SPI strings of length 50bits and 904bits in two different modes. I am in the process of generating a user interface with Qt to allow for the handling of settings/data to be sent and now I need to find a decent way to package my numbers into an acceptable format.

For instance, I have 5 x 10bit numbers creating the 50bit stream (I also need to append 6 zeros to the front for the uController handling). Each of these numbers is currently stored in Qt as an int.

How would I go about packaging this data to send as a datagram over UDP?

I was considering using either a QByteArray or a QBitArray. The byte array seems more useful for strings (I think it is also '/0' terminated, which may get sent over UDP -- ??) If I construct a QBitArray, is there an easy was to convert my int numbers to 10bits?

Despite the fact that I have not solved this problem, it still seems rather trivial... I would really appreciate any help or insight into this matter, thanks!

- Cotlone

tbscope
7th June 2010, 07:37
A bit array is more like a series of switches. It's not meant to be used to represent 10 bit numbers for example, although you can do that.
A byte array stores bytes, and a byte is 8 bits.

You can use fromRawData with the byte array, then it is not /0 terminated.
But here too, your computer uses 8 bits for a byte.

What you need to do is create a converter. You say that you need to append (or prepend) 6 bits? So that means you need to receive and send 56 bits? That would be easy then, as this is a multitude of 8 bits. So in essence you need to send and receive 56/8 = 7 bytes. The same with 904 bits, which is 113 bytes.

JD2000
7th June 2010, 14:33
sprintf() function with the %d modifier ?
- just a thought!

Cotlone
8th June 2010, 06:15
Thanks for your replies guys. Yeah, the extra 6 bits prepended (I wrote appended before sorry) is to chock the length to the next multiple of 8 (56) to give the 7 bytes for transmission.

I had set up a bit of code here to load a bit array. My values are 10bit (as defined by "unsigned varname:10;") and taken from the settings object in each respective getX function. I'm then loading the individual bits in the array as I go, this seems to work fine, but would using fromRawData be more appropriate here, as I still need to convert to a QByteArray for sending with writeDatagram (from the UDP socket class)?

Is it generally easier to convert this QBitArray to a QByteArray or just figure a way to generate the QByteArray in the first place?



QBitArray *bitArray = new QBitArray(56);

for(int i=0;i<10;i++)
{
bitArray->setBit(i+40, (settings->getVH2()&(2^i))==(2^i)); // AND the value with a mask and see if it equals the mask
bitArray->setBit(i+30, (settings->getVL2()&(2^i))==(2^i));
bitArray->setBit(i+20, (settings->getVH1()&(2^i))==(2^i));
bitArray->setBit(i+10, (settings->getVL1()&(2^i))==(2^i));
bitArray->setBit(i+00, (settings->getVL0()&(2^i))==(2^i));
}


Thanks again for your help guys!

tbscope
8th June 2010, 06:41
Here's what I would do



0: 000000
1: 0000011111 (decimal = 31)
2: 1100110011 (decimal = 819)
3: 0011100111 (decimal = 231)
4: 1110000111 (decimal = 903)
5: 1010101010 (decimal = 682)

In total:

00000000000111111100110011001110011111100001111010 101010

In 8 bit sections:

00000000 00011111 11001100 11001110 01111110 00011110 10101010
Values: 0 63 204 206 63 30 170


Turn those decimal values into chars. Then use a QByteArray to append them.
http://doc.qt.nokia.com/4.6/qbytearray.html#fromRawData

Do the same in reverse when reading the data.

Cotlone
9th June 2010, 01:48
Thanks for your reply tbscope, I appreciate it ;-)
As for the data manipulation and packaging, I was thinking the same thing as you illustrated. This is what I have implemented at present, though on a second look I think I may need to shuffle the order of my variables/bits around. Using QByteArray this seems to be the easiest way to go, I can also send this QByteArray directly into the writeDatagram function of QUdpSocket.



/*
50 bit input:
P0:P9(VH2), P0:P9(VL2), P0:P9(VH1), P0:P9(VL1), P0:P9(VL0)
first bit of data stream is P9(VL0), last bit of data stream P0(VH2)

bbbbbbbbBBBBBBBBbbbbbbbbBBBBBBBBbbbbbbbbBBBBBBBBbb bbbbbb
MSB 00000055555555554444444444333333333322222222221111 111111 LSB
*/

QByteArray *thresholdData = new QByteArray();
thresholdData->append((unsigned char)(settings->getVH2() >> 8));
thresholdData->append((unsigned char)(settings->getVH2()));
thresholdData->append((unsigned char)(settings->getVL2() >> 2));
thresholdData->append((unsigned char)((settings->getVL2() << 6) | (settings->getVH1() >> 4)));
thresholdData->append((unsigned char)((settings->getVH1() << 4) | (settings->getVL1() >> 6)));
thresholdData->append((unsigned char)((settings->getVL1() << 2) | (settings->getVL0() >> 8)));
thresholdData->append((unsigned char)(settings->getVL0()));


Thanks for your help!

JD2000
9th June 2010, 09:24
Its been a long time since I did any bit twiddling and I forgot about bit fields, you can use one of these:

struct asicdata{
unsigned int padding :6
unsigned int a :10
unsigned int b :10
unsigned int c :10
unsigned int d :10
unsigned int e :10
}

//using tbscope's data
struct asicdata dta = { 0, 31, 819, 231, 903, 682 }
I hope this helps.