Go Down

Topic: No such thing as a 'Nibble' in C++? (Read 1 time) previous topic - next topic

FeersumEndjinn

Hi,

I'm fairly new to Arduino and I am currently working with a Serial GPS receiver.

I receive some returned bytes such as firmware versions as a byte, however the higher 2 bits form the major revision, then there should be a decimal place, then the lower 2 bits form the minor revision number.

Please can anyone help me or point me in the right direction to split bytes in 2?  The bit() command only seems to allow you to look at individal bits, when I need a 'nibble', 2 bit size.

Many Thanks,
Morrolan

Groove

I always thought of nibbles (or nybbles) as being half a byte, or four bits.

hint: if you can read a single bit, you're halfway there.
Per Arduino ad Astra

FeersumEndjinn

Groove,

I'm sorry you are correct, a nibble is 4 bits, allowing values between 0 - 15.

Maybe it is my lack of understanding of C++, but how would one add the four individual bits together form 1 single nibble-sized number?

Many Thanks,
Morrolan  

AlphaBeta

Code: [Select]
typedef struct {
 unsigned low:4;
 unsigned high:4;
} nibble;

nibble test = { 3, 6 };

void setup() {
 Serial.begin(9600);
 Serial.println(test.low);
 Serial.println(test.high);
}
void loop(){}

Professor Chaos

#4
Oct 08, 2010, 10:25 pm Last Edit: Oct 08, 2010, 11:50 pm by lefstin Reason: 1
Assuming you are trying to decompose a received byte into two nibbles:

Code: [Select]
byte data;

byte lownibble = data & B00001111;

byte highnibble = data >> 4;

P18F4550

Im with Professor Chaos on this one, you could use some inline asm also such as
swapf, data
which swaps the high nib and low nib in a byte, it is useful when talking to 4bit lcd's

Rusty in Texas

And I don't believe that there's anything in the C or C++ language
references that would guarantee that the 'high' bitfield would be aligned
with the four most significant bits nor the 'low' bitfield being aligned with
the four least significant bits.  Maybe on the Arduino it might work....

Coding Badly

#7
Oct 09, 2010, 07:09 am Last Edit: Oct 09, 2010, 07:14 am by bcook Reason: 1
Quote
Maybe on the Arduino it might work....

It does.  It works well.

For those concerned with performance... certain combinations of bit fields will generate several machine instructions.  AlphaBeta's example is fairly lean.  I think it's the same as using shift-and.

westfw

The compiler is actually smart enough to use swapf when doing bit pieces of 4 bits.  Sometimes.  C does better than C++...

(http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=752634#752634 )

UltraMagnus

#9
Oct 09, 2010, 01:28 pm Last Edit: Oct 09, 2010, 01:29 pm by UltraMagnus Reason: 1
http://softsolder.com/2009/11/23/arduino-bit-fields-start-low/

bitfields and unions are incredibly useful in uC programming.

AWOL

Quote
bitfields and unions are incredibly useful in uC programming

And also incredibly irritating if you inadvertently use the same union at opposite ends of a link with different endianness.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

UltraMagnus

Quote
And also incredibly irritating if you inadvertently use the same union at opposite ends of a link with different endianness.


perhaps, but that is nothing that cannot be solved by a quick lookup table.

westfw

Quote
nothing that cannot be solved by a quick lookup table.

IIRC, the IP "Fragment offset" field can not be represented as a C bitfield on a little-endian CPU/compiler.  It spans the byte boundry on a big-endian system, but ends up discontiguous on little-endian systems.  So there are things that can't be solved with a lookup table...

:-)

Go Up