Pages: [1]   Go Down
Author Topic: How do I get the 3d byte of a word?  (Read 1199 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
  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:
  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
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 610
Posts: 49073
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
  byte third_byte = ( addr >> 16 ) & 0xff; // 0xff is 11111111 in binary

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Paul.  Woops... I mean "3d byte of a long" I think!

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

Cheers,
- Bret
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

France
Offline Offline
Edison Member
*
Karma: 37
Posts: 1005
Scientia potentia est.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello, something like that:
Code:
b3 | (b2 << 8) | (b1 << 16)
« Last Edit: December 21, 2012, 12:19:26 am by guix » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 300
Posts: 26219
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Be careful; shifting an Arduino "int" left sixteen bits is likely to leave you with nothing.
Best cast it to "unsigned long" first.
Logged

"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.

Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Edison Member
*
Karma: 5
Posts: 1730
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Add
Unsigned long 3dbyte =
Before that and youl be fine
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 300
Posts: 26219
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Unsigned long 3dbyte
You can't have a variable or function name that starts with a digit.
Logged

"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.

Pakistan
Offline Offline
Sr. Member
****
Karma: 6
Posts: 357
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You can't have a variable or function name that starts with a digit.
This happen last night to me when i defined
Code:
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
Logged


Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 610
Posts: 49073
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Add
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.
« Last Edit: December 22, 2012, 07:41:15 am by PaulS » Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: December 24, 2012, 03:08:35 am by Coding Badly » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 300
Posts: 26219
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
And, I hope this isn't a dump question, but how could I test this code?
With an Arduino?
Just a thought.
Logged

"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.

Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1]   Go Up
Jump to: