Пожиратель времени Serial.print().

Piskunov
Offline
Зарегистрирован: 13.02.2014

Пытаюсь решить задачу, в которой есть некоторое ограничение на время выполнения одного цикла loop().

И, конечно, программа не обходится без выдачи сообщений. После нескольких неудачных попыток появилась мысль измерить время выполнения ... выдачи сообщений в порт. И тут я сильно удивился - 34 миллисекунды!!! Это уже больше половины того, во что я хотел уложится.

Подскажите, пожалуйста, как можно уменьшить время???

unsigned long prevMicros = 0;
void setup() 
{
         Serial.begin (9600);
         pinMode (LED_BUILTIN, OUTPUT);
}
void loop() 
{
         // запоминаем текущее значение времени
         prevMicros = micros();
         // мигаем встроенным светодиодом
         digitalWrite(LED_BUILTIN, millis() % 1000UL / 500UL);
         // выводим время выполнения одного цикла
         Serial.print ("The execution time of one cycle: ");
         Serial.print (micros() - prevMicros);
         Serial.println (" uS");
}

 

maksim
Offline
Зарегистрирован: 12.02.2012

Для начала можно увеличить скорость передачи данных Serial.begin(115200);

The execution time of one cycle: 2804 uS

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

Vладимир
Offline
Зарегистрирован: 27.01.2015

если возможно то отправлять данные в порт короткими  частями ,

если приемная и передающая часть пишется вами , то нужно полностью отказатся от текстовых данных , заменив их числовыми (по типу кодов ошибок) 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

maksim пишет:

Для начала можно увеличить скорость передачи данных Serial.begin(115200);

Или даже больше..... Если есть чем принимать.....
Проверял RealTerm-ом на 921600 прекрасно работает

Да, да, именно      Serial.begin(921600);

Жалко в ИДЕ такую скорость не выставить. ( 115200 у меня просто в default забита.)

 

Piskunov
Offline
Зарегистрирован: 13.02.2014

maksim пишет:

Для начала можно увеличить скорость передачи данных Serial.begin(115200);

The execution time of one cycle: 2804 uS

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

Получилось по-дурацки, но зато очень быстро:

unsigned long prevMicros = 0;
char msg[] = "The execution time of one cycle: ";
int i = 0;
void setup() 
{
         Serial.begin (9600);
         pinMode (LED_BUILTIN, OUTPUT);
}
void loop() 
{
         // запоминаем текущее значение времени
         prevMicros = micros();
         // мигаем встроенным светодиодом
         digitalWrite(LED_BUILTIN, millis() % 1000UL / 500UL);
         // выводим время выполнения одного цикла
         if (msg[i]) {
               Serial.print (msg[i]);
               i++;
         } else {
               i = 0;
               Serial.print (micros() - prevMicros);
               Serial.println (" uS");
         }
}

И ещё, подскажите где можно почитать про "свой неблокирующий Serial.print()"?

maksim
Offline
Зарегистрирован: 12.02.2012

Занялся писать портянку как это можно сделать и заглянул в исходники Serial, а оказывается, там уже все и есть, то есть Serial.print() и так неблокирующая. А проблема ваша в том, что вы формируете больше данных, чем можно передать за этот промежуток времени, буфер заполняется и начинается ожидание. Если же формировать меньше данных, чем можно передать, то Serial.print() работает быстро:

The execution time of one cycle: 904 uS

достаточно в ваш пример добавить задержку:

void loop() 
{
  // запоминаем текущее значение времени
  prevMicros = micros();
  // мигаем встроенным светодиодом
  digitalWrite(LED_BUILTIN, millis() % 1000UL / 500UL);
  // выводим время выполнения одного цикла
  Serial.print ("The execution time of one cycle: ");
  Serial.print (micros() - prevMicros);
  Serial.println (" uS");
  delay(1000);
}

 

Piskunov
Offline
Зарегистрирован: 13.02.2014

maksim пишет:

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

Спасибо!

Сам я чего-то не допёр ))