Here's how I solved the problem of
printing 64 bit values as a string.
If there is an easier method I like to know?.
/******Testet on Arduino Due ******/
/***** Testet on Arduino Uno *****/
byte i = 0;
byte ComBuffer[12];
String str;
uint64_t MaxValue = 18446744073709551615; // 8 bytes (2 ^ 64) - 1 max value
void setup()
{
Serial.begin(115200);
Serial.println("Test for uint64_t to String."); // Test that program works
Serial.flush();
str = ToString(MaxValue); // uint64_t to string
Serial.println(str);
Serial.flush();
}
void loop()
{
if( Serial.available() > 0 )
{
ComBuffer[i] = (byte)Serial.read();
if (ComBuffer[i] == 13 )
{
if(ComBuffer[0] == 'p')
{
str = ToString(MaxValue); // uint64_t to string
Serial.println(str);
}
if(ComBuffer[0] == 'u') // Test add 1 to number
{
MaxValue = MaxValue + 1;
str = ToString(MaxValue); // uint64_t to string
Serial.println(str);
}
if(ComBuffer[0] == 'd') // Test subtract 1 from number
{
MaxValue = MaxValue - 1;
str = ToString(MaxValue); // uint64_t to string
Serial.println(str);
}
i = ClearComBuffer();
}
if(i == 11) // Prevent overflow of ComBuffer
i = ClearComBuffer();
i++;
}
}
String ToString(uint64_t x)
{
boolean flag = false; // For preventing string return like this 0000123, with a lot of zeros in front.
String str = ""; // Start with an empty string.
uint64_t y = 10000000000000000000;
int res;
if (x == 0) // if x = 0 and this is not testet, then function return a empty string.
{
str = "0";
return str; // or return "0";
}
while (y > 0)
{
res = (int)(x / y);
if (res > 0) // Wait for res > 0, then start adding to string.
flag = true;
if (flag == true)
str = str + String(res);
x = x - (y * (uint64_t)res); // Subtract res times * y from x
y = y / 10; // Reducer y with 10
}
return str;
}
int ClearComBuffer()
{ // clear com buffer for old data
for(int i = 0; i < 12; i++)
{
ComBuffer[i] = 0;
}
return -1;
}
Oh, and no need to keep looking up the upper limit of a 64 bit number when you can simply have the compiler provide it by including 'limits.h' and using the constant
Thanks for the many answers.
I testet all of your code on my Arduino Due board.
lloyddean you code will not compile this line, Serial.print(value % 10);
error: call of overloaded 'print(uint64_t)' is ambiguous?. and a long error list
You second proposal works great
Thanks for the infomation UINT64_MAX
guix code works great, i had to change your function to this to get it to compile.
String uintToStr( const uint64_t num, String str )
joergenHansen:
lloyddean you code will not compile this line, Serial.print(value % 10);
error: call of overloaded 'print(uint64_t)' is ambiguous?. and a long error list
It's telling you that the print() function doesn't have a method to handle 64 bit parameters. Try casting to a byte:
I have a new question, working on my Arduino Due board.
I've read on the internet about sampling volts, to get a better resolution.
I think it was a document from microchip, that explained how this could be done.
Speed is not important.
I'd love to have your opinion on this code.
void setup() {
analogReadResolution(12);
}
unsigned long SampleVolt()
{ // 12 bit to 14 bit 4 ^ 2 = 16 analogRead and div by 2 ^ 2 = 4
// 12 bit to 15 bit 4 ^ 3 = 64 analogRead and div by 2 ^ 3 = 8
// 12 bit to 16 bit 4 ^ 4 = 256 analogRead and div by 2 ^ 4 = 16
unsigned long Volt = 0;
for(int n = 0; n < 256; n++)
{
delayMicroseconds(20);
Volt = Volt + analogRead(A0);
}
Volt = Volt / 16;
return Volt; // 16 bit value
}
I have tested on a machine that moves a potentiometer to different postions,
and then reading the new potentiometer value.
This gave me a better resolution???.
That is NOT over-sampling, it is simply averaging a number of readings, which does absolutely nothing to improve accuracy or resolution. It simply creates more consistent readings.
// 12 bit to 14 bit 4 ^ 2 = 16 analogRead and div by 2 ^ 2 = 4
// 12 bit to 15 bit 4 ^ 3 = 64 analogRead and div by 2 ^ 3 = 8
// 12 bit to 16 bit 4 ^ 4 = 256 analogRead and div by 2 ^ 4 = 16
The comment describes oversampling.
It's not my problem if the code fails to implement it.
// 12 bit to 14 bit 4 ^ 2 = 16 analogRead and div by 2 ^ 2 = 4
// 12 bit to 15 bit 4 ^ 3 = 64 analogRead and div by 2 ^ 3 = 8
// 12 bit to 16 bit 4 ^ 4 = 256 analogRead and div by 2 ^ 4 = 16
The comment describes oversampling.
It's not my problem if the code fails to implement it.
Even the comments describe only averaging, and keeping several bits of noise to give the appearance of increased resolution (but it is still just noise...). Over-sampling requires sampling at a high sample rate, then applying extensive digital filtering to push the noise above the Nyquist limit so it doesn't affect the output.
Thanks for the many interesting good answers.
So I have not achieved anything.
I might as well do this
for(int n = 0; n < 256; n++)
{ Volt = Volt + analogRead(A0); }
Volt = Volt / 256;
I read this website so what he claims are not true.
Of course, be sure to backup your Print.cpp and Print.h files before replacing them with the new ones, and don't just rename them (for example, "oldPrint.cpp") because the Arduino IDE will find them and complain about duplicate definitions.