Float through Serial with more than 2 Digits

I hope Development is the right corner for this.
So, here is an easy way to print floats with more than 2 digits precision through Serial.
First open the file Print.h in your folder hardware/cores/arduino/ and add the following to the public functions of the class:

      void println(double,int);
      void print(double,int);

It should look like this:

class Print
{
  private:
    void printNumber(unsigned long, uint8_t);
    void printFloat(double, uint8_t);
  public:
    virtual void write(uint8_t) = 0;
    virtual void write(const char *str);
    virtual void write(const uint8_t *buffer, size_t size);
    void print(char);
    void print(const char[]);
    void print(uint8_t);
    void print(int);
    void print(unsigned int);
    void print(long);
    void print(unsigned long);
    void print(long, int);
    void print(double);
    void print(double,int); // New Method
    void println(void);
    void println(char);
    void println(const char[]);
    void println(uint8_t);
    void println(int);
    void println(unsigned int);
    void println(long);
    void println(unsigned long);
    void println(long, int);
    void println(double);
    void println(double,int); // New Method
};

Then add the following to Print.cpp:

void Print::print(double n,int prec)
{
  printFloat(n, prec);
}

void Print::println(double n,int prec)
{
  print(n,prec);
  println();
}

Now you can call Serial.println(FLOAT,INT) where INT is the desired precision.
Here is a short sketch that reads in the value of Analogpin 0, converts it to a Voltage between 0V and 5V and sends the value via Serial.

void setup(){
  Serial.begin(9600);
}


void loop(){
  float data=5*analogRead(0)/1023.;
  Serial.print(data);
  Serial.print(" ");
  Serial.println(data,4);
}

Hopefully someone may find this useful :wink:

Why did you declare the new functions taking doubles, when you then call printFloat which takes a float? A double that is outside the range of a float will not print properly.

Hi,

at this point the name of the function is not perfect. When you look into Print.h or Print.cpp you see that the printFloat-function expects indeed a double and not a float. So there should be no problems.

void printFloat(double, uint8_t);

A double that is outside the range of a float will not print properly

AVR/Arduino defines double as a float so mixing the two is not really an issue - at least with the current versions .

After a bit of testing i found a small problem. If you want to do something like this

  int test=123;
  Serial.print(test,BIN);

it won't compile because of an ambiguous call. The "dirty" way to fix this would be

  int test=123;
  Serial.print((long)test,BIN);

My other attemp to fix this is to add prototypes/functions for print(int,int) and println(int,int) by adding this to Print.h

void println(int,int); 
void print(int,int);

and this to Print.cpp

void Print::print(int n, int base)
{
 print((long)n,base);
}

void Print::println(int n, int base)
{
  print(n, base);
  println();
}

Now it will compile without an error, but i am not sure if this is the best way to fix this. Maybe someone knows a better way ;)

There's nothing "dirty" about an explicit cast. In this case, the cast is from a 2 byte type to a 4 byte type.

You could also use the long() function to perform the conversion.

In the Print::print overload that you added, you perform the same explicit cast. Why is that one OK, but not the cast in the function call in the pde?

With "dirty" i would like to say that it doesnt fit to the feeling of the rest of the Arduino IDE in my opinion. We are using the Arduino platform in an exercise attending a lecture at university and some of the students never did some programming with c (or another language). Then it would be simpler for them (and also for me ;) ) to not have to do an explicit cast but let the software do it automatically behind the scenes. Otherwise there would be some question why it is not working when they use print(int,int) and why it works when they just use print(int) ;) Ok, then i will continue to use it with the new Print::print overload and see if there are other problems.