I have stumbled upon a problem that I cannot find the answer to. I have read on the forum and also on other sites for similar problems but I had no luck.
What I am trying to do is to bit-shift an unsigned long integer containing the value micros() into 4 bytes to send over serial communication. This is my code:
unsigned long timestamp;
byte timestamp_byte[4];
void setup() {
// put your setup code here, to run once:
Serial.begin(38400);
}
void loop() {
// put your main code here, to run repeatedly:
timestamp = micros();
timestamp_byte[0] = timestamp >> 24; //First 8 bits
timestamp_byte[1] = timestamp >> 16;
timestamp_byte[2] = timestamp >> 8;
timestamp_byte[3] = timestamp; //Last 8 bits
Serial.write(timestamp_byte[0]);
Serial.write(timestamp_byte[1]);
Serial.write(timestamp_byte[2]);
Serial.write(timestamp_byte[3]);
Serial.println("");
Serial.println(timestamp); //Print for verifying purposes
Serial.println(timestamp,BIN);
delay(1000);
}
I save the serial data sent to the computer using RS232 DataLogger (Eltima Software) to create a .txt file. I have then used Matlab and also Free Hex Editor Neo to check the contents of the file.
As far as I can tell my code works for the 3 lower bytes. The problem is in the first byte of timestamp_byte I send as it it always 00100000 instead of 00000000 (At least for the first 16 seconds it should be 00000000).
For example if timestamp = 1000576 (us)
I get
00100000 00001111 01000100 10000000 (= 537871488 in DEC)
instead of
00000000 00001111 01000100 10000000 (= 1000576 in DEC)
I have tested this on several numbers and the problem persist. I am probably missing something important here, but I don't know what.
I hope someone can help me.
Sincerely, MJ
Some additional info:
The code I posted is only a part of a larger code that reads some sensor inputs, but I have tested this exact code I provided and it has the same problem.
The board I am using is a Arduino Uno board rev. 3 (From original starter kit)
The baud rate is set higher than 9600 due to large amounts of data I need to transfer in the original code.
write_bytes_from_long_test_12_11.ino: In function 'void loop()':
write_bytes_from_long_test_12_11:21: error: call of overloaded 'write(long unsigned int&, int)' is ambiguous
write_bytes_from_long_test_12_11.ino:21:28: note: candidates are:
In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26:0,
from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:29,
from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:224,
from write_bytes_from_long_test_12_11.ino:1:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:54:12: note: size_t Print::write(const char*, size_t)
size_t write(const char buffer, size_t size) {
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:54:12: note: no known conversion for argument 1 from 'long unsigned int' to 'const char'
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:53:20: note: virtual size_t Print::write(const uint8_t*, size_t)
virtual size_t write(const uint8_t buffer, size_t size);
^
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:53:20: note: no known conversion for argument 1 from 'long unsigned int' to 'const uint8_t {aka const unsigned char*}'
call of overloaded 'write(long unsigned int&, int)' is ambiguous
This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.
So you don't think I made an error in my code with the bit shifting? Because there must be something wrong with the first byte I send over...
The 00100000 is the space character you are sending in the println perhaps?
I think the receiving end is eliding null characters - have you set it up in
binary mode (ie no software flow control or interpretation of control characters?)
The 00100000 is not the space character. I have flow control set to none (I don't know what that means). The thing is, I can read the last three bytes correctly, only the first one is corrupted so I doubt it is a logging issue. I have tried waiting 16 seconds and the reading after that show correct as the value from micros is larger than 3 bytes. The first byte is then 00000001. After about 32 seconds it is 00000010 which also gives a correct value.
I think I have solved it now...
I have assigned the unsigned long integer timestamp a high value, so the first line in the program is now:
unsigned long timestamp = 1UL << 31; //This should now be number 2^31
I have no idea why this affects anything, since the function micros should override the value anyways even if it was not initialized before.
Which confirms that you made some changes. You didn't post the modified code, though...
I forgot to write the line of code that I changed into the code brackets. I have included the code in my post though.
I'm going to guess that you masked the original problem, or you changed more than you said, and fixed the problem.
As it turns out I actually did without noticing it. The problem was all along with Notepad. If I opened the file and saved it again it changed the character from 00000000 to 00100000 (probably also other charachters). So all this time I was looking for the problem in the wrong place. Thanks for the help.
MJamsek:
As it turns out I actually did without noticing it. The problem was all along with Notepad. If I opened the file and saved it again it changed the character from 00000000 to 00100000 (probably also other charachters). So all this time I was looking for the problem in the wrong place. Thanks for the help.
Ah. Use a hex editor - plenty of free ones out there.