Arduino Serial.print () оптимизация - PullRequest
       33

Arduino Serial.print () оптимизация

2 голосов
/ 04 апреля 2011
unsigned long current_millis_value = 0;
unsigned long previous_millis_value = 0;
unsigned long m = 0;
unsigned int seconds = 0;
unsigned int minutes = 0;
unsigned int hours = 0;

unsigned long clockTimeStart = 1800000; //30 Minutes
unsigned long currentClockTime;

void loop() {
    current_millis_value = millis();
    currentClockTime -= current_millis_value - previous_millis_value;
    previous_millis_value = current_millis_value;

    minutes = (currentClockTime / 1000 / 60);
    seconds = (currentClockTime / 1000) % 60;
    m = (currentClockTime % 100);

    Serial.print(minutes);
    Serial.print(":");
    Serial.print(seconds);
    Serial.print(":");
    Serial.println(m);
}

Я получаю разрыв во времени между последовательными записями где-то от 9-11 мс на последовательную записанную строку.Есть ли способ оптимизировать метод Serial.print(), чтобы разрешить запись нескольких значений для типов значений long и String?

Пример (это недопустимо, но в соответствии с тем, что я думаю):

Serial.print(minutes + ":" + seconds + ":" + m);

Я знаю, что это не JavaScript, в котором я работаю - просто ищу возможности оптимизации для процесса написания.Я знаю, что MOD может быть дорогим, но простое вычитание и запись значения currentClockTime оставляет мне время разрыва 6-7 мс.

Ответы [ 5 ]

4 голосов
/ 04 апреля 2011

У Arduino есть конкатенация строк в стиле Java. Я понятия не имею, ускорит ли это вас, но объединит все в одну строку перед отправкой.

String package = "" + minutes;
package += ":"+seconds;
package += ":"+m;
Serial.print(package);

Если вам удастся восстановить строку на другой стороне, возможно, лучший способ - использовать Serial.Write и отправить необработанные данные, а затем восстановить строку на принимающей стороне. Это уменьшит объем данных, отправляемых каждым циклом, с 5-10 байтов до 3-4 байтов.

3 голосов
/ 09 мая 2011

Библиотека Streaming должна делать то, что вы хотите:

Serial << minutes << ":" << seconds << ":" << m;
2 голосов
/ 04 апреля 2011

Любой способ предварительно преобразовать все в строковое значение, чтобы вы могли выписать всю строку сразу? Например, используйте что-то вроде snprintf() функции, чтобы записать в заранее выделенный char[], который вы затем распечатываете за один вызов Serial.print()?

Так, например:

char buffer[32];
snprintf(buffer, 32, "%u : %u : %lu", minutes, seconds, m);
Serial.print(buffer);

- Jason

0 голосов
/ 16 сентября 2014

Самый быстрый и предпочтительный способ объединения строк в Arduino:

  • Используйте класс String.
  • Если вам действительно нужна скорость и / или вы просто хотите избежать созданияновые строки в памяти с каждой операцией конкатенации, резервируют необходимую память заранее с помощью reserve () .
  • Сначала установите для объекта пустую строку "".
  • Затем добавьте необходимые символы или строки, вызвав concat () или оператор + =, , используя ровно одну операцию concat () или + = на строку кода .Это сделано для того, чтобы избежать создания временных объектов Strings.
  • За счет предварительного выполнения Reserve () объект String будет эффективно действовать в качестве строкового буфера.

Применяя вышеизложенноерекомендации, операции конкатенации будут выполняться на месте .

Обратите внимание, что для функции import () должно быть выбрано наиболее подходящее значение для емкости буфера строки, то есть: максимальное количество символов, которое вам нужноперед String выполняет realloc (), не включая завершающий ноль символ '\ 0'.

Далее следуют три альтернативы:

1) Вот пример кода:

// Declaration, outside setup() and loop()
String line;

// Inside setup()
// Use the appropriate value for reserve(), depending on on your actual usage.
line.reserve(10);

// Inside loop()
line = "";
line += minutes;
line += ":";
line += seconds;
line += ":";
line += m;
Serial.println(line);

2) В качестве альтернативы вызову reserve () в setup (), вы можете объявить и инициализировать строку с помощью «шаблона» или фиктивной строки, которая имеет желаемую (максимальную) длину.

Здесьпример кода для этой альтернативы,

// Declaration, outside setup() and loop()
String line = "XXXX:YY:ZZ";

// No need to use reserve() inside setup()

// Inside loop()
line = "";
line += minutes;
line += ":";
line += seconds;
line += ":";
line += m;
Serial.println(line);

Первый подход позволяет вам использовать Reserve () с динамически рассчитанным значением максимальной длины, тогда как второй подход приводитв некоторой степени лучше читать код, когда у вас есть «шаблон» или известная фиксированная длина строки, которую вы будете составлять позже.

3) Если вам нужно только вывести данные в выходной поток(обычно последовательный), это самый быстрый и самый компактный код, без необходимости использования String или внешних библиотек,

// No need to declare a String outside setup() and loop()
// No need to use reserve() inside setup()

// Inside loop()
Serial.print(minutes);
Serial.print(":");
Serial.print(seconds);
Serial.print(":");
Serial.println(m);

Примечание: ответ Джона Y точно такой же, как мой последнийкусок кода, за исключением его «более простого» для чтения кода (при условии, что вы чувствуете себя комфортно с оператором <<, используемым в качестве C ++ потокового синтаксического сахара).В некоторых случаях, однако, использование библиотеки потоковой передачи приведет к созданию немного большего или более медленного кода. </p>

0 голосов
/ 11 декабря 2013

Я нашел самый простой способ последовательной печати одной строки, состоящей из целых чисел и ваших слов (сообщение):

в кармане:

int w = 12;

Serial.Print ("my number is: ");

Serial.Print (w);

Serial.Println (" - which is to be used in calculation!"

РЕЗУЛЬТАТ:

На последовательном мониторе вы увидите (в виде одной ЛИНИИ !!!!!!!!!!):

мой номер: 12 - который будет использоваться в расчете!

...