I'm having a really strange inconsistancy.
I'm preparing for reading from binary files on Arduino (for a midi player, in case you were interested).
If I try to combine 4 bytes on Arduino to a long, it gives me a wrong result.
However, if I use the equivalent code on PC, I get the correct value.
Input is: 0x12481248 (0x12, 0x48, 0x12, 0x48) (really a random number).
Arduino gives: 4680.
Code::Blocks gives: 306713160.
4680 is the same as 0x1248, and the result you get when you use an int instead of long on Arduino (2 bytes omitted).
Arduino code:
void setup(){
Serial.begin(57600);
char read1 = 0x12;
char read2 = 0x48;
char read3 = 0x12;
char read4 = 0x48;
unsigned long testint = read1<<24|read2<<16|read3<<8|read4;
unsigned long testint2 = 306713160;
Serial.println(testint);
Serial.println(testint2);
}
void loop(){}
testint2 is to show that it isn't caused by Serial.println(). Serial Monitor output is indeed:
4680
306713160
C++ code:
#include <iostream>
using namespace std;
int main(){
char read1 = 0x12;
char read2 = 0x48;
char read3 = 0x12;
char read4 = 0x48;
unsigned long testint = read1<<24|read2<<16|read3<<8|read4;
cout << testint;
}
Any idea what's going on?
Also, does anyone know a better/prettier way of converting bytes with Arduino/SD library?
The long that you want to construct is done by shifting one of the bytes in the array 24 places to the next. Then, the next byte is shifted 16 bits to the left, and added. Then, the next byte is shifted 8 bits to the left, and added. Then, the final byte is added.
The BigInteger class has a longValue() method to convert a byte array to a long value: long value = new BigInteger(bytes). longValue();
One method is to create a string variable and then append the byte value to the string variable with the help of + operator. This will directly convert the byte value to a string and add it in the string variable. The simplest way to do so is using valueOf() method of String class in java.
On Arduino, int
size is 16 bits.
In this line:
unsigned long testint = read1<<24|read2<<16|read3<<8|read4;
even if the result is stored in a unsigned long
(32 bits), the bitwise operations are done on int
s.
Change this line to:
unsigned long testint = (unsigned long)read1 << 24
| (unsigned long)read2 << 16
| (unsigned long)read3 << 8
| (unsigned long)read4;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With