3

is it even possible to print a variable output with 4 digits before and one digit after decimal in serial monitor?

my pot reading is shown in the above output

value   -   1.2
value   -   51.5
value   -   61.8
value   -   546.6
value   -   255.0
value   -   1235.9

to this

value   -   0001.2
value   -   0051.5
value   -   0061.8
value   -   0546.6
value   -   0255.0
value   -   1235.9
6
  • There are some implementations of printf() kicking around in some libraries. If they are fully implemented you could use the command printf ("value - %04.1f\n", value); and that will give you 4 digits before the DP padded with zeros and one after the DP. – Code Gorilla Jun 7 '18 at 11:36
  • stdio sprintf and co. are build in, but without %f support. simplest is to code print of necessary count of zeros – Juraj Jun 7 '18 at 11:39
  • %f specified does not work with Arduino provided functions like snprintf. – Maximilian Gerhardt Jun 7 '18 at 11:40
  • @MaximilianGerhardt, those are AVR libraries, not Arduino. nongnu.org/avr-libc/user-manual/modules.html – Juraj Jun 7 '18 at 11:41
  • @Juraj Sorry I misread the comment. I somehow read that they are supported, not that they are not. my mistake. – Maximilian Gerhardt Jun 7 '18 at 11:43
3

You basiscally want a format string which includes %f. However on Arduino, that only returns a ? (not included to to space reasons). Refer to https://stackoverflow.com/q/27651012/5296568.

However the alternative is dtostrf (double-to-string-formatted). The function takes the double / float value, the total wanted width of the string and the decimal places you want to have.

However it fills the string with spaces to the left until the total width is met. You need an additional pass to replace it with 0.

#include <Arduino.h>

void setup(){
    Serial.begin(115200);

    const float vals[] = {
            1.2, 51.5, 61.8,
            546.6, 255.0,
            1235.9
    };

    //allocate 8 byte buffer
    //biggest string is "-9999.9\0" (with NUL)
    char buf[8];

    int numVals = (int) (sizeof(vals) / sizeof(*vals));

    for(int i=0; i < numVals; i++) {
        //format correctly
        dtostrf(vals[i], 4+1+1, 1, buf);

        //convert left-appended spaces to zeroes
        for(size_t j=0; j < sizeof(buf); j++){
            if(buf[j] == ' ')
                buf[j] = '0';
        }

        //print buffer
        Serial.println(buf);
    }
}


void loop() {
}

Prints

0001.2
0051.5
0061.8
0546.6
0255.0
1235.9

Edit: You can also offload it into a function and then feed it with the ADC values.

Example:

#include <Arduino.h>

void printValueFormatted(float value, int numDecimalPlaces, int totalWidth) {
    //format correctly
    char buf[16]; 
    //prevent buffer overflow
    if(totalWidth >= (int) sizeof(buf))
         return;
    dtostrf(value, totalWidth, numDecimalPlaces, buf);

    //convert left-appended spaces to zeroes
    for(size_t j=0; j < sizeof(buf); j++){
        if(buf[j] == ' ')
            buf[j] = '0';
    }

    //print buffer without newline
    Serial.print(buf);
}

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


void loop() {
    float val = analogRead(0);
    Serial.print("ADC Count: ");
    Serial.print(val);
    Serial.print("  -- Voltage: ");
    val = val * 5.0f / 1023.0f;
    printValueFormatted(val, 1, 4+1+1);
    //print newline
    Serial.println();
    delay(100);
}

Prints

ADC Count: 719.00  -- Voltage: 0003.5
ADC Count: 718.00  -- Voltage: 0003.5
7
  • What if i want to change the input analog value to this type of format! then what should I do? – Peouse Dutta Jun 7 '18 at 12:22
  • @PeouseDutta I updated the code a bit, do you understand now? – Maximilian Gerhardt Jun 7 '18 at 12:37
  • Yes that was very helpful. :) – Peouse Dutta Jun 7 '18 at 13:57
  • Why it is not working when I am printing it on a LCD? it is showing 13.800 instead of 0013.8 – Peouse Dutta Jun 8 '18 at 10:33
  • @PeouseDutta Can you pastebin the code you're running? – Maximilian Gerhardt Jun 8 '18 at 10:37
3
if(val < 1000){Serial.print('0');}
if(val < 100){Serial.print('0');}
if(val < 10){Serial.print('0');}
Serial.println(val, 1);
2
  • 4
    This is going to fail for values just under powers of 10. Consider 999.99 - that is indeed less than 1000, so a leading zero gets printed, but the value itself rounds to 1000.0 when limited to one digit after the decimal point. You end up with 01000.0, one character too many. (The idea would work just fine with integer values.) – jasonharper Jun 7 '18 at 14:40
  • As is, this isn't going to work. However, it does suggest a strategy of pre-converting to an integer type and a fraction, being careful to get those correctly rounded, and then printing them in an individually formatted manner. – Chris Stratton Jun 8 '18 at 13:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.