Відповісти

Введіть повідомлення і натисніть Надіслати
Параметри

Назад

Огляд теми (нові повідомленні вгорі)

Green
2018-05-06 19:19:29

На самом деле millis() имеет джиттер. А на 8-ми мгц просто гигантский! Поэтому иногда (например для динамической индикации) приходится использовать нештатный миллис().
Ну а в пустом loope конечно можно добиться абсолютной (до такта) скважности = 2, только зачем?)

renoshnik
2018-05-06 18:29:55
Olej пише:

Вот любопытные вещи относительно хронометража в Arduino:

При использовании millis() нужно помнить об одной особенности - millis() "тикает" не равномерно.
Возвращаемое значение увеличивается на единицу каждые 1024 мсек. Затем, когда миллис отстанет на 1 мсек, она "подводится" на единицу, т.е.  возвращаемое значение перескакивает через один.
При измерении длительных интервалов это не страшно, но при интервалах в несколько мсек это заметно.


Смотря, что вы считаете длительным интервалом ...  smile  по моему весьма заметно....

#include <S65Display.h> 
S65Display lcd; 
#define BLACK        RGB(  0,  0,  0)
#define WHITE        RGB(255,255,255)
#define RED          RGB(255,  0,  0)
#define GREEN        RGB(  0,255,  0)
#define GREEN2       RGB(  0,255, 51)
#define BLUE         RGB(  0,  0,255)
#define YELLOW       RGB(255,255,  0)
#define YELLOW2      RGB(153,153,  0)
#define PINK         RGB(204,051,153)
#define BGCOLOR      RGB( 51,204,255)
char str[10];
byte hour=0, minut=0, secund=0;
unsigned long TimeCHR;
byte Sec=0, Min=0, Hrs=0;

void setup() {   
  lcd.init(2);   lcd.clear(0); 
  lcd.clear(BLACK);  					//закрашиваем дисплей
  lcd.drawRect(1,1,175,131,RED); 		// рисуем рамку
  lcd.drawRect(3,3,173,129,GREEN2); 	// рисуем рамку
  lcd.drawRect(5,5,171,127,BLUE); 		// рисуем рамку
  lcd.drawText(52, 55,"test time", 1, GREEN, BLACK);
// ************************************			
// * Настраиваем таймер времени *
// ************************************	
  TIMSK1 = 0x01; 		// включенно глобальное прерывание переполнения таймера
  TCCR1A = 0x00; 		
  TCNT1 = 0x0BDC; 		// установить начальное значение для удаления ошибки времени (регистр бит-бит)
  TCCR1B = 0x04; 		// запуск таймера / установка часов   
  } 

//	********************************************************************
//	функция учета времени
//	********************************************************************	
ISR(TIMER1_OVF_vect) { TCNT1=0x0BDC; measure(); }	
// функция вызывается с интервалом в одну секунду
void measure (void) {	secund++; 
  if (secund==60) 	{secund=0; minut++;} 
  if (minut==60) 	{minut=0; hour++;}
  if (hour==24) 	{hour=0;}	
	sprintf(str, "%02d.%02d.%02d", (int)hour, (int)minut, (int)secund); 
	lcd.drawText(55, 25, str, 1, YELLOW, BLACK);	}
//	====================================================================  
//	====================================================================
  	
  void loop() {
	TimeCHR = millis();	
		Sec = (TimeCHR/1000L)%60;
			Min = ((TimeCHR/1000L)/60L)%60;
				Hrs = ((TimeCHR/1000L)/3600L)%24;	
	sprintf(str, "%02d.%02d.%02d", (int)Hrs, (int)Min, (int)Sec); 
	lcd.drawText(55, 85, str, 1, YELLOW2, BLACK);	
/* for (int i = 0; i <= 15; i++) {	
lcd.drawText(52, 55,"test time", 1, WHITE, BLACK);	delay(100);
lcd.drawText(52, 55,"test time", 1, RED, BLACK);	delay(100);
lcd.drawText(52, 55,"test time", 1, BLUE, BLACK);	delay(100);
lcd.drawText(52, 55,"test time", 1, PINK, BLACK);	delay(100);	
lcd.drawText(52, 55,"test time", 1, GREEN, BLACK);	delay(100);	
	} */
  }  
//	====================================================================  

http://i.piccy.info/i9/dac81faee8bb5b4b3b111aced540e9e1/1525620449/477562/1161865/00004.jpg

http://i.piccy.info/i9/39ae4e996c6d2ce4a64812209258db93/1525620463/418130/1161865/00005.jpg

Olej
2018-03-27 23:54:18
Kaka пише:

Проверили.

Правда не совсем точно...

Kaka пише:

Скважность, конечно не ровно 2, но близко к тому. Читать надо.

Как это "не ровно"?
Если время пустого цикла loop() порядка ~0.5мкс. то при delay( 1 ) скважность будет 1 + 1.0005 - это и есть "не ровно 2"? hmm

Kaka
2018-03-27 20:38:03
Olej пише:

рассыпается миф

Так там в теме именно так вопрос и ставился - проверить это. Проверили. Скважность, конечно не ровно 2, но близко к тому. Читать надо.

Olej
2018-03-27 09:50:44
Kaka пише:
Olej пише:

В-третьих, мне не хочется возиться с осциллографом.

Ну, как писал Высоцкий: "Стукнул раз - специалист - видно по нему! smile

Я не понимаю что вас так развеселило? Я написал же как и почему способ аппаратного определения, с помощью осциллографа, тоже порочный логически: он будет давать заниженные значения частоты, или затянутый период одного цикла loop().
Хотя сама цифра длины периода и не так важна (разве любопытства ради). Если она мала (800нс или 300нс - не важно) то:
- рассыпается миф, пересказываемый во многих обсуждениях об Arduino, что цикли с 2-мя delay( 1 ) (и любыми другими delay()) будет иметь скважность не 2 ... т.е. что loop() ещё что-то куда-то добавляет;
- можно спокойно не учитывать какие бы ни было задержки, вносимые частями исполняющей системой, прикомпилируемой IDE;
- хотя можно, понятности и точности ради, вообще исключить из исполнимого скетча функции setup() и loop(), прописав туда собственную функцию main():

int main() {
    Serial.begin( 9600 ); 
    Serial.println( "++" ); 
}

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

Kaka
2018-03-27 08:41:04
Olej пише:

В-третьих, мне не хочется возиться с осциллографом.

Ну, как писал Высоцкий: "Стукнул раз - специалист - видно по нему! smile

Olej
2018-03-26 21:09:29
Kaka пише:
Olej пише:

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

Достаточно было почитать тему по той ссылке, что я давал. Там есть этот пример с осциллограммой.

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

Kaka
2018-03-26 20:32:09
Olej пише:

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

Достаточно было почитать тему по той ссылке, что я давал. Там есть этот пример с осциллограммой.

Olej
2018-03-24 11:49:57
Olej пише:

3. дополнительная задержка, вносимая в цикл loop() исполняющей системой Arduino исчезающе мала, меньше 1мкс ... неважно сколько там точно.

Это хорошая новость (для меня wink ). Потому что она опровергает описываемые на разных форумах Arduino утверждения о том, что простейший пример генерации меандра не будет иметь скважности 2:

void loop()
{
  digitalWrite( ledPin, HIGH );  
  delay( 1 );   
  digitalWrite( ledPin, LOW );
  delay( 1 );
}

Так что стоило повозиться с тестированием, чтобы лишний раз самому убедиться, что разговоры по дополнительные задержки, вносимые к циклу loop() - это пустое: цикл - он и в Африке цикл.

Olej
2018-03-24 11:36:42
Kaka пише:

Так что измерял ты не скорость вызовов loop, а скорость твоих тормозов.

В принципе, да.
За счёт очень длинных (в сравнении с тактовой частотой) операций процессора +=, * + очень короткой задержки сверх цикла loop(), даже влияние 2-3 операций уже длиннее 1-го цикла loop(). Но это можно компенсировать, сделав калибровку на выполнение точно тех же операций (не заисанных в коде по-другому), но во внутреннем пустом цикле не выходя за пределы 1-го прохода цикла loop().
Как-то вот так, например:

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

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

#define step()                    \
  next = micros();                \
  if( i++ > 0 )                   \
    s1 += (next - prev);          \
  prev = next;

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 = i = 0;
  }  
  step();                           // интервал в loop 
  if( i > rep ) {                   // вычисление результатов
    double m = (double)s1 / rep;
    s1 = i = 0;
  loop: step();                     // интервал во внутреннем цикле
    if( i <= rep ) goto loop;    
    double c = (double)s1 / rep;
    Serial.print( rep, DEC );
    Serial.print( " : " ); 
    Serial.print( m, 3 ); 
    Serial.print( " - " ); 
    Serial.print( c, 3 ); 
    Serial.print( " = " ); 
    Serial.println( m - c, 3 );     
    cont = true;
  }
}

В результате будет как-то так:

100 : 9.960 - 9.640 = 0.320
1000 : 9.992 - 9.684 = 0.308
10000 : 9.998 - 9.684 = 0.314
100000 : 9.998 - 9.684 = 0.314
1000000 : 9.998 - 9.684 = 0.315

1. видно хорошую сходимость в зависимости от числа усреднения
2. может, чуть заниженный итог из-за одной "лишней" операции goto (для цикла использовать for() и while() не хотелось, там зависимоть от того как компилятор распорядится, и вносимые искажения там ещё больше ... проверено)
3. дополнительная задержка, вносимая в цикл loop() исполняющей системой Arduino исчезающе мала, меньше 1мкс ... неважно сколько там точно.

P.S. (Это что не лазить и не смотреть период осциллографом... Хотя с осциллографом тоже есть вопрос: в цикле loop() должна быть хотя бы одна операция вывода ... даже если её записать операцией AVR как PIND |= (1 << 3); - без промежуточного вызова функций Arduino)

Olej
2018-03-22 17:02:44
Kaka пише:

Понятно. Диагноз ясен. Вопрос закрыт.

Вот и я подумал, что с самонадеянным ... радиомонтажником big_smile обсуждать дальше не стану.

Kaka
2018-03-22 17:00:07

Понятно. Диагноз ясен. Вопрос закрыт.

Olej
2018-03-22 16:58:19
Kaka пише:
Olej пише:

В AVR обычно и в Arduino в частности таймер настроен на системный тик как-раз по 1024-й микросекунде (если не лазить к таймеру руками).

Ты идиот? Частота в ардуино 16МГц, значит системный тик - 1/16 микросекунды.

Идиот - это ты, дружище.
А 1/16 микросекунды - это период частоты процессора, к системному тику никакого прямого отношения не имеет ... хотя системный тик и формируется из этой частоты.
Это только у недоумков-самоделкиных, безграмотных радиолюбителей - что частота процессора, что системный тик ... и всё по хер.

Kaka
2018-03-22 16:54:17
Olej пише:

В AVR обычно и в Arduino в частности таймер настроен на системный тик как-раз по 1024-й микросекунде (если не лазить к таймеру руками).

Ты идиот? Частота в ардуино 16МГц, значит системный тик - 1/16 микросекунды. Не знаю, какие тебе нужны источники и пруфы, чтобы из частоты период получить, ну почитай учебник для 6-го класса.

Kaka
2018-03-22 16:52:30
Olej пише:

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

Так ты определись - или делай, или не болтай. Не пахнет там никакими 17,6 мкс и близко. Это твои тормоза. Так что измерял ты не скорость вызовов loop, а скорость твоих тормозов.

Підвал форуму