Страница 1 из 1

программирование Arduino

Добавлено: 21 мар 2018, 20:39
Olej
Уже много по этому поводу написано в разных темах: Arduino (отчасти) и Arduino + Processing.
Но всё-таки там - это специфические вопросы ... и темы перегружены.
Поэтому вот такая отдельная тема.

Re: программирование Arduino

Добавлено: 21 мар 2018, 20:44
Olej
Вот любопытные вещи относительно хронометража в Arduino:
При использовании millis() нужно помнить об одной особенности - millis() "тикает" не равномерно.
Возвращаемое значение увеличивается на единицу каждые 1024 мсек. Затем, когда миллис отстанет на 1 мсек, она "подводится" на единицу, т.е. возвращаемое значение перескакивает через один.
При измерении длительных интервалов это не страшно, но при интервалах в несколько мсек это заметно.
Так же (время системного тика чуть меньше 1mc) имеет место во всех процессорных семействах и всех операционных системах (или средах выполнения). Но это в точности соответствует представлениям реального времени и требованиям стандарта POSIX 1003b для реального времени: "фактические значения временных интервалов может быть сколь угодно больше заказанных, но никогда не может оказаться меньше". Или то же самое: единица шкалы измерения времени (1мс.) может быть меньше, но не смеет быть больше.

В вашем изложении период 1mc фактически соответствует 0,9765625mks. Тогда процесс коррекции millis() строго детерминированный, и можно точно вычислить период, с которым ошибка millis() будет накапливать 1ms и будет подлежать коррекции.
Сделал специально такой тестовый код:

Код: Выделить всё

#include <stdio.h>
int serial_fputchar( const char ch, FILE *stream ) { Serial.write( ch ); return ch; }
static FILE *serial_stream = fdevopen( serial_fputchar, NULL );

void setup() {
  stdout = serial_stream;
  Serial.begin( 115200 ); 
}

void loop() {
  while( !Serial.available() );
  unsigned len = 0;
  while( Serial.available() ) {
    int r = Serial.read();
    if( r >= '0' && r <='9' ) 
      len = len * 10 + ( r - '0' );
    delay( 1 );
  }
  Serial.println( len, DEC );
  printf( "вычисление... ожидайте...\n" );
  unsigned long *prev = new unsigned long [ len ],
                *next = new unsigned long [ len ];
  int i = 0;
  do {
    prev[ i ] = millis();
    while( prev[ i ] == ( next[ i ] = millis() ) );
    if( next[ i ] - prev[ i ] > 1 ) i++;
  } while( i < len );
  for( i = 0; i < len; i++ ) {
    printf( "%lu:%lu:%2u", prev[ i ], next[ i ], i ? prev[ i ] - prev[ i - 1 ] : 0 );    
    printf( "%s", ( 9 == ( i % 10 ) ) ? "\n" : " | " );
  }
  printf( "\n" );
  delete [] prev;
  delete [] next;  
}
И вот что он даёт...
m2.png
Вот как это происходит по умолчанию (если не влазить в этот процесс): коррекция производится чаще через 43, реже через 42 последовательных вызовов millis().

программирование Arduino

Добавлено: 22 мар 2018, 00:10
Olej
Интересный вопрос: продолжительность пустого цикла опроса loop()?
Часто пишут: что мы, мол, точно не знаем задержек повторения loop() ... поэтому сложно судить ... о скважности, например delay() ...

Проверяем!

Код: Выделить всё

void setup() {
  Serial.begin( 115200 ); 
}

unsigned long rep, i, s1, s2, prev, next;
bool cont = true; 

void loop() {
  if( cont ) {                       // ввод числа повторений
    while( !Serial.available() );
    rep = 0;
    while( Serial.available() ) {
      int r = Serial.read();
      if( r >= '0' && r <='9' ) 
        rep = rep * 10 + ( r - '0' );
      delay( 3 );
    }
    cont = false;
    s1 = s2 = prev = next = i = 0;
  }    
  next = micros();
  if( i <= rep ) {                     // посчёт задержек
    if( i > 0 ) {
      uint32_t inter = next - prev;
      s1 += inter;
      s2 += inter * inter; 
    }
    i++;
  }
  prev = next;
  if( i == rep + 1 ) {                 // вычисление результатов
    Serial.print( i - 1, DEC );
    Serial.print( " : " );  
    double m = (double)s1 / rep,
           d = (double)s2 / rep - m * m;
    Serial.print( m, 2 );
    Serial.print( " +/-" );
    Serial.println( sqrt( d ) ); 
    cont = true;
  }
}
В итоге имеем:
Изображение

Re: программирование Arduino

Добавлено: 22 мар 2018, 00:29
Olej
Olej писал(а):В итоге имеем:
Итог:
- период повторения "пустых" loop() в среднем 17.61 мкс.
- со среднеквадратичным разбросом (СКО) 2.09 мкс. (11.87% от среднего)

Re: программирование Arduino

Добавлено: 22 июл 2022, 14:08
Olej
В проекте TinyGo - A Go Compiler For Small Places на их GIT-репозитории в перечислении таргет-платформ появилось:

Код: Выделить всё

...
Arduino Mega 1280
Arduino Mega 2560
Arduino MKR1000
Arduino MKR WiFi 1010
Arduino Nano
Arduino Nano 33 BLE
Arduino Nano 33 BLE Sense
Arduino Nano 33 IoT
Arduino Nano RP2040 Connect
Arduino Uno
Arduino Zero
...
TinyGo — это проект по переносу Go на микроконтроллеры и небольшие системы с одним процессорным ядром. Он похож на emgo, но основное отличие состоит в том, что мы хотим сохранить модель памяти Go (что подразумевает некую сборку мусора). Еще одно отличие состоит в том, что TinyGo использует LLVM внутри, а не генерирует C, что, как мы надеемся, приведет к меньшему и более эффективному коду и, безусловно, к большей гибкости.