Как ускорить работу с последовательным портом?

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

В любой момент времени по двум проводам могут поступить команды, которые необходимо обработать и молниеносно отправить ответ.

Сначала пользовался SoftwareSerial, но там максимальная скорость ограничена 9600, соответственно, всё жутко тормозило. Вдовесок некоторые байты терялись, либо перемешивались, что приводило к глюкам.

Перешёл на "железный" Serial, где можно поднять скорость до 112500 - сразу заметил прибавку в скорости работы, тем не менее, хотелось бы меньшей задержки.

Я не совсем понимаю, как работает порт, но в теории цикл программы должен прерываться как только приходят байты с порта. По факту этого нет, пока писал, подумал, что как раз задержка в 20мс всё и портит. Но именно такая задержка и нужна мне в основной программе (мне надо выполнять цикл каждые 20 мс)

Для наглядности цикл loop (не буду писать начало программы для более быстрого восприятия). Что я делаю не так?

 
void loop() {
  if (millis() - myTimer >= 20) {
    myTimer = millis();
    if (Serial.available()) {
      byte inc = Serial.read();
      if (inc != 0x0A){
        data += String(inc);//добавляем полученный с порта байт в строку
      } else{
        // получили в переменную data само сообщение с порта, отправляем ответ
        String mval = data.substring(data.indexOf(" ",12)+1,data.indexOf(" ",14));
        Serial.print("t2.txt=\"");
        Serial.print(mval);    //00
        Serial.print("\"");
        Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF);
        data = "";
      }
      inc == 0x0A;
    }
  }
}
rkit
Offline
Зарегистрирован: 23.11.2016

Задержка между циклом основной программы связь замедлять не должна - это, наоборот, время, когда связь можно спокойно обработать.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

и что должен делать вышеприведенный огрызок авнакода?

Logik
Offline
Зарегистрирован: 05.08.2014

/// что как раз задержка в 20мс всё и портит.

Да.

///Но именно такая задержка и нужна мне в основной программе (мне надо выполнять цикл каждые 20 мс)

Мозги включи. Если в морозилке -18С это не значить что вся хата должна замерзнуть.

b707
Offline
Зарегистрирован: 26.05.2017

andreykrasnodar пишет:

подумал, что как раз задержка в 20мс всё и портит. Но именно такая задержка и нужна мне в основной программе (мне надо выполнять цикл каждые 20 мс)

вы определитесь - вам нужна "максимально быстрая реакция" или " надо выполнять каждые 20 мс" - это как бы два взаимно противоречащих условия :)

И да, код - авно ^)

sadman41
Offline
Зарегистрирован: 19.10.2016

Nextion-ом пахнет...

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

rkit пишет:

Задержка между циклом основной программы связь замедлять не должна - это, наоборот, время, когда связь можно спокойно обработать.

Ниже вам (и моему коду) противоречат, советуя включить мозги.

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

DetSimen пишет:

и что должен делать вышеприведенный огрызок авнакода?

Побайтно прочитать данные из порта, записать эту строку в data, взять оттуда нужное мне значение и отправить "обратно" в виде "t2.txt="значение" плюс три непечатаемых символа.

sadman41
Offline
Зарегистрирован: 19.10.2016

Может глупость спрошу - обратно-то зачем отправлять? Внутри самого дисплея не перекидывается?

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Logik пишет:

/// что как раз задержка в 20мс всё и портит.

Да.

///Но именно такая задержка и нужна мне в основной программе (мне надо выполнять цикл каждые 20 мс)

Мозги включи. Если в морозилке -18С это не значить что вся хата должна замерзнуть.

Спасибо. Мозг включён, знаний не хватает. Подскажите, как лучше сделать (ниже 2 варианта):

1. Уменьшить задержку с 20 до 1, попутно введя переменную-счётчик, инкрементировать каждый цикл и выполнять нужные действия при достижении счётчиком значения 20, а затем сбрасывать его

2. Код обработки данных с Serial поместить до if(...mills), тем самым, как я вижу, он будет обрабатываться каждый цикл, а сам код программы, обёрнутый в mills, будет выполняться каждые 20 мс.

b707
Offline
Зарегистрирован: 26.05.2017

andreykrasnodar пишет:

Ниже вам (и моему коду) противоречат, советуя включить мозги.

ты просто нифига не понял. мозги советуют включить тебе. а ты ркита учить вздумал.

Если ответ на строчку в Сериале нужно обработать НЕМЕДЛЕННО, что она у тебя делает внутри цикла в задержкой...?

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

b707 пишет:

andreykrasnodar пишет:

подумал, что как раз задержка в 20мс всё и портит. Но именно такая задержка и нужна мне в основной программе (мне надо выполнять цикл каждые 20 мс)

вы определитесь - вам нужна "максимально быстрая реакция" или " надо выполнять каждые 20 мс" - это как бы два взаимно противоречащих условия :)

И да, код - авно ^)

Я спрашиваю как реализовать.

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

b707 пишет:

И да, код - авно ^)

Там всего 20 строк, что можно в них написать не так? Как бы сделали вы?

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

sadman41 пишет:
Может глупость спрошу - обратно-то зачем отправлять? Внутри самого дисплея не перекидывается?

Я привёл облегчённый вариант, где ничего не обрабатывается, а просто обратно цифра "закидывается" - и то меня спросили, что этот код делает. Если б я написал весь код, да ещё, как выразились тут - "авно", у участников мозг закипел бы.

b707
Offline
Зарегистрирован: 26.05.2017

andreykrasnodar пишет:

Там всего 20 строк, что можно в них написать не так?

изощренные программист и в одной строке может сделать десяток ошибок :)

например - вот ты строчку получаешь, извлекаешь поле после 12-ого символа, отправляешь обратно...

И даже не предполагаешь. что строчка может оказаться короче...

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

b707 пишет:

и ответ на строчку в Сериале нужно обработать НЕМЕДЛЕННО, что она у тебя делает внутри цикла в задержкой...?

Выше - два варианта. Какой из них предпочтительней?

b707
Offline
Зарегистрирован: 26.05.2017

andreykrasnodar пишет:

b707 пишет:

и ответ на строчку в Сериале нужно обработать НЕМЕДЛЕННО, что она у тебя делает внутри цикла в задержкой...?

Выше - два варианта. Какой из них предпочтительней?

разве из моей же, процитированной тобой выше фразы - не ясно ? :)

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

b707 пишет:

andreykrasnodar пишет:

Там всего 20 строк, что можно в них написать не так?

изощренные программист и в одной строке может сделать десяток ошибок :)

например - вот ты строчку получаешь, извлекаешь поле после 12-ого символа, отправляешь обратно...

И даже не предполагаешь. что строчка может оказаться короче...

Честно - не предполагаю, это выше я и называю "глюком", когда часть байтов пропадает.

b707
Offline
Зарегистрирован: 26.05.2017

andreykrasnodar пишет:

это выше я и называю "глюком", когда часть байтов пропадает.

нет, байты пропадают не от этого

sadman41
Offline
Зарегистрирован: 19.10.2016

№2 предпочтительней, а inc == 0x0A; - бессмыслица.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

andreykrasnodar пишет:
SoftwareSerial, но там максимальная скорость ограничена 9600
Вас обманули. Можно гораздо больше.

andreykrasnodar пишет:
Перешёл на "железный" Serial, где можно поднять скорость до 112500
Вас опять обманули. Можно гораздо больше.

Только Вам всё это не поможет.

До тех пор, пока Вы сами не поймёте, что именно Вам нужно - отвечать как можно быстрее или раз в 20мс, Вам не поможет никто и ничто.

 

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

b707 пишет:

andreykrasnodar пишет:

b707 пишет:

и ответ на строчку в Сериале нужно обработать НЕМЕДЛЕННО, что она у тебя делает внутри цикла в задержкой...?

Выше - два варианта. Какой из них предпочтительней?

разве из моей же, процитированной тобой выше фразы - не ясно ? :)

Нет. Давайте я приведу исправленный код, вы скажете - это верно или нет?

void loop() {
    if (Serial.available()) {
      byte inc = Serial.read();
      if (inc != 0x0A){
        data += String(inc);//добавляем полученный с порта байт в строку
      } else{
        // получили в переменную data само сообщение с порта, отправляем ответ
        String mval = data.substring(data.indexOf(" ",12)+1,data.indexOf(" ",14));
        Serial.print("t2.txt=\"");
        Serial.print(mval);    //00
        Serial.print("\"");
        Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF);
        data = "";
      }
    }

  if (millis() - myTimer >= 20) {
    myTimer = millis();
    // а тут пишу основной код программы с вычислениями и опросами датчиков
  }
}

 

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

b707 пишет:

andreykrasnodar пишет:

это выше я и называю "глюком", когда часть байтов пропадает.

нет, байты пропадают не от этого

Так я не писал от чего именно они пропадают, а вы пишете "не от этого". Если интересно моё мнение, то это пришельцы-байтоеды их воруют, но мне наплевать.

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

sadman41 пишет:

а inc == 0x0A; - бессмыслица.

Почему?

sadman41
Offline
Зарегистрирован: 19.10.2016

Подумайте, что означает это выражение.

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Ниже ответ

sadman41
Offline
Зарегистрирован: 19.10.2016

Это сами придумали или подсказал кто?

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

sadman41 пишет:

Подумайте, что означает это выражение.

Понял, про какую вы строку. И правда, можно было бы написать хоть 0x00, хоть ""

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

andreykrasnodar пишет:

И правда, можно было бы написать хоть 0x00, хоть ""

Мда. 

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

DetSimen пишет:

Мда. 

 

Да уж...

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Давайте уже по теме. Код выше, сообщение 21.

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

TeodorNetto
TeodorNetto аватар
Offline
Зарегистрирован: 03.06.2021

Они тут все такие. 

b707
Offline
Зарегистрирован: 26.05.2017

andreykrasnodar пишет:

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

так и тут так же :)

Никто код тебе писать не будет. не жди... ибо не умеем, теоретики все.

TeodorNetto попроси, он умеет

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

b707 пишет:

andreykrasnodar пишет:

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

так и тут так же :)

Никто код тебе писать не будет. не жди... ибо не умеем, теоретики все.

TeodorNetto попроси, он умеет

Так мне писать код не надо, он написан мною.

Про теоретиков смешно. Это как среди парашютистов рассказывать, что прыгал с 5000 км, а на вопрос о скорости падения вычислить её по формуле, внести поправки на сопротивление - и всем станет ясно, что человек никогда не прыгал.

b707
Offline
Зарегистрирован: 26.05.2017

andreykrasnodar пишет:

Так мне писать код не надо, он написан мною.

да, припоминаю...

inc == 0x0A;

если код писать умеешь, не понятно в чем вопрос тогда. На ошибки тебе указали.

 

Logik
Offline
Зарегистрирован: 05.08.2014

andreykrasnodar пишет:

Logik пишет:

/// что как раз задержка в 20мс всё и портит.

Да.

///Но именно такая задержка и нужна мне в основной программе (мне надо выполнять цикл каждые 20 мс)

Мозги включи. Если в морозилке -18С это не значить что вся хата должна замерзнуть.

Спасибо. Мозг включён, знаний не хватает. Подскажите, как лучше сделать (ниже 2 варианта):

1. Уменьшить задержку с 20 до 1, попутно введя переменную-счётчик, инкрементировать каждый цикл и выполнять нужные действия при достижении счётчиком значения 20, а затем сбрасывать его

2. Код обработки данных с Serial поместить до if(...mills), тем самым, как я вижу, он будет обрабатываться каждый цикл, а сам код программы, обёрнутый в mills, будет выполняться каждые 20 мс.

Приятно удивлен, можешь же если хочешь!

Оба варианта абсолютно рабочие.

Первый намного сильней, я так делаю всегда. Потому что счетчиков можно кучу накидать и получить все времена для проги. И других плюсов там много. Ну а цифры 1мс, или 0,1 или 100 - по ситуации, чтоб лооп успевал.

Второй на форуме чаще встречается.

b707
Offline
Зарегистрирован: 26.05.2017

Logik пишет:

Первый намного сильней, я так делаю всегда. Потому что счетчиков можно кучу накидать и получить все времена для проги.

нафига куча счетчиков. если есть миллис? любые "времена для проги" обеспечивает :)

lilik
Offline
Зарегистрирован: 19.10.2017

andreykrasnodar пишет:

Про теоретиков смешно. Это как среди парашютистов рассказывать, что прыгал с 5000 км, а на вопрос о скорости падения вычислить её по формуле, внести поправки на сопротивление - и всем станет ясно, что человек никогда не прыгал.

Ужас!!! С 5000 км! В скафандре?

Скорость падения (я не прыгал) 5 м/c или 50, как кому повезёт.

А вообще == это совсем не = 

Тоска.

lilik
Offline
Зарегистрирован: 19.10.2017

Как альтернатива надругательствам над непорочностью.

https://alexgyver.ru/lessons/parsing/

Logik
Offline
Зарегистрирован: 05.08.2014

b707 пишет:

Logik пишет:

Первый намного сильней, я так делаю всегда. Потому что счетчиков можно кучу накидать и получить все времена для проги.

нафига куча счетчиков. если есть миллис? любые "времена для проги" обеспечивает :)

А ты как ТС, мозги включи и сравни два варианта в подробностях, для сложных случаев, когда много событий должны следовать в правильном порядке и соблюдать времена между ними.

b707
Offline
Зарегистрирован: 26.05.2017

Logik пишет:

А ты как ТС, мозги включи и сравни два варианта в подробностях, для сложных случаев, когда много событий должны следовать в правильном порядке и соблюдать времена между ними.

Если "много событий в правильном порядке" - возможно счетчики удобнее. Но только без учета времени. Времена без таймера неудобно.

 

Logik
Offline
Зарегистрирован: 05.08.2014

Что там "не удобно"?  По ресету пусть счетчик в нуле, инкрементится каждые 5 миллисекунду, пишем свич по нему 0..2 - ниче не делаем, после ресета сразу, 3 - опросил первый датчик, 5- второй, 6,7,8 - опрос кнопки, чтоб дребезг не морочил, 10 - запрос отправили на сервер 11-15 проверяем ответ, 16 - сервер не ответил, 20- дошли до границы периода счетчик присваиваем 0 И второму счетчику делаем +1 для других задач. Попробуй то же на миллисах )) Что удобней? А счетчиков может быть много, на разные интервалы...

b707
Offline
Зарегистрирован: 26.05.2017

Logik пишет:

Попробуй то же на миллисах )) Что удобней?

не вижу разницы. честно говоря. Миллис - ровно такой же счетчик,

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

Logik пишет:

Первый намного сильней, я так делаю всегда. 

Но ведь тут получаем задержку в 1 мс. Не будет ли тормозить процесс?

Хотя... что я спрашиваю - надо пробовать. Другое дело, что теория и практика расходятся, например, иногда на практике идёт потеря байта - в некоторых случаях будет критично.

andreykrasnodar
Offline
Зарегистрирован: 04.10.2020

lilik пишет:

Ужас!!! С 5000 км! В скафандре?

Без. Почитайте про эти прыжки.

b707
Offline
Зарегистрирован: 26.05.2017

andreykrasnodar пишет:

теория и практика расходятся, например, иногда на практике идёт потеря байта

значит с твоей теорией что-то не так...

lilik
Offline
Зарегистрирован: 19.10.2017

andreykrasnodar пишет:

lilik пишет:

Ужас!!! С 5000 км! В скафандре?

Без. Почитайте про эти прыжки.

Быть такого не может :-)

Где читать?

lilik
Offline
Зарегистрирован: 19.10.2017

Этот? Высота маловата, мне кажется.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andreykrasnodar пишет:

Про теоретиков смешно. Это как среди парашютистов рассказывать, что прыгал с 5000 км, а на вопрос о скорости падения вычислить её по формуле, внести поправки на сопротивление - и всем станет ясно, что человек никогда не прыгал.

прыгнуть с 5000 км можно, только сколько столетий до земли лететь будешь )))
А вот на Эльбрус прыгнул Мекер Балаев

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

andreykrasnodar пишет:

lilik пишет:

Ужас!!! С 5000 км! В скафандре?

Без. Почитайте про эти прыжки.

Я бы почитал, только нет таких прыжков в природе :-(

Мировой рекорд - 40км.

А 5000 км. ... похоже, о прыжках Вы знаете ещё меньше, чем о программировании :-(

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

lilik пишет:

 

тот? Высота маловата, мне кажется.

Раз в десять!