Запрос Serial.print

возможно ли вообще вывести переменный вывод с 4 цифрами до и одной цифрой после десятичной точки в последовательном мониторе?

мои показания потенциометра показаны в выходных данных выше

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

к этому

value   -   0001.2
value   -   0051.5
value   -   0061.8
value   -   0546.6
value   -   0255.0
value   -   1235.9

, 👍3

Обсуждение

В некоторых библиотеках есть некоторые реализации printf(). Если они полностью реализованы, вы можете использовать команду printf ("value - %04.1f\n", value);, и это даст вам 4 цифры перед DP, дополненные нулями, и одну после DP., @Code Gorilla

stdio sprintf и другие встроены, но без поддержки %f. Самый простой — закодировать вывод необходимого количества нулей, @Juraj

Указанный %f *не* работает с функциями Arduino, такими как snprintf., @Maximilian Gerhardt

@MaximilianGerhardt, это библиотеки AVR, а не Arduino. http://nongnu.org/avr-libc/user-manual/modules.html, @Juraj

@Juraj Извините, я неправильно понял комментарий. Я как-то прочитал, что они *поддерживаются*, а не что нет. Моя ошибка., @Maximilian Gerhardt

Хотя библиотеки не являются библиотеками Arduino, решение о подключении полной или миниатюрной версии, не поддерживающей плавающую точку, *является* решением Arduino., @Chris Stratton


2 ответа


Лучший ответ:

3

Вам в принципе нужна строка формата, которая включает %f. Однако на Arduino это возвращает только ? (не включено из-за пробелов). См. https://stackoverflow.com/q/27651012/5296568.

Однако альтернативой является dtostrf (double-to-string-formatted). Функция принимает значение double / float, общую желаемую ширину строки и желаемое количество десятичных знаков.

Однако он заполняет строку пробелами слева, пока не будет достигнута общая ширина. Вам нужен дополнительный проход, чтобы заменить его на 0.

#include <Arduino.h>

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

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

    //выделяем 8-байтовый буфер
    //самая большая строка - "-9999.9\0" (с NUL)
    char buf[8];

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

    for(int i=0; i < numVals; i++) {
        //правильный формат
        dtostrf(vals[i], 4+1+1, 1, buf);

        //преобразовать пробелы слева в нули
        for(size_t j=0; j < sizeof(buf); j++){
            if(buf[j] == ' ')
                buf[j] = '0';
        }

        //буфер печати
        Serial.println(buf);
    }
}


void loop() {
}

Печатные издания

0001.2
0051.5
0061.8
0546.6
0255.0
1235.9

Изменить: Вы также можете выгрузить его в функцию, а затем передать ей значения АЦП.

Пример:

#include <Arduino.h>

void printValueFormatted(float value, int numDecimalPlaces, int totalWidth) {
    //правильный формат
    char buf[16]; 
    //предотвращаем переполнение буфера
    if(totalWidth >= (int) sizeof(buf))
         return;
    dtostrf(value, totalWidth, numDecimalPlaces, buf);

    //преобразовать пробелы слева в нули
    for(size_t j=0; j < sizeof(buf); j++){
        if(buf[j] == ' ')
            buf[j] = '0';
    }

    //печатайте буфер без новой строки
    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);
    //печать новую строку
    Serial.println();
    delay(100);
}

Печатные издания

ADC Count: 719.00  -- Voltage: 0003.5
ADC Count: 718.00  -- Voltage: 0003.5
,

А что, если я захочу изменить входное аналоговое значение на этот тип формата? Что мне делать?, @Peouse Dutta

@PeouseDutta Я немного обновил код, теперь вы понимаете?, @Maximilian Gerhardt

Да, это было очень полезно. :), @Peouse Dutta

Почему он не работает, когда я печатаю на ЖК-дисплее? показывает 13.800 вместо 0013.8, @Peouse Dutta

@PeouseDutta Можете ли вы вставить код, который вы запускаете?, @Maximilian Gerhardt

Я выложил весь код, посмотрите, @Peouse Dutta

@PeouseDutta Хорошо, поскольку это довольно длинно, я думаю, было бы лучше, если бы вы задали это как новый вопрос и удалили свой 'ответ' здесь (потому что это не ответ). Также включите то, что он печатает в последовательной консоли., @Maximilian Gerhardt


2
if(val < 1000){Serial.print('0');}
if(val < 100){Serial.print('0');}
if(val < 10){Serial.print('0');}
Serial.println(val, 1);
,

Это не сработает для значений, которые немного меньше степеней 10. Рассмотрим 999.99 — это действительно меньше 1000, поэтому печатается начальный ноль, но само значение округляется до 1000.0, если ограничиться одной цифрой после десятичной точки. В итоге вы получите 01000.0, на один символ больше. (Идея отлично подойдет для целочисленных значений.), @jasonharper

Как есть, это не сработает. Однако предлагается стратегия предварительного преобразования в целый тип и дробь, с осторожностью округляя их правильно, а затем печатая их в индивидуальном формате., @Chris Stratton