Скорость виртуального COM порта для Arduino Nano с CH341

SergeiSX
Offline
Зарегистрирован: 02.10.2018
void setup() {
  // put your setup code here, to run once:
  Serial.begin(1000000); // Устанвливаем высокую скорость

}

unsigned long t0;
unsigned long t1;
String s = "This is test String 123";
String s2 = "This is test String2";
String sCmd = "";
char c;
void loop() {
  // put your main code here, to run repeatedly:

  // Прием - ответная передача. Режим минимальной обработки

  if(Serial.available() > 1) // Если есть символы
  {
    t0 = micros();
    sCmd = Serial.readStringUntil('\xa');  // Принимаем строку

    t1 = micros();    
    Serial.print("Recevice time:");
    Serial.println(t1 - t0);    
    
    t0 = micros();
    Serial.print(sCmd + "\xa"); // Передаем обратно
    
    Serial.flush(); // Ждем окончания передачи
    t1 = micros();    
    Serial.print("Send time:");
    Serial.println(t1 - t0);    
  }
  
    
}

Здравствуйте! Начал работать с ардуино недавно. Сейчас использую Arduino Nano с китайской микросхемой преобразователя COM-USB CH341. При этом пытаюсь использовать для обмена между программой на компьютере и программой в плате виртуальный COM порт на задаваемой скорости до 2000000 бод. Но скорость обмена с программой на компьютере все равно не превышает 18 кбайт в секунду. Вывожу время одной операции при посылке данных через функцию Serial.println и при приеме данных через Serial.ReadStringUntil. Программа приведена выше. Вот ее результаты для одного символа и для группы символов:

SergeiSX
Offline
Зарегистрирован: 02.10.2018

Извините, вопрос не задал. Хотел спросить, что я делаю неправильно? Почему скорость обмена так далека от теоретической для данной заданной скорости в 1000000 бод или 2000000 бод?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А Вы уверены, что COM-порт Ардуины способен работать на скоростях порядка 1-2 Мбит?

Datak
Offline
Зарегистрирован: 09.10.2014

SergeiSX пишет:

Почему скорость обмена так далека от теоретической для данной заданной скорости в 1000000 бод или 2000000 бод?

По моим подсчётам, "Send time:158" соответствует не 18 кбайт в секунду, а примерно 58 - то есть, почти 600000 бод.

Нормальный результат для ардуины, я считаю. А если хочется полной теоретически возможной скорости - это наверно уже осциллографом смотреть, и выяснять где именно возикают паузы.

Вполне может быть, виноватым окажется даже не ардуино, а компьютер. Во всяком случае, я бы для начала проверил скорость передачи/приёма компом при работе "на себя", т.е. через просто замкнутые контакты RX и TX, без всякой ардуины, вообще.

SergeiSX
Offline
Зарегистрирован: 02.10.2018

Спасибо за ответы! Но понимаете, осциллограф здесь поможет разве что для внешнего порта. А я работаю через USB то есть порт то виртуальный. И к скорости посылки у меня нет претензий, проблема как раз в скорости приема от компьютера. И пожалуй Вы правы, скорее всего это компьютер. Но почему виртуальный порт компьютера через USB не может обеспечить скорость непонятно... Еще раз спасибо ! Вопрос как проверить максимальную скорость виртуального COM порта через USB на компьютере ??? 

Datak
Offline
Зарегистрирован: 09.10.2014

SergeiSX пишет:

осциллограф здесь поможет разве что для внешнего порта. А я работаю через USB то есть порт то виртуальный

А, да, это я не додумал. Насчёт обойтись совсем без ардуино это я зря - CH340 ведь стоит именно в ардуино. ))

Но всё равно, смысл эксперимента понятен - исключить влияние микроконтроллера, и узнать на какой скорости работает сам компьютер.

Насколько я понимаю, для этого нужно подать на ардуино сигнал RESET (постоянно), чтобы контроллер "отпустил" ноги RX/TX, и потом просто соединить эти RX и TX перемычкой.

Я не утверждал, что виноват именно комп - просто, если уж искать причину, так надо проверить всё что можно.

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

andriano пишет:

А Вы уверены, что COM-порт Ардуины способен работать на скоростях порядка 1-2 Мбит?

Несколько лет назад работало, проверял 921600 реалтермом (Realterm).
По крайней мере данные передавались и не терялись.....

SergeiSX
Offline
Зарегистрирован: 02.10.2018

А на самом деле дело еще печальнее. Я попробовал слать сообщения не из серии байт а из одного байта и мерять время пересылки в программе на компьютере. Скорость получилась вообще ужасной... около 2 кбайт в секунду. Тут точно, или я что - то не так делаю, или китайская ардуино нано не может больше. То есть что 1 байт что 16 передавать за раз скорость меняется не пропорционально.... Интересно, а можно как то два компьютера соединить через виртуальный ком порт по USB или лучше по Eithernet попробовать?

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

SergeiSX пишет:

А на самом деле дело еще печальнее. Я попробовал слать сообщения не из серии байт а из одного байта и мерять время пересылки в программе на компьютере. Скорость получилась вообще ужасной... около 2 кбайт в секунду. То есть что 1 байт что 16 передавать за раз скорость меняется не пропорционально....

Вы прям Америку открыли :) Практически не существует протоколов, где передача 1 байта будет происходить с той же скоростью, как и серии. Да, кстати, это не только к  байтам относится :) - передача одного ли яблока, ящика или тонны яблок из Петербурга в Казань тоже занимает примерно одинаковое время, вовсе не пропорциональное количеству :)

Аналогия понятна?

SergeiSX
Offline
Зарегистрирован: 02.10.2018

b707 пишет:

SergeiSX пишет:

А на самом деле дело еще печальнее. Я попробовал слать сообщения не из серии байт а из одного байта и мерять время пересылки в программе на компьютере. Скорость получилась вообще ужасной... около 2 кбайт в секунду. То есть что 1 байт что 16 передавать за раз скорость меняется не пропорционально....

Вы прям Америку открыли :) Практически не существует протоколов, где передача 1 байта будет происходить с той же скоростью, как и серии. Да, кстати, это не только к  байтам относится :) - передача одного ли яблока, ящика или тонны яблок из Петербурга в Казань тоже занимает примерно одинаковое время, вовсе не пропорциональное количеству :)

Аналогия понятна?

На совсем, по идее пересылка одного байта должна быть побыстрее ))) Мягко говоря. Иначе при чем тут 1 мегабит заявленной скрости? Вопрос только в том что реально тормозит так сильно, ардуино или же виртуальный порт на компьютере. И тогда вопрос почему порция данных пересылается не пропорционально медленее одного данного ??? Это что, логика такая у виртуального COM порта ?? А что ж тогда делать если надо слать короткие сообщения но часто???

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

SergeiSX пишет:

 вопрос почему порция данных пересылается не пропорционально медленее одного данного ??? Это что, логика такая у виртуального COM порта ?? А что ж тогда делать если надо слать короткие сообщения но часто???

Какие однако вы наивные вопросы задаете... не программист что ли?

Куча коротких сообщений ВСЕГДА передается значительно медленнее, чем одно длинное суммарной длины. В любом протоколе есть "накладные расходы" - заголовки пакетов, служебная информация.  Вы думаете, что передали 1 байт, а компьютер для этого отправил в линию еще пятьдесят. И так ДЛЯ КАЖДОГО пакета, независмо от длины. В итоге для 1 байта передается 51, для 16-ти -  67, а для тысячи - 1050. И в каком случае удельная скорость передачи Ваших байтов оказывается выше, как вы думаете?

Те мегабиты скорости, о которых вы говорите - никогда не достигнутся на коротких сообщениях. Это аксиома.

Странно, что вообще приходится обьяснять такие очевидные вещи. Если не верите - проделайте эксперимент - сравните время, за которое копируется 1 файл размером 50-100мегабайт, и 500 файлов такого же суммарного обьема.  Маленькие файлы можете найти в директории Windows\Fonts

 

SergeiSX
Offline
Зарегистрирован: 02.10.2018

Ну не будем показывать друг на друга пальцем и обвинять в том что кто - то из нас непрофессионал. )) Меня мой опыт устравивает))) Я понимаю что в драйвере порта есть буферы. И что драйвер не посылает байт немедленно(хотя по идее надо бы было предусмотреть такой режим). Сам писал такие драйверы. Но вот не совсем понятно почему такие дикие накладные расходы ? Вы всерьез верите что для того чтобы отправить в линию один байт необходимо готовиться к этому едва ли не миллисекунду? Я помню мы замеряли время реакции драйвера ядра для NT 4 на DeviceIoControl. Ну там ито было быстреен)))  А именно такое время у меня получается для посылки одного байта в одну сторону.

 

strarbit
Offline
Зарегистрирован: 12.06.2016

ATMEGA328 Baud Rate Error = 0% at 2,4k, 250k, 0,5M, 1M

SergeiSX
Offline
Зарегистрирован: 02.10.2018

Извините, а что означает эта статистика? Каков реальный трафик ?

strarbit
Offline
Зарегистрирован: 12.06.2016

SergeiSX пишет:

Извините, а что означает эта статистика? Каков реальный трафик ?

это реальный трафик) (если условие идеал не 200 ft кабель)

SergeiSX
Offline
Зарегистрирован: 02.10.2018

Тогда подскажите, пожалуйста, а как Вы его замеряли? Какой программой? И если программа Ваша, то какую модель доступа к COM порту Вы использовали ? Я использую асинхронную по событиям. Моя плата Arduino Nano с китайским чипом CH341 для преобразования COM - Serial. Если слать длинную последовательность байт скорость как будто выше если по одному байту скорость ужасная. Я грешить уже стал на то что виртуальный COM порт реализован через протокол USB и видимо драйвер связывает трафик COM порта с какой - то низкоприоритетной конечной точкой USB. Но не уверен в своих предположениях. Если не трудно поделитесь информацией как Вы замеряли скорость?

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

Учитывайте, что Винда - не RTOS. Если сам процесс уже начавшейся пересылки и будет привязан к заданной частоте, то его начало (синхронизация) не обязано произойти в тот момент, когда вы даете команду send().

 

strarbit
Offline
Зарегистрирован: 12.06.2016

персонально чип CH340G, чипконтроллер плата uno от китай, софт putty & TerminalPro. USB cabel 5.9 ft.

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

strarbit, так по даташиту у 340-й до 2Mbps обещанная скорость... Или нет?

SergeiSX
Offline
Зарегистрирован: 02.10.2018

strarbit пишет:

персонально чип CH340G, чипконтроллер плата uno от китай, софт putty & TerminalPro. USB cabel 5.9 ft.


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

SergeiSX
Offline
Зарегистрирован: 02.10.2018

sadman41 пишет:

Учитывайте, что Винда - не RTOS. Если сам процесс уже начавшейся пересылки и будет привязан к заданной частоте, то его начало (синхронизация) не обязано произойти в тот момент, когда вы даете команду send().

 


Спасибо! Замечание справедливое. Просто мне казалось что если порт занят мной эксклюзивно и протокол нижнего уровня usb то протоколы не должны давать таких диких задержек. Я боюсь что проблема в драйвере порта.

SergeiSX
Offline
Зарегистрирован: 02.10.2018

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

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

SergeiSX пишет:

Просто мне казалось что если порт занят мной эксклюзивно и протокол нижнего уровня usb то протоколы не должны давать таких диких задержек. Я боюсь что проблема в драйвере порта.

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

К тому же, насколько я помню, USB - не point-to-point шина, по двум ее проводам может передаваться траффик нескольких конкурирующих устройств. 

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

 

SergeiSX
Offline
Зарегистрирован: 02.10.2018

sadman41 пишет:

SergeiSX пишет:

Просто мне казалось что если порт занят мной эксклюзивно и протокол нижнего уровня usb то протоколы не должны давать таких диких задержек. Я боюсь что проблема в драйвере порта.

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

К тому же, насколько я помню, USB - не point-to-point шина, по двум ее проводам может передаваться траффик нескольких конкурирующих устройств. 

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

 


Согласен, вопрос непростой! Увы я как раз боюсь что на уровне usb выделена конечная точка с низким приоритетом. Но я постарался исключить весь другой траффик на данном usb хабе. Скачаю наверное putty&Terminal Pro и попробую как рекомендуется выше померять.

strarbit
Offline
Зарегистрирован: 12.06.2016

sadman41 пишет:

strarbit, так по даташиту у 340-й до 2Mbps обещанная скорость... Или нет?

даташит 2Mbps, передатчик ошибка меньше чем 0,3%, приемник < 2%. В реально кабель USB 5pin  5,9 ошибка нет. (любовь ftdi, max)

SergeiSX
Offline
Зарегистрирован: 02.10.2018

strarbit пишет:

sadman41 пишет:

strarbit, так по даташиту у 340-й до 2Mbps обещанная скорость... Или нет?

даташит 2Mbps, передатчик ошибка меньше чем 0,3%, приемник < 2%. В реально кабель USB 5pin  5,9 ошибка нет. (любовь ftdi, max)


Извините, я наверное тупой, но из вашего скриншота непонятно как меняется реальный траффик. Подскажите пожалуйста, как с помощью этого терминала или putty померять реальную скорость приема и передачи строки в плату с CH341?

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

Полагаю, что здесь мы видим простой эхо-тест на Custom speed. Если обратно (Recieve field) он приходит непобитым, то следует вывод - канал без ошибок работает на заданной скорости. Т.е. тут инструментальных измерений нет.

SergeiSX
Offline
Зарегистрирован: 02.10.2018

sadman41 пишет:

Полагаю, что здесь мы видим простой эхо-тест на Custom speed. Если обратно (Recieve field) он приходит непобитым, то следует вывод - канал без ошибок работает на заданной скорости. Т.е. тут инструментальных измерений нет.


Ну из этого как раз совсем не следует что реальный траффик при коротких сообщениях будет на заявленной скорости. Посмотрел исходники putty, ничего принципиально нового они не используют при обмене с COM портом в Windows. Похоже все же это драйвер порта.

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

SergeiSX пишет:
Ну из этого как раз совсем не следует что реальный траффик при коротких сообщениях будет на заявленной скорости.

В таком случае, для начала, необходимо принять общую методику измерений. Как минимум - оговорить от какой и до какой точки, а так же при каком характере траффика требуется измерение пропускной способности канала.

Я не думаю, что производитель чипа  в даташите указал скорость исходя из промеров через винду. Ногами чип может дергать так, чтобы обеспечить частоту для передачи на скорости в 2Mbps, ошибок не делает при этом - значит так вендор и написал в документации.  Считаю, что, в принципе, примененный strarbit метод оценки возможной скорости релевантен для вышеуказанных вводных условий при условии совершения минимума телодвижений. 

SergeiSX
Offline
Зарегистрирован: 02.10.2018

sadman41 пишет:

SergeiSX пишет:
Ну из этого как раз совсем не следует что реальный траффик при коротких сообщениях будет на заявленной скорости.

В таком случае, для начала, необходимо принять общую методику измерений. Как минимум - оговорить от какой и до какой точки, а так же при каком характере траффика требуется измерение пропускной способности канала.

Я не думаю, что производитель чипа  в даташите указал скорость исходя из промеров через винду. Ногами чип может дергать так, чтобы обеспечить частоту для передачи на скорости в 2Mbps, ошибок не делает при этом - значит так вендор и написал в документации.  Считаю, что, в принципе, примененный strarbit метод оценки возможной скорости релевантен для вышеуказанных вводных условий при условии совершения минимума телодвижений. 


Согласен. Для длинных сообщений я получал 33 килобайта в секунду. Скорее всего один символ передается в линию с заданной скоростью. Все остальное сделано так как удобно было для usb протокола при буферизации данных и не слишком быстрой реакции драйвера на очередной запрос.

strarbit
Offline
Зарегистрирован: 12.06.2016

Скрин видно время приема байты 123456789+0Dh+0Ah от чипконтроллер, скорость 2Mbps. Пауза или задержка и ошибка приема нет

Буфер размер на приемник и передатчик указывавет OS.

SergeiSX
Offline
Зарегистрирован: 02.10.2018

strarbit пишет:

Скрин видно время приема байты 123456789+0Dh+0Ah от чипконтроллер, скорость 2Mbps. Пауза или задержка и ошибка приема нет

Буфер размер на приемник и передатчик указывавет OS.


Я смотрел код putty. Там даже проще чем я делаю для приема байтов. Скрин говорит о том что выставлена скорость 2 мегабода. А о реальном времени приема строки ничего не говорится. Точнее нет информации о разнице между временем посылки и временем приема в микросекундах. Есть лишь информация что при данной выставленной скорости ошибок нет. Определяющим здесь является реальное время за которое строка передана принята на другой стороне и получена в программе. А оно боюсь будет существенно выше чем для 2 мегабод. Или покажите мне на скрине красным кружком в Paint где реальное время передачи строки. Я видимо туплю и чего - то не понимаю.

strarbit
Offline
Зарегистрирован: 12.06.2016

OS windows не система реальное время. На скрин реально нет разницы между временем приема 12 байт, стого прием быстрый, пауза нет. на скрин время от компьютера - часы, минуты, секунды, миллисекунды, также  в низ статус бар счетчик принятых байт RX. В Recieve ошибки байтов нет.

SergeiSX
Offline
Зарегистрирован: 02.10.2018

strarbit пишет:

OS windows не система реальное время. На скрин реально нет разницы между временем приема 12 байт, стого прием быстрый, пауза нет. на скрин время от компьютера - часы, минуты, секунды, миллисекунды, также  в низ статус бар счетчик принятых байт RX. В Recieve ошибки байтов нет.


Я Вас понял. Попробую тот же тест сделать дома для платы nano

SergeiSX
Offline
Зарегистрирован: 02.10.2018
    sCmd = Serial.readStringUntil('\xa');  // Принимаем строку
    for(int i = 0; i < 10; ++i)
    {
      Serial.print(sCmd + "\xa"); // Передаем обратно    
      Serial.flush();
      delayMicroseconds(1500);
    }

Я провел тест терминала. В программе на плате я вставил цикл который 10 раз повторяет строку символов, посланную с терминала. В каждой итерации цикла была вставлена задержка в 500 микросекунд. По идее если бы терминал честно принимал строки с задержкой то он бы отобразил в поле миллисекунды разное время на каждую вторую запись. А он отобрази все ответы с одним временем. То есть терминал буферизирует ответы от платы и выводит их одним пакетом. Причем еще и с паузой.

strarbit
Offline
Зарегистрирован: 12.06.2016

SergeiSX пишет:

    sCmd = Serial.readStringUntil('\xa');  // Принимаем строку
    for(int i = 0; i < 10; ++i)
    {
      Serial.print(sCmd + "\xa"); // Передаем обратно    
      Serial.flush();
      delayMicroseconds(1500);
    }

Я провел тест терминала. В программе на плате я вставил цикл который 10 раз повторяет строку символов, посланную с терминала. В каждой итерации цикла была вставлена задержка в 500 микросекунд. По идее если бы терминал честно принимал строки с задержкой то он бы отобразил в поле миллисекунды разное время на каждую вторую запись. А он отобрази все ответы с одним временем. То есть терминал буферизирует ответы от платы и выводит их одним пакетом. Причем еще и с паузой.

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

SergeiSX
Offline
Зарегистрирован: 02.10.2018

strarbit пишет:

SergeiSX пишет:

    sCmd = Serial.readStringUntil('\xa');  // Принимаем строку
    for(int i = 0; i < 10; ++i)
    {
      Serial.print(sCmd + "\xa"); // Передаем обратно    
      Serial.flush();
      delayMicroseconds(1500);
    }

Я провел тест терминала. В программе на плате я вставил цикл который 10 раз повторяет строку символов, посланную с терминала. В каждой итерации цикла была вставлена задержка в 500 микросекунд. По идее если бы терминал честно принимал строки с задержкой то он бы отобразил в поле миллисекунды разное время на каждую вторую запись. А он отобрази все ответы с одним временем. То есть терминал буферизирует ответы от платы и выводит их одним пакетом. Причем еще и с паузой.

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

Ну хорошо, если я неправильно настроил терминал, тогда подскажите как правильно провести тест, если в скетче именно такая вот программа когда каждый ответ задерживается на 500 микросекунд. Как это отобразить в терминале правильно ?

SergeiSX
Offline
Зарегистрирован: 02.10.2018

strarbit пишет:

SergeiSX пишет:

    sCmd = Serial.readStringUntil('\xa');  // Принимаем строку
    for(int i = 0; i < 10; ++i)
    {
      Serial.print(sCmd + "\xa"); // Передаем обратно    
      Serial.flush();
      delayMicroseconds(1500);
    }

Я провел тест терминала. В программе на плате я вставил цикл который 10 раз повторяет строку символов, посланную с терминала. В каждой итерации цикла была вставлена задержка в 500 микросекунд. По идее если бы терминал честно принимал строки с задержкой то он бы отобразил в поле миллисекунды разное время на каждую вторую запись. А он отобрази все ответы с одним временем. То есть терминал буферизирует ответы от платы и выводит их одним пакетом. Причем еще и с паузой.

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

Ну хорошо, если я неправильно настроил терминал, тогда подскажите как правильно провести тест, если в скетче именно такая вот программа когда каждый ответ задерживается на 500 микросекунд. Как это отобразить в терминале правильно ?

Vladimir Shamov
Offline
Зарегистрирован: 28.12.2018

Я с октября занимаюсь разработкой в Ардуино программы - измерения давления на двух датчиках. Реально меня интересовало время цикла измерений, а не когда результаты придут в компьтер через компорт. Поэтому я сначала поисследовал работу таймера в Ардуино и увидел, что разброс срабатывания достигает десятков микросекунд (+-12). Стало быть, прерывания также срабатывают "когда хотят".

Но для задачи это было некритично. Необходимо время измерения раз в 1-2 милисекунды. Самое интересное получается, если замерять время прохождения цикла LOOP с выдачей результатов и "молча" просто измеряя время цикла. Ведь от этого зависит когда ты измеришь свои АЦП. Так что, мне кажется за это надо "биться", а не как срабатывает непонятно когда выдающий накопленные данных буфер Serial.

Для замеров я написал тест (меня еще интересовало согласование двух датчиков). Кого интересует - есть диаграмма - две минуты Ардуино закидывает в монитор строки: 1 датчик, 2 датчик, номер цикла и длительность от начала опыта. Раброс времени цикла от 240 до 1200 микросекунд. Главное же то, что длительность между измерениями находится в пределах одной-двух милисекунд, не смотря на "отправку пакетов буфером Serial" когда ему хочется. Вот текст теста:

// Тест согласования датчиков давления
const int analogInPin = A0;   // Давление до детали - датчик до входа
const int analogInPin1 = A1;  // давление за деталью
unsigned long int nowt;       // время начала цикла
unsigned long int last;       // храним предпоследний nowt=micros(); для определения во время опыта времени одного цикла
unsigned long int delt;       // = if (l>t) {maxi - l + t + 1; } else {t - l;};
int presI = 0;               // давление до детали
int presO = 0;               // давление после детали > предыдущего
// необходимые константы
unsigned long int maxi = 4294967295;  // "емкость" формата 4 294 967 295 GLOBAL
unsigned long int maxP = 120000000;    // регистрация измерений соответствует 120 000 000 мксек
unsigned long int T = 0;    // time 
unsigned long int Count = 0;      // всего сделано измерений
int inByte=0;
int e = 1;
void setup() 
{
    Serial.begin(115200);
    // пока последовательный порт не будет открыт - ничего не делаем: вопрос как закрыть? - похоже не надо!
    while (!Serial) {};             // по совету для Leonardo https://doc.arduino.ua/ru/guide/ArduinoLeonardoMicro
    //pinMode(LED_BUILTIN, OUTPUT); // ПРИ ОТРАБОТКЕ РЕЖИМА БУДЕТ гаснуть(в начале) или зажигаться (в конце) ЛАМПОЧКА НА АРДУИНЕ
    nowt = micros();              // ПОДСЧЕТ ИНТЕРВАЛОВ ВРЕМЕНИ В МИКРОСЕКУНДАХ
    last = nowt;                  // Начальная установка важной переменной 
    Count=0; inByte=0; e=1;
}
void loop() 
{
  Count++; 
  nowt=micros();                      // СЧИТАЕМ, ЧТО ЭТО ВРЕМЯ ИЗМЕРЕНИЙ для этого их все сюда ! 
  presI = analogRead(analogInPin);     // давление до детали                                 !
  presO = analogRead(analogInPin1);    // давление после детали 
  while (Serial.available() > 0) 
  {   // считываем байты - по первому формируем режим
     inByte = Serial.read();
     if (inByte==85)     //U опыт с прерываниями - переход event
     {  
        e = 0;  T=0; Count=0; 
        inByte=0; 
     };
  }; // while (Serial.available() > 0) 

if (e==0)
{
      Serial.print(presI); Serial.print(";");
      Serial.print(presO); Serial.print(";");
      Serial.print(Count);Serial.print(";");
      Serial.println(T);

  if (T>maxP) //maxP) // 30 sek = 30 000 000
   {
      Serial.println("###U");
      T=0; Count=0; e=1;
   };
}    // (event==0)
else // (event==1) простой
{
  T=0;
}; // event=1
  if (last>nowt) {     delt = maxi - last + nowt + 1; }
  else           {     delt = nowt - last;              };
  T = T + delt;
  last = nowt;           // весь следующий цикл будет хранить время предпоследнего измерения, 
} // LOOP

график времен прохождения цикла в течении 2 минут(не сумел вставить картинку) опишу так:

2 минуты измерений - рост времени цикла до 1 милисекунды за 1 секунду, потом неравномерно нарастает время цикла до 1.2 милисек к концу второй минуты измерений - дальше не измерял.

Вывод на Ардуино не удастся отследить изменения через компорт быстрее 1 милисек много данных. Поможет отслеживание в течение 10 сек через кольцевой буфер небольшого количества данных.

Например, мне удалось 10 сек наблюдать эти два датчика со временем цикла менее 700 микросекунд, обеспечивая по этой схеме 2 милисекундные измерения и выдавая 1 измерение из КБ за цикл, помогая (сглаживая время буфера) Serial равномернее "опорожняться". Если я неправ в чем - интересно услышать спокойное другое мнение.

 

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Vladimir Shamov пишет:

  if (last>nowt) {     delt = maxi - last + nowt + 1; }
  else           {     delt = nowt - last;              };

 

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

То есть :

for i in range(10):
    print( str((i+2**32-5) & 0xffffffff) + "-10 = "+ str((i+2**32 -15) & 0xffffffff))

4294967291-10 = 4294967281
4294967292-10 = 4294967282
4294967293-10 = 4294967283
4294967294-10 = 4294967284
4294967295-10 = 4294967285
0-10 = 4294967286
1-10 = 4294967287
2-10 = 4294967288
3-10 = 4294967289
4-10 = 4294967290

В строке 9 уменьшаемое перешагнуло рубеж переполнения 32-разрядных чисел.

Для не-программиста не знать этого - простительно, просто исправьте, смешно выглядит.

Vladimir Shamov
Offline
Зарегистрирован: 28.12.2018

Спасибо.

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

Люблю молодых, считающих себя программистами. Спасибо еще раз за арифметику.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Vladimir Shamov пишет:

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

По какой методике разброст измеряли?

Какие прерывания имеются ввиду?

Цитата:
Необходимо время измерения раз в 1-2 милисекунды. Самое интересное получается, если замерять время прохождения цикла LOOP с выдачей результатов и "молча" просто измеряя время цикла. Ведь от этого зависит когда ты измеришь свои АЦП. Так что, мне кажется за это надо "биться", а не как срабатывает непонятно когда выдающий накопленные данных буфер Serial.

Не совсем понятно - за что именно надо биться?

 

Цитата:
Например, мне удалось 10 сек наблюдать эти два датчика со временем цикла менее 700 микросекунд, обеспечивая по этой схеме 2 милисекундные измерения и выдавая 1 измерение из КБ за цикл, помогая (сглаживая время буфера) Serial равномернее "опорожняться". Если я неправ в чем - интересно услышать спокойное другое мнение.

Вы можете описать, что, конкретно, вам требуется для решения вашей задачи? Делать измерения с фиксированным интервалом в 2 мс?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Vladimir Shamov, долго пытался вникнуть в Ваш код и не слишком преуспел в этом.

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

Далее: по поводу 1 абзаца сообщения №38: не очень понятно, что и как Вы измеряли, но сильно подозреваю, что измеряли совсем не то, что хотели, либо сделали неверные выводы (по всей видимости, в этом абазаце Вы описываете результаты какого-то другого скетча, а не того, что приведен в сообщении).

Текст в остальных абзацах не прояснил того, что и как Вы пытаетесь сделать.

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

1. Вывод на печать происходит каждую итерацию цикла. Без пропусков.

2. Интервал времени между измереними порядка 2 мс.

3. Длина выводимой строки порядка 22 символов.

4. Из сравнения скорости порта 115200, а также пп. 1, 2 и 3 можно заключить, что длительность итерации определяется временем передачи по последовательному порту.

Но из приведенного совершенно непонятно:

- что именно Вы хотели измерить,

- с какой целью ставили эти эксперименты.

Если была цель уложиться в 2 мс, то Вы ее не просто не достигли, а явно и не пытались достичь. Тогда что?

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

andriano пишет:

Vladimir Shamov, долго пытался вникнуть в Ваш код и не слишком преуспел в этом.

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

Жаль расстраивать коллегу тем, что отправлять можно со скоростью 1 Mbps и двоичные данные - по два байта на измерение, как раз по 10 мкс на байт плюс паузы. ;)))))))))))

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Влад, мне кажется, достаточно отправлять по 3 байта на два измерения. А может, и меньше.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

andriano пишет:

Влад, мне кажется, достаточно отправлять по 3 байта на два измерения. А может, и меньше.

для скорости АВРовского АЦП это уже почти безразлично... если мы не станем повторять подвиги А........, с раскруткой АЦП на 100500 дофиГерц. ;))))

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

wdrakula пишет:

для скорости АВРовского АЦП это уже почти безразлично... если мы не станем повторять подвиги А........, с раскруткой АЦП на 100500 дофиГерц. ;))))

А это, между прочим, идея. Тогда и двух байтов хватит.