Go Down

### Topic: How do I get the 3d byte of a word? (Read 2762 times)previous topic - next topic

#### clone45

##### Dec 15, 2012, 07:13 pm
Hello,

How do I get the 3rd byte of a word?

I have code that can get me the low and high bytes of an int, which looks like this:

byte high_byte = ( addr >> 8 ) & 0xff; // 0xff is 11111111 in binary
byte low_byte = addr & 0xff;

But now I need to get the three lowest bytes of a word.  How would I do that?  For example:

Code: [Select]
`  byte first_byte = ??;      // lowest byte  byte second_byte = ??;   // second lowest byte  byte third_byte = ??;     // third lowest byte`

I find myself in this situation after upgrading some ram from a 256k chip to a 1-meg chip.  Having done so, the memory addresses can't fit in a word anymore, and the chip that I'm using (a FM25V10) requires that I use 17bit addresses which are passed in via the SPI interface.

My old code looks like this:

Code: [Select]
`  byte addrByte2 = ( addr >> 8 ) & 0xff; // 0xff is 11111111 in binary  byte addrByte1 = addr & 0xff;      digitalWrite(chip_select, LOW);  SPI.transfer(CMD_WREN);  //write enable  digitalWrite(chip_select, HIGH);    digitalWrite(chip_select, LOW);  SPI.transfer(CMD_WRITE); //write command    // Transfer memory address  SPI.transfer(addrByte2);  SPI.transfer(addrByte1);   // Transfer value (byte)  SPI.transfer(value);`

Thanks,
- Bret

#### PaulS

#1
##### Dec 15, 2012, 07:19 pm
word seems to be a Microsoft-specific term. While the Arduino unfortunately supports such a term, it is not common usage, so one of us needs to look up its size.

If the first byte occupies the lowest 8 bits, and the second bytes occupies the next 8 bits, it doesn't seem unlikely that the 3rd byte occupies the next 8 bits.

Code: [Select]
`  byte third_byte = ( addr >> 16 ) & 0xff; // 0xff is 11111111 in binary`

#### clone45

#2
##### Dec 15, 2012, 07:49 pm
Thanks Paul.  Woops... I mean "3d byte of a long" I think!

I figured as much, but I wanted to be sure. :-)

Cheers,
- Bret

#### clone45

#3
##### Dec 21, 2012, 03:13 am
I have a follow up question.  I now need to go the other direction.  I have three bytes representing the lower 3 bytes of a long.  I need to construct an unsigned long out of them and set the remaining 8 most significant bits of the long to 0.  How do I pull that off?

Thanks,
- Bret

#### guix

#4
##### Dec 21, 2012, 06:17 amLast Edit: Dec 21, 2012, 06:19 am by guix Reason: 1
Hello, something like that:
Code: [Select]
`b3 | (b2 << 8) | (b1 << 16)`

#### AWOL

#5
##### Dec 21, 2012, 08:35 am
Be careful; shifting an Arduino "int" left sixteen bits is likely to leave you with nothing.
Best cast it to "unsigned long" first.
"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.
I speak for myself, not Arduino.

#### clone45

#6
##### Dec 22, 2012, 03:39 am
AWOL,

You got me thinking.  I have each of the values stored in bytes.  Wouldn't guix's solution not work?  Wouldn't b2 << 8 shift all the bits off of my byte completely?

For example:

byte my_variable;
print my_variable << 8;  // would this print 0?

Cheers,
- Bret

#### winner10920

#7
##### Dec 22, 2012, 07:00 am
Unsigned long 3dbyte =
Before that and youl be fine

#### AWOL

#8
##### Dec 22, 2012, 08:21 am
Quote
Unsigned long 3dbyte

You can't have a variable or function name that starts with a digit.
"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.
I speak for myself, not Arduino.

#### Khalid

#9
##### Dec 22, 2012, 08:31 am

You can't have a variable or function name that starts with a digit.

This happen last night to me when i defined
Code: [Select]
`byte 1stTime=30;`
and i was unable to compile with a bizaree error of Arduino...
I replaced the 1 with f and now its working fine.
Lesson Learnt:
1-Always define variable without using the digit.
2- If forget , then visit this thread
Simply...You can't afford me..

Author Of:
http://my-woodcarving.blogspot.com/
http://www.free3dscans.blogspot.com/
http://my-diysolarwind.blogspot.com/

Oops..some one gave me Karma...

#### PaulS

#10
##### Dec 22, 2012, 01:39 pmLast Edit: Dec 22, 2012, 01:41 pm by PaulS Reason: 1
Quote
Unsigned long 3dbyte =
Before that and youl be fine

Aside from the incorrect name, the underlying premise is false.

Try this:
unsigned long validName = 60 * 1000 * 10;
The result of 60 * 1000 * 10 will fit in an unsigned long, right? Of course. But, what value is actually there when you print validName? It will not print as 600000.

Why? Because all the values on the right are int values, so int arithmetic is used. And, 60 * 1000 is NOT going to fit in an int.

The same problem happens with bit shifting. When all the values in the equation are int or smaller (as in b1 << 16), the registers used will be int registers, and the result of b1 << 16 will be that all the bits in b1 got shifted out of the int register.

On the other hand, ((unsigned long)b1 << 15) will cause the use of a larger register, so the shifted result is not lost. When the contents of this unsigned long register are ultimately assigned to an unsigned long, the result will be correct.

The type on the left side of the equal sign is not even considered until the compiler has created a result based on the right side information, types, and values to be assigned, so changing the left side type only won't help.

#### dhenry

#11
##### Dec 22, 2012, 01:56 pm
3rd byte of a word doesn't exist.

There are a few ways to get to the 3rd (most significant) byte of an unsigned long. The fastest would be to cast it to a unsigned char pointer, and advance that pointer by 2 to get to the 3rd byte.

You can also use union, or a pointer to a struct that contains 4 bytes.

The downside with such approaches would be that they are endian dependent.

#### clone45

#12
##### Dec 24, 2012, 05:51 amLast Edit: Dec 24, 2012, 09:08 am by Coding Badly Reason: 1
PaulS,

So, are you saying that this might work?:

unsigned long somevar = (unsigned long)b3 | ((unsigned long)b2 << 8) | ((unsigned long)b1 << 16)

And, I hope this isn't a dump question, but how could I test this code?  Should I use the arduino simulator?

Cheers,
- Bret

#### AWOL

#13
##### Dec 24, 2012, 09:06 am
Quote
And, I hope this isn't a dump question, but how could I test this code?

With an Arduino?
Just a thought.
"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.
I speak for myself, not Arduino.

#### clone45

#14
##### Dec 24, 2012, 04:59 pm
AWOL,

Oh, yeah... I think I get where you're coming from.  You mean, like use Serial.print()?  I forgot that even existed.  Thanks for the tip.

- B

Go Up