Как напечатать несколько строк в строке?

Скажем, у меня есть некоторые переменные, которые я хочу распечатать на терминале, что самый простой способ распечатать их в строке?

В настоящее время я делаю что-то вроде этого:

Serial.print ("Var 1:"); Serial.println (var1);
Serial.print («Var 2:»); Serial.println (var2);
Serial.print («Var 3:»); Serial.println (var3);

Есть ли лучший способ сделать это?

40 голосов | спросил sachleen 13 FebruaryEurope/MoscowbThu, 13 Feb 2014 23:22:59 +0400000000pmThu, 13 Feb 2014 23:22:59 +040014 2014, 23:22:59

10 ответов


34

ardprintf - это функция, которую я взломал вместе, которая имитирует printf по последовательному соединению. Эта функция (приведенная внизу) может быть вставлена ​​в начало файлов, где нужна функция. Он не должен создавать конфликтов.

Его можно назвать похожим на printf. Посмотрите его в действии в этом примере:

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

void loop ()
{
  int l = 2;
  char * j = "test";
  long k = 123456789;
  char s = 'g';
  float f = 2.3;

  ardprintf ("test% d% l% c% s% f", l, k, s, j, f);

  Задержка (5000);

}

Ожидаемый результат:

 test 2 123456789 g test 2.30

Прототип функции:

 int ardprintf (char *, ...);

Он возвращает количество аргументов, обнаруженных в вызове функции.

Это определение функции:

 #ifndef ARDPRINTF
#define ARDPRINTF
#define ARDBUFFER 16
#include <stdarg.h>
#include <Arduino.h>

int ardprintf (char * str, ...)
{
  int i, count = 0, j = 0, флаг = 0;
  char temp [ARDBUFFER + 1];
  for (i = 0; str [i]! = '\ 0'; i ++) if (str [i] == '%') count ++;

  va_list argv;
  va_start (argv, count);
  для (i = 0, j = 0; str [i]! = '\ 0'; i ++)
  {
    если (ул [я] == '%')
    {
      temp [j] = '\ 0';
      Serial.print (температура);
      J = 0;
      temp [0] = '\ 0';

      Переключатель (ул [++ я])
      {
        case 'd': Serial.print (va_arg (argv, int));
                  ломать;
        case 'l': Serial.print (va_arg (argv, long));
                  ломать;
        case 'f': Serial.print (va_arg (argv, double));
                  ломать;
        case 'c': Serial.print ((char) va_arg (argv, int));
                  ломать;
        case 's': Serial.print (va_arg (argv, char *));
                  ломать;
        по умолчанию:  ;
      };
    }
    еще
    {
      temp [j] = str [i];
      j = (j + 1)% ARDBUFFER;
      если (J == 0)
      {
        temp [ARDBUFFER] = '\ 0';
        Serial.print (температура);
        Темп [0] = '\ 0';
      }
    }
  };
  Serial.println ();
  return count + 1;
}
#undef ARDBUFFER
#endif

** Чтобы напечатать символ %, используйте %%. *


Теперь, доступный на Github gists .

ответил asheeshr 14 FebruaryEurope/MoscowbFri, 14 Feb 2014 08:16:45 +0400000000amFri, 14 Feb 2014 08:16:45 +040014 2014, 08:16:45
14

Обычно я не ставил два ответа на вопрос, но я только что нашел этот сегодня, где вы можете использовать printf без какого-либо буфера.

//Функция printf и связанная с ней печать
int serial_putchar (char c, FILE * f) {
    if (c == '\ n') serial_putchar ('\ r', f);
    return Serial.write (c) == 1? 0: 1;
}

FILE serial_stdout;

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

    //Настроить stdout
    fdev_setup_stream (& serial_stdout, serial_putchar, NULL, _FDEV_SETUP_WRITE);
    stdout = & serial_stdout;

    printf («Мое любимое число -% 6d! \ n», 12);
}

void loop () {
  статический длинный счетчик = 0;
  if (millis ()% 300 == 0) {
    printf ("millis ():% ld \ tcounter:% ld (% 02X) \ n", millis (), counter, counter ++);
    задержка (1);
  }
}

Это все еще имеет ограничение с плавающей запятой.

edit: Я думал, что немного поработаю над этим, и он работает очень хорошо. Я добавил лучший тест в цикл с форматированным выходом.

ответил Madivad 27 FebruaryEurope/MoscowbThu, 27 Feb 2014 08:22:01 +0400000000amThu, 27 Feb 2014 08:22:01 +040014 2014, 08:22:01
4

Это, вероятно, не лучше, просто другое. Вы можете использовать объект String для вывода. Эти объекты позволяют конкатенацию и поддерживают автоматическое типирование.

Serial.begin (9600);
Строковая метка = "Var";
const byte nValues ​​= 3;
int var [nValues] = {36, 72, 49};

for (int i = 0; i <nValues; i ++) {
    String stuff = label + i + ":";
    Serial.println (материал + var [i]);
}
ответил Klaus-Dieter Warzecha 14 FebruaryEurope/MoscowbFri, 14 Feb 2014 00:41:19 +0400000000amFri, 14 Feb 2014 00:41:19 +040014 2014, 00:41:19
4

Обычно я использовал вкладки, чтобы все стало лучше в Serial. Имея элементы, как я могу позволить arduino стрелять как можно быстрее, будучи в состоянии заметить определенные изменения в переменных.

Попробуйте что-то вроде этого:

Serial.println ("Var 1: \ tVar 2tVar 3:");
Serial.print ( "\ т");
Serial.print (var1);
Serial.print ( "\ т");
Serial.print (var2);
Serial.print ( "\ т");
Serial.print (var3);
Serial.println ();

Или что-то вроде этого:

Serial.print ("Var 1:"); Serial.println (var1);
Serial.print ("\ tVar 2:"); Serial.println (var2);
Serial.print ("\ tVar 3:"); Serial.println (var3);
ответил Steven10172 14 FebruaryEurope/MoscowbFri, 14 Feb 2014 11:19:56 +0400000000amFri, 14 Feb 2014 11:19:56 +040014 2014, 11:19:56
1

Обычно я (больно) придерживаюсь нескольких строк Serial.print, но когда он становится запутанным, я возвращаюсь к sprintf. Это раздражает то, что у вас должен быть доступный буфер для него.

Использование так же просто (??), как:

char buffer [35]; //вы должны знать, как долго ваши данные могут быть
                 //не забывая о непечатаемых и нулевых символах
Sprintf (буфер, "var1:% I \ tvar2:% I \ tvar3:% I", var1, var2, var3);
Serial.println (буфер);

Слово предупреждения, однако, не поддерживает (по умолчанию) поддержку плавающих типов.

ответил Madivad 27 FebruaryEurope/MoscowbThu, 27 Feb 2014 08:19:35 +0400000000amThu, 27 Feb 2014 08:19:35 +040014 2014, 08:19:35
1

Я использую это только для отладки, но:

int a = 10;
int b = 20;
Serial.println ("a =" + String (a) + "и b =" + String (b));
ответил linhartr22 29 J0000006Europe/Moscow 2018, 03:58:16
0

Используя Streaming.h вместо

Serial.print ("Var 1:"); Serial.println (var1);
Serial.print («Var 2:»); Serial.println (var2);
Serial.print («Var 3:»); Serial.println (var3);

можно написать

Serial <"Var 1:" <var1) <"Var 2:" <var2 <"Var 3:" <var3 <епсИ;

Определение < в Streaming.h, в сущности, переводит это в ряд обычных вызовов Serial.print () , То есть < представляет собой синтаксический сахар, реализованный без увеличения размера кода.

Если у вас нет установленного Streaming.h, получите Streaming5.zip из arduiniana.org . Разархивируйте его в каталог ваших библиотек, например, в ~ /sketchbook /libraries. Добавьте строку #include <Streaming.h> в эскизы, где вы используете << в качестве оператора потока.

Предусмотрены спецификаторы базового преобразования _HEX, _DEC, _OCT и _BIN, а также функция _FLOAT (с числом десятичных знаков) и endl. Например, для печати значений широты и долготы в форме «Ваши координаты: -23.123, 135.4567» можно написать:

Serial <«Ваши координаты« <<_FLOAT (широта, 3) <"," <_FLOAT (долгота, 4) <епсИ;

Это также можно записать как

Serial <F («Ваши координаты») <<_FLOAT (широта, 3) <"," <_FLOAT (долгота, 4) <епсИ;

, который сохранил бы более длинную строку в PROGMEM вместо того, чтобы вносить ее в ОЗУ.

Примечание, Streaming.h не создает никаких строк как таковых; он просто доставляет текст своих < -аргументов в поток. A класс PString на arduiniana может создавать строки из входов потока, если нужны строки вместо потокового вывода или необходимо.

ответил James Waldby - jwpat7 9 FebruaryEurope/MoscowbThu, 09 Feb 2017 20:19:47 +0300000000pmThu, 09 Feb 2017 20:19:47 +030017 2017, 20:19:47
0

Использование будет зависеть от типа данных ваших переменных.

Если они int, это будет % d или % i Если они string, это будет % s

Обертка для печати

Вы можете изменить лимит на основе ваших требований

 #include <stdarg.h>
void p (char * fmt, ...) {
    char buf [128]; //результирующая строка, ограниченная 128 символами
    va_list args;
    va_start (args, fmt);
    vsnprintf (buf, 128, fmt, args);
    va_end (args);
    Serial.print (BUF); //Результат вывода в Serial
}

Источник: https://playground.arduino.cc/Main/Printf

Примеры использования:

 p ("Var 1:% s \ nVar 2:% s \ nVar 3:% s \ n", var1, var2, var3); //строки
p ("Var 1:% d \ nVar 2:% d \ nVar 3:% d \ n", var1, var2, var3); //номера

ESP8266

Его встроенный в Serial класс фреймворка. Нет необходимости в дополнительной библиотеке или функции.

 //строки
Serial.printf ("Var 1:% s \ nVar 2:% s \ nVar 3:% s \ n", var1, var2, var3);
//номера
Serial.printf ("Var 1:% d \ nVar 2:% d \ nVar 3:% d \ n", var1, var2, var3);

Подробнее о советах по форматированию на странице справки формата printf: http: //www. cplusplus.com/reference/cstdio/printf/

\ n - это escape-последовательность для строки.

  

Последовательности Escape используются для представления определенных специальных символов в строковых литералах и символьных литералах.

Источник: http://en.cppreference.com/w/cpp/language /бежать

[EDIT] - Как отметил @Juraj, он недоступен на большинстве модулей AVR. Поэтому я добавил упоминание ESP8266 и оболочку printf для общих модулей AVR.

ответил Remi 20 J0000006Europe/Moscow 2018, 15:02:12
-1

От http://playground.arduino.cc/Main/Printf Я заметил, что это отлично работает на моем mega2560

Вот и все, что просто сработало, нет необходимости в vsnprintf_P или PROGMEM ...

 #include "Arduino.h"
void local_printf (const char * format, ...)
{
статическая линия счисления [80];
va_list args;
va_start (args, format);
int len ​​= vsnprintf (строка, sizeof (строка), формат, args);
va_end (арг);
для (char * p = & line [0]; * p; p ++) {
    if (* p == '\ n') {
        Serial.write ( '\ г');
    }
    Serial.write (* р);
}
if (len> = sizeof (строка))
    Serial.write ( '$');
}

void setup ()
{
Serial.begin (115200);
local_printf ("% s:% d:% s \ n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
}

void loop ()
{
static int count = 0;
local_printf ("% s:% d:% s% d \ n", __FILE__, __LINE__, __PRETTY_FUNCTION__, count ++);
задержка (1 * 1000);
}

//src /main.c: 24: void setup ()
//src /main.c: 30: void loop () 0
//src /main.c: 30: void loop () 1
ответил rzr 22 FebruaryEurope/MoscowbWed, 22 Feb 2017 03:04:25 +0300000000amWed, 22 Feb 2017 03:04:25 +030017 2017, 03:04:25
-3
int Money_amount = 55;

Serial.print (String («Новая сумма: $» + Money_amount));

Вы увидите на терминале:

Новая сумма: $ 55
ответил Michael Kushner 27 PMpFri, 27 Apr 2018 21:43:33 +030043Friday 2018, 21:43:33

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132