Высокая точность синхронизации на Arduino для последовательной связи

Я использую Arduino Uno для отправки информации о времени и напряжении по последовательному порту на Python для построения графика. Однако временные интервалы между последовательными отметками времени, похоже, со временем увеличиваются, что сказывается на моем графике. Это особенно верно, когда скорость передачи установлена ​​на 9600, где мои начальные разницы во времени могут быть 1320 и увеличиваются до 16400 после относительно короткого периода времени. Когда этот показатель будет максимальным 115200 бит /с, изменение будет медленнее и менее заметным, примерно с 1340 по 1500 год даже после относительно длительного запуска отправки. Все времена даются в микросекундах.

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

  1. Могу ли я получить большую точность во времени?
  2. Что вызывает это изменение времени?

Вот что я сейчас имею:

 #include <eHealth.h>

extern volatile unsigned long timer0_overflow_count;
float fanalog0;
int analog0;
unsigned long time;    

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

void loop() { 
  while (Serial.available()>0){  
    serialByte=Serial.read();
    if (serialByte=='S'){        
      while(1){
        fanalog0=eHealth.getECG();  
        // Use the timer0 => 1 tick every 4 us
        time=(timer0_overflow_count << 8) + TCNT0;        
        // Microseconds conversion.
        time=(time*4);   
        //Print in a file for simulation
        //Serial.print(time);
        //Serial.print(" ");
        Serial.print(fanalog0,5);
        Serial.print("\n");

        if (Serial.available()>0){
          serialByte=Serial.read();
          if (serialByte=='F')  break;
        }
      }
    }
  }
}
10 голосов | спросил user3284376 11 MarpmTue, 11 Mar 2014 13:13:08 +04002014-03-11T13:13:08+04:0001 2014, 13:13:08

3 ответа


3

Я могу придумать несколько вещей, которые могут повлиять на «согласованность» таймингов последовательной записи:

  • размер данных для печати

Это может быть наиболее очевидным, о чем можно подумать, но в действительности, чем больше вы печатаете, тем больше он будет обрабатывать.

Решение: напечатайте строку в строку с известной длиной.

  • с использованием буферизованного последовательного интерфейса

в unix вы можете получить доступ к последовательному порту с использованием буферизованного или небуферизованного способа. Использование буферизованного способа в течение длительного времени может сделать его немного медленнее по мере заполнения буфера, обычно это происходит, когда данные поступают быстрее, чем вы читаете itâ € |

Решение: используйте небуферизованную последовательную линию ( eg : на Darwin /OSX это /dev/cu.usbmodemXXX вместо /dev/tty.usbmodemXXX

  • приоритет таймеров

похоже, что вы используете прерывание TC, и у AVR есть приоритеты в том, как обрабатываются прерывания, я не знаю порядок приоритета для Atmega328, и это не одна из самых документированных функций, поэтому я не Не знаю, насколько безопасен TC0 против прерывания UART.

Решение: смотрите далее в документации /таблице о приоритетах прерывания и при необходимости измените таймер; и /или выполнить тест без использования другого таймера.

  • данные, которые вы читаете, занимают больше времени, чтобы читать со временем

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

Решение: посмотрите исходный код библиотеки, которую вы используете, и либо оптимизируйте ее, либо удалите вычисление, если оно есть, либо учтите это увеличение времени обработки.

  • избежание накладных расходов на arduino

, но если вы действительно хотите оптимизировать серийный выход из arduino, вам следует избегать использования arduino overheadâ € | Но это менее элегантно и удобно использовать.

Я уверен, что есть другие моменты, которые мне не хватает, но это первые вещи, которые я проверил, прежде чем рыть дальше.

НТН

ответил zmo 11 MarpmTue, 11 Mar 2014 19:28:40 +04002014-03-11T19:28:40+04:0007 2014, 19:28:40
3

Используйте таймер и ISR (процедура обслуживания прерываний), чтобы сделать выбор времени более точным.

Взгляните на прерывание 1 мс Доказательство концепции . Идея состоит в том, чтобы в системе было достаточно точное 1 мс «сердцебиение», которое может использоваться для запуска других событий. В PoC он используется для мигания светодиода на ½ Гц, но доступ к новым переменным millisecondCounter и secondCounter позволяет запускать события в основном цикле на произвольном (но точно рассчитанные моменты).

ответил jippie 11 MarpmTue, 11 Mar 2014 21:16:42 +04002014-03-11T21:16:42+04:0009 2014, 21:16:42
2

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

Следующий вопрос заключается в том, что ООН имеет очень слабую временную базу. См. Здесь сравнение различных типов Arduino с привязкой времени DCF77.

Заключение: если вам нужно точное время или получить Arduino с кристаллом или пойти на RTC. Я могу настоятельно рекомендовать RTC DS3231 /DS3232, поскольку они обычно достигают точности в 2 ppm из коробки.

ответил Udo Klein 28 PMpMon, 28 Apr 2014 12:52:37 +040052Monday 2014, 12:52:37

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

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

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