Простые часы нереального времени

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

Порывшись по форуму сплошь и рядом попадались примеры часов реального времени, буть то DS1307 или что-то поточнее, так как часов реального времени не существует в принципе, решил озаглавить тему именно так.
К сути вопроса?
Какова долговременная стабильность часов с использованием функции millis() на обычной ардуине из поднебесной.
Так как до нас всё давно придумано ниже приведён кусочек кода, где корректировка времени производится поэтапно, а именно: раз в секунду (полсекунды), раз в минуту, раз в час ...ну и можно раз в сутки...
Вспомним большие такие вестибюльные часы корректировавшие своё время по сигналам точного времени передаваемым по радиотрансляционной сети.
И собственно кусочек кода

void myClock01()
   {
     if (millis() - previousMillis >=500) 
   {  
   previousMillis = previousMillis + 496; //корректировка на наш кварц и задержки в коде
   millis();  //запуcкаем таймер
   digitalWrite(53, !digitalRead(53));//меняем значение порта каждые 0.5секунд
   
   if(digitalRead(53)==HIGH)//если 12 нога лог1 то...
   {
     sek++;//переменная секунда + 1
    
     }
   
   if(digitalRead(53)==LOW)
   {
     //через каждые 0.5 секунд меняем символ ":" на "."
   
   }
   
   if(sek>59)//если переменная секунда больше 59 ...
   {
     sek=0;//сбрасываем ее на 0
     min++;//пишем +1 в переменную минута
      previousMillis = previousMillis - 7; //корректировка раз в минуту точнее 6.82м сек
   }
      
   if(min>59)//если переменная минута больше 59 ...
   {
     min=0;//сбрасываем ее на 0
     chas++;//пишем +1 в переменную час
     previousMillis = previousMillis + 0; //корректировка раз в час
    }
   
   if(chas >23)//если переменная час больше 23 ...
   {
     chas=0;//сбрасываем ее на 0
     previousMillis = previousMillis + 0; //корректировка раз в сутки
    }
      
   //вывод символов на дисплей//
 

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
millis();  //запуcкаем таймер

Аффтор жжет. Таффай исчо.

bwn
Offline
Зарегистрирован: 25.08.2014

На сколько брешет кварц, на столько же и миллис + температурный дрейф кварца (величина переменная) если вы не в термостате.

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

qwone пишет:

millis();  //запуcкаем таймер

Аффтор жжет. Таффай исчо.

Согласен, но КОД (С) http://arduino.ru/forum/programmirovanie/chasy-i-arduino
Я даже комментарии не удалял,
просто поправил алгоритмс )))
 

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

bwn пишет:

На сколько брешет кварц, на столько же и миллис + температурный дрейф кварца (величина переменная) если вы не в термостате.

Там не только кварц, я же показал, вызываю как функцию, а кварц "функции millis() на обычной ардуине из поднебесной."

Была возможность потестировать 7 часов с гаком, за это время отствание 6,82 миллисекунды,
если Вы запускали в работу сервер NTP то в курсе о временной нестабильности обычных кварцев
Те, что на материнских платах )))
Минимальное время для прогона - сутки, тогда что-то скажу. можно конечно прикупить высокостабильный кварцевый резонатор - 0.5 ррм было бы самое то )))
Удивляет, что столько могучих специалистов на форуме а детские ошибки не поправили )))
Это даже мне, ни разу не программисту невооруженным глазом видно - "...но ведь я не агитатор я потомственный кузнец..."

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ua6em, часы на миллис никто не делает. Не стоит воспринимать творчество начинающих всерьёз.

bwn
Offline
Зарегистрирован: 25.08.2014

"Какова долговременная стабильность часов с использованием функции millis() на обычной ардуине из поднебесной.
Так как до нас всё давно придумано ниже приведён кусочек кода, где корректировка времени производится поэтапно, а именно: раз в секунду (полсекунды), раз в минуту, раз в час ...ну и можно раз в сутки...
Вспомним большие такие вестибюльные часы корректировавшие своё время по сигналам точного времени передаваемым по радиотрансляционной сети."

Где в этом тексте вопрос об исправлении ошибок? Есть вопрос про миллис, Вам на него ответили.

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

dimax пишет:

ua6em, часы на миллис никто не делает. Не стоит воспринимать творчество начинающих всерьёз.

А на чём делают? DS1307 - из двух имеющихся у меня (из поднебесной) не АЙС (от слова совсем), более точные DS3231 пока не подошли...Посмотрим, что скажет суточное тестирование...меня устраивает суточная точность одна секунда...и на ардуине используя функцию millis() это достижимо )))
"Вам не нравятся коты? Да Вы их просто готовить не умеете"

Кстати, Дмитрий, к вам вопрос более серьёзного плана, надо сделать регулятор, где за базовое снимаемое напряжение принято 6-8 милливольт, читал ваши посты, датчик съёма от пинов А в паре сантиметрах, есть теоретическая возможность не городить с внешним ацп? (точность разрешения 0,2 милливольта устроит)

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ua6em, если уж делать часы пользуясь ресурсами МК, то лучше делать так . А чем вам DS3231 не угодил?

Вам нужно измерять напряжение 8 мВ с точностью 0,2мв? С одной стороны это всего 40 отсчётов, и можно  получить такую точность пользуясь любым встроенным АЦП с встроенным усилителем, но это в теории. На практике помехи от МК и питания проползут на вход, и устроят шум и гам, чем сделают такое измерение абсолютно не пригодным. Поэтому скорее всего придёться делать усилитель на  хотя бы самым простом инструментальном ОУ типа ad623, сделать ему отдельное чистое питание, и тогда результат будет хорошим. Или  всё-таки внешний ацп с встроенным усилением, и  тоже отвязка его от питания МК.

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

dimax пишет:

ua6em, если уж делать часы пользуясь ресурсами МК, то лучше делать так . А чем вам DS3231 не угодил?

Вам нужно измерять напряжение 8 мВ с точностью 0,2мв? С одной стороны это всего 40 отсчётов, и можно  получить такую точность пользуясь любым встроенным АЦП с встроенным усилителем, но это в теории. На практике помехи от МК и питания проползут на вход, и устроят шум и гам, чем сделают такое измерение абсолютно не пригодным. Поэтому скорее всего придёться делать усилитель на  хотя бы самым простом инструментальном ОУ типа ad623, сделать ему отдельное чистое питание, и тогда результат будет хорошим. Или  всё-таки внешний ацп с встроенным усилением, и  тоже отвязка его от питания МК.

Маюсь, или сменить датчик, это 130 рублей где-то в + и на выходе 60-80 милливольт, уже что-то, если AD623 то они цены на неё не сложат, но там можно усилением и до 3-5 вольт добраться тоже +140 или 12 битную ацп, Вы где-то приводили ссылку на букашку, где-то тоже в этих пределах цен...
Да, заказал 16 битный 4 канальный ацп, в пути - и по IIC и по ценам приемлемо, надо макетировать однако

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

Я правильно понимаю, на таймерах, это так:

volatile uint8_t minut=0;
volatile uint8_t chas=0;
volatile uint8_t sec=0;

void setup(){
Serial.begin(9600);
TCCR1A=(1<<WGM11); //режим14 FAST PWM 
TCCR1B=(1<<CS12)|(1<<WGM13)|(1<<WGM12); //делить частоту CPU на 256
ICR1=62499;  // (16000000MHz /div256) -1 = 1 раз в секунду
TIMSK1=(1<<TOIE1); //разрешить прерывание
}

ISR (TIMER1_OVF_vect) { 
sec++ ; //инкремент переменной каждую секунду
if (sec>59){sec=0; minut++; }
if (minut>59){minut=0; chas++; }
if (chas>23){chas=0;}
}

void loop(){
Serial.print(chas);
Serial.write(':');
Serial.print(minut);
Serial.write(':');
Serial.print(sec);
Serial.println();
}

 

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

ua6em пишет:

Да, заказал 16 битный 4 канальный ацп, в пути - и по IIC и по ценам приемлемо, надо макетировать однако

А мне уже такой приехал, неделю назад его доковырял. Годная штука. 

И был он на 10 центов дешевле, в середине октября до скидок и распродаж заказывал )))

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

Мне его 4 16 битных канала точно ни к чему, пока ни к чему

По коду, 12 часов 40 минут, в секунду укладываюсь )))
Точнее подстроить, нужен прогон дней 10 хотя бы
 

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

Это без сто грамм не одолеешь, но оно мне надо:

TCCR1A=(1<<WGM11); //режим14 FAST PWM 
TCCR1B=(1<<CS12)|(1<<WGM13)|(1<<WGM12); //делить частоту CPU на 256
ICR1=62499;  // (16000000MHz /div256) -1 = 1 раз в секунду
TIMSK1=(1<<TOIE1); //разрешить прерывание

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ua6em, а что вам нужно? Понять как это работает -так это надобно изучать таймеры. Погуглите книжку Евстифеев микроконтроллеры avr семейства mega, я пор ней учился.

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

ua6em пишет:

Это без сто грамм не одолеешь, но оно мне надо:

TCCR1A=(1<<WGM11); //режим14 FAST PWM 
TCCR1B=(1<<CS12)|(1<<WGM13)|(1<<WGM12); //делить частоту CPU на 256
ICR1=62499;  // (16000000MHz /div256) -1 = 1 раз в секунду
TIMSK1=(1<<TOIE1); //разрешить прерывание

 

Одолею с 50 грамм!

Это аппаратноспецифическое. Я понимаю Ваш настрой, как и другие тру програмеры стараюсь избегать такого. Но это не всегда удается. Приходится иногда привязывать код к аппаратной части где нельзя избежать или избегать накладно. Но есть отдельно взятые товарищи, зачастую происхождением из электронщиков, которым такое как бальзам на раны а даташит страниц на 500 за любимый сериал. Для них идеальный код - его отсутствие, на крайняк сетап шоб инитить всю ету хрень ;) Это и есть одна из основ местных холиваров.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

ua6em пишет:

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

раскрой лучше тему запуска таймера немогучим специалистам:

3      if (millis() - previousMillis >=500) // здесь таймер не запускаем?
 
 
06    millis();  // а, здесь запуcкаем таймер?

как так?

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

я почитал по аппаратным таймерам, даже мысли возникли, а ежели к примеру тактировать оный от "Гиацинта" то можно получить очень точные таймера. Гиацинт и сейчас можно найти на развалах, по цене где-то в 10 тыщ. Его "Лунники" используют в конверторах на высоких частотах как опору.
Я так понимаю код снимает ограничение millis() в 50 дней?
В реальных часиках написаных на миллис (код которых я видел) вводят еще одну переменную, счётчик с даты последней синхронизации и от него отталкиваются, синхронизируя его через милс и он не 16 битный
 

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

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

каюсь...каюсь...каюсь...

но сути это не меняет жеж

 

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

ua6em пишет:

Я так понимаю код снимает ограничение millis() в 50 дней?

какой код какое ограничение снимает?

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

ua6em пишет:

Согласен, но КОД (С) http://arduino.ru/forum/programmirovanie/chasy-i-arduino
Я даже комментарии не удалял,
просто поправил алгоритмс )))

серьёзно? - просто поправил алгоритм?

previousMillis = millis();  //запучкаем таймер

заменил на?

millis();  //запуcкаем таймер

первое запускает таймер, а второе что делает?

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

Клапауций 234 пишет:

ua6em пишет:

Согласен, но КОД (С) http://arduino.ru/forum/programmirovanie/chasy-i-arduino
Я даже комментарии не удалял,
просто поправил алгоритмс )))

серьёзно? - просто поправил алгоритм?

previousMillis = millis();  //запучкаем таймер

заменил на?

millis();  //запуcкаем таймер

первое запускает таймер, а второе что делает?

Выпейте кофейку, в рабочем коде нет второго, а если бы даже было то считайте это командой NOP
...я понял ...Вы обиделись...
на меня кофе уже подействовало )))
 

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

ua6em пишет:

Выпейте кофейку, в рабочем коде нет второго, а если бы даже было то считайте это командой NOP
...я понял ...Вы обиделись...
на меня кофе уже подействовало )))

в каком коде нет какого кода и на что я обиделся?

я спросил, что делает в твоём коде millis();  //запуcкаем таймер

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

Клапауций 234 пишет:

ua6em пишет:

Выпейте кофейку, в рабочем коде нет второго, а если бы даже было то считайте это командой NOP
...я понял ...Вы обиделись...
на меня кофе уже подействовало )))

в каком коде нет какого кода и на что я обиделся?

я спросил, что делает в твоём коде millis();  //запуcкаем таймер

 

Мы уже с Вами на ты???
Оригинально, Король Иордании Хусейн меня на ты не называл, Раджив Ганди тоже, по имени да, но не на ты... быдлимс???

КОД функции:

// Clock - Timer
// Часы реализованные через millis()
//  Измеренная точность хода 2 миллисекунды в сутки

void myClock01()
   {
     if (millis() - previousMillis >=500) 
   {  
   previousMillis = previousMillis + 496; // корректировка на наш кварц и задержки в коде
      digitalWrite(53, !digitalRead(53)); // меняем значение порта каждые 0.5секунд
   
   if(digitalRead(53)==HIGH)              // если 53 нога лог1 то...
   {
     sek++;                               // переменная секунда + 1
    
   
    }
   
   if(digitalRead(53)==LOW)
   {
                                          // через каждые 0.5 секунд меняем символ ":" на "."
                                          // здесь будет город заложон, а пока изменений показаний секунд достаточно
   }
   
   if(sek>59)                             // если переменная секунда больше 59 ...
   { 
     sek=0;                               // сбрасываем ее в 0
     min++;                               // пишем +1 в переменную минута
      previousMillis = previousMillis - 7;// корректировка раз в минуту точнее 6.82м сек
   }
      
   if(min>59)//если переменная минута больше 59 ...
   {
     min=0;//сбрасываем ее на 0
     chas++;//пишем +1 в переменную час
     previousMillis = previousMillis + 62; // корректировка раз в час на 62 миллисекунды
    }
   
   if(chas >23)//если переменная час больше 23 ...
   {
     chas=0;//сбрасываем ее на 0
     previousMillis = previousMillis + 12; // корректировка раз в сутки на 12 миллисекунд
    }
      
                                           // вывод символов на дисплей чтобы ничего не блымало выводим единой строкой
    String str001 = String(chas);
    String str002 = String(min);
    String str003 = String(sek);
     utftDisplay.setFont(SevenSegmentFull);
     utftDisplay.setColor(0, 255, 173);   // цвет а ЛЯ "Я мортал того комбата"
                                          // и никакой математики, всё в лоб
   if (chas>=0 && chas<10 && min>=0 && min<10) {
       utftDisplay.print("0"+str001 + ":" + "0"+str002, 5,  7);}
     if (chas>=0 && chas<10 && min>=10) {
       utftDisplay.print("0"+str001 + ":" + str002, 5,  7);}
       if (chas>=10 && min>=0 && min<10) {
       utftDisplay.print(str001 + ":" + "0"+str002, 5,  7);}
         if (chas>=10 && min>=10) {
         utftDisplay.print(str001 + ":" + str002, 5,  7);}
         
                                          // секунды выводим другим шрифтом
         utftDisplay.setFont(BigFont);
         
         if (sek>=0 && sek<10) {
         utftDisplay.print(":0" + str003, 167, 7);}
          if (sek>=10) {
         utftDisplay.print(":" + str003, 167, 7);}
         
  } 
 

 

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

ua6em пишет:

Мы уже с Вами на ты???

сколько тебе лет?

ua6em пишет:

КОД функции:

куда внезапно исчезла строка? millis();  //запуcкаем таймер

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

 previousMillis = previousMillis + 496; // корректировка на наш кварц и задержки в коде

что делать, когда время исполнения кода не постоянная величина?

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

как бы понятно, что существует две величины, влияющие на точность часов:

- точность кварца.

- время исполнения кода.

но, категорически неправильно считать эти величины постоянными и брать их с потолка.

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

Клапауций 234 пишет:

 previousMillis = previousMillis + 496; // корректировка на наш кварц и задержки в коде

что делать, когда время исполнения кода не постоянная величина?

Менять программиста )))
я очень в курсе о написание ОС реального времени (правда на языке ассемблера и даже в тактах процессора)

понятно и ребёнку, что постоянная 496 это для конкретного устройства?
Если не понятно, озвучу:

ВСЕ КОНСТАНТЫ РАСЧИТАНЫ ДЛЯ КОНКРЕТНОГО МОЕГО УСТРОЙСТВА
при повторении кода их придётся подобрать или
ребята НИКОГДА НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ НЕ ИСПОЛЬЗУЙТЕ ЭТОТ КОД )))

Извечный вопрос - Что делать?
- Использовать правильный код

volatile uint8_t minut=0;
volatile uint8_t chas=0;
volatile uint8_t sec=0;

void setup(){
Serial.begin(9600);
TCCR1A=(1<<WGM11); //режим14 FAST PWM 
TCCR1B=(1<<CS12)|(1<<WGM13)|(1<<WGM12); //делить частоту CPU на 256
ICR1=62499;  // (16000000MHz /div256) -1 = 1 раз в секунду
TIMSK1=(1<<TOIE1); //разрешить прерывание
}

ISR (TIMER1_OVF_vect) { 
sec++ ; //инкремент переменной каждую секунду
if (sec>59){sec=0; minut++; }
if (minut>59){minut=0; chas++; }
if (chas>23){chas=0;}
}

void loop(){
Serial.print(chas);
Serial.write(':');
Serial.print(minut);
Serial.write(':');
Serial.print(sec);
Serial.println();
}

, для точности хода подключив "Гиацинт"

 

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

ua6em пишет:

Менять программиста )))

программиста например такого кода нужно менять? - время его исполнения зависит от условия.

void loop() {
if (условие) {что-то сделать;}
}

ua6em пишет:

я очень в курсе о написание ОС реального времени (правда на языке ассемблера и даже в тактах процессора)

*прекращай прыгать с темы на тему - об ОС реального времени тебя никто не спрашивал.

ua6em пишет:

понятно и ребёнку, что постоянная 496 это для конкретного устройства?

какого конкретно устройства?

какой смысл постить код для никому не известного устройства?

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

ua6em пишет:

понятно и ребёнку, что постоянная 496 это для конкретного устройства?

Какому ребенку понятно? фото и видео где ребенок понимает назначения констант в студию!

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

Mr.Privet пишет:

ua6em пишет:

понятно и ребёнку, что постоянная 496 это для конкретного устройства?

Какому ребенку понятно? фото и видео где ребенок понимает назначения констант в студию!

зачем тебе фото ТС?

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

Mr.Privet пишет:

ua6em пишет:

понятно и ребёнку, что постоянная 496 это для конкретного устройства?

Какому ребенку понятно? фото и видео где ребенок понимает назначения констант в студию!

Щёлкаете зомбоящик и на первом "Лучше всех" и на втором "Синяя птица" канале будет вам видео )))
Да и здесь на сайте, кто-то выкладывал коды своего чада

И вообще, я мастер по переливанию из пустого в порожнее, у меня и сертификат имеется )))

 

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

Протестировал оба решения часов и программное на millis() и на таймере с использованием прерывания, результат:
1.На миллис достигнута точность хода менее 1 секунды в сутки, это сопоставимо с DS1307

2. Таймер, при всей правильности решения - разочаровал, точность хода (часы отстают) на 1 минуту 27 секунд за 3-х часовой прогон

Расчётные корректирующие программные задержки в миллисекундах 1 секунда - 8 миллисекунд, 1 минута - 1 миллисекунда, 1 час - 2 миллисекунды, 24 часа - 14  (на такие уставки корректируется время в обозначенные промежутки)

Если реализуется через millis() в минуту задержка составляет 481 миллисекунда, а ежели через прерывание 2068,96 миллисекунд

ГУРУ, я ничего не напутал???

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

Напутали. Оба подхода при правильной реализации эквивалентны. Точность хода зависит только от точности кварца. Ну с учетом поправок конечно, но они при изменении температуры увы не выручат. 

nik182
Offline
Зарегистрирован: 04.05.2015

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

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

Logik пишет:

Напутали. Оба подхода при правильной реализации эквивалентны. Точность хода зависит только от точности кварца. Ну с учетом поправок конечно, но они при изменении температуры увы не выручат. 

Код через прерывание брал такой
 

volatile uint8_t minut=0;
volatile uint8_t chas=0;
volatile uint8_t sec=0;

void setup(){
Serial.begin(9600);
TCCR1A=(1<<WGM11); //режим14 FAST PWM 
TCCR1B=(1<<CS12)|(1<<WGM13)|(1<<WGM12); //делить частоту CPU на 256
ICR1=62499;  // (16000000MHz /div256) -1 = 1 раз в секунду
TIMSK1=(1<<TOIE1); //разрешить прерывание
}

ISR (TIMER1_OVF_vect) { 
sec++ ; //инкремент переменной каждую секунду
if (sec>59){sec=0; minut++; }
if (minut>59){minut=0; chas++; }
if (chas>23){chas=0;}
}

void loop(){
Serial.print(chas);
Serial.write(':');
Serial.print(minut);
Serial.write(':');
Serial.print(sec);
Serial.println();
}

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

О кварце, речь изначально шла о конструкции из поднебесной И, ТАМ И ЗДЕСЬ УСЛОВИЯ ОДНИ И ТЕ ЖЕ

 

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

nik182 пишет:

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

Видимо не совсем то же прерывание ))) Никто не дизассемблировал и не смотрел код миллис?
Такие задержки можно объяснить только тем (если рассматривать по аналогии с интел процессорами), что при прерывании приходится сохранять а затем вытаскивать из стека большой объём данных, миллис оно то на 0 прерывание, так? видимо есть разница на аппаратном уровне?

Тут еще программирования как бы и нет, так баловство, программирование это когда рождённые в муках часов за десять 400 строк текста парсера на "ЧИСТОМ PHP" парсят и приводят в нужный вид базу данных в 40-50 тысяч записей за 6 секунд, а здесь РАЗВЛЕКАЕМССИ

GarryC
Offline
Зарегистрирован: 08.08.2016

1. Не надо ничего дизассемблировать, исходный код для работы с временем лежат себе спокойно в файле ..\hardware\arduino\avr\cores\arduino\wiring.h.

2. Не надо привлекать аналогии, это AVR и тут все просто.

3. Если что то делаешь, то делай это хорошо, иначе не делай совсем - универсальное правило.

nik182
Offline
Зарегистрирован: 04.05.2015

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

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

GarryC пишет:

1. Не надо ничего дизассемблировать, исходный код для работы с временем лежат себе спокойно в файле ..\hardware\arduino\avr\cores\arduino\wiring.h.

2. Не надо привлекать аналогии, это AVR и тут все просто.

3. Если что то делаешь, то делай это хорошо, иначе не делай совсем - универсальное правило.

через прерывание написан плохо али как?

Почитал про таймера - "Тогда наша секунда обеспечивается с точностью 8000 000 плюс минус 256 тактов. Не велика погрешность, всего 0,003%."
То-есть на 16 мегагерцах это 6 миллисекунд, как и на millis()
И...зачем городить огород...???

А на какие пины на mega2560 выведено под второй кварц? не найду что-то

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ua6em, какие-то нереальные цифры вы получили. С таким отрывом от реальности  работает например внутренний  RC-осциллятор мк, но никак не кварц. Счас накатаю прогу по быстрому, сам проверю..

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

dimax пишет:

ua6em, какие-то нереальные цифры вы получили. С таким отрывом от реальности  работает например внутренний  RC-осциллятор мк, но никак не кварц. Счас накатаю прогу по быстрому, сам проверю..

И моя mega2560 ))) - она правда сначала никак не хотела общаться с дисплеем по IIC, может просто неисправна, а я тут на уши всех поднял...

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

ua6em пишет:

через прерывание написан плохо али как?

Почитал про таймера - "Тогда наша секунда обеспечивается с точностью 8000 000 плюс минус 256 тактов. Не велика погрешность, всего 0,003%."
То-есть на 16 мегагерцах это 6 миллисекунд, как и на millis()

))) Да. Верно написано. Только это не противоречит тому что и на таймере и на millis() точность одинакова и выше чем у Вас получилась. Просто если секунда ушла, допустим в плюс, то следующая (или предыдущая) уйдет в минус и компенсирует. Получается 1сек +-256 тактов и 2сек тоже +-256 тактов и сутки тоже +-256 тактов, это не совсем погрешность, она не обладает свойством адитивности. В общем если пересчет реализован верно (миллис или прерывания - без разницы), то сутки по часам ардуины будут соответствовать 24*60*60*16000000 тактов. Но это не будет совпадать с 24часами реального времени, т.к. один такт не равен в точности 1/16000000сек. Погрешность именно здесь она не большая обычно до 10 сек в сутки  и целиком зависит от кварца.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

правильные часы так нужно писать #5

unsigned long RTC_TIC_M16 = 0;

ISR (TIMER2_OVF_vect) {RTC_TIC_M16++;} // обработка событий по прерыванию счётчика

void setup() {
///////////////////////////////////////////////////////////////////
cli(); // запрет прерываний глобально
TIMSK &= ~(_BV(TOIE2) | _BV(OCIE2)); // отключение прерывания Таймера 2
ASSR |= _BV(AS2); // перевод Таймера 2 в асинхронный режим тактирования от кварцевого резонатора 32768Гц
TCNT2 = 0x00; // начальная инициализация счётчика
TCCR2 = 0x05; // установка коэффициента деления 128
OCR2  = 0x00; // совпадение с частотой 1 Гц
while (ASSR & (_BV(TCN2UB) | _BV(OCR2UB) | _BV(TCR2UB))); // ждём готовности таймера
TIMSK |= _BV(TOIE2); // разрешаем прерывание от Таймера 2
sei(); // разрешаем прерывания глобально
///////////////////////////////////////////////////////////////////
}

void loop() {}

 

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

нет, вы невнимательно читали документацию по прерываниям, у нас нет никакой возможности считать данные из одного управляющего регистра, считываем косвенно, точность +-256 тактов процессора, то-есть 1000 миллисекунд мы определяем с точностью 6 миллисекунд, у меня эти 6 миллисекунд вылезли на функции millis(), я их и корректирую два раза в секунду в программных часах, точность корректировки 1 миллисекунда, если делать на таймерах точность корректировки 1 секунда (в тысячу раз больше), есть техническая возможность использовать высокостабильный кварц на 100 килогерц, процессор позволяет, но я не нашёл к каким пинам mega2560 его подключить, но это как бы штучное изделие.

Резюме в другом (если mega2560 исправна) сделать высокостабильные часики на прерываниях на стандартном mega2560 без использования стронних модулей часов НИЗЗЯ, А ПРОГРАММНО - МОЖНО!

Если кто-то считает обратное скетч в студию...без бла...бла...бла...

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

Клапауций 234 пишет:

правильные часы так нужно писать #5

unsigned long RTC_TIC_M16 = 0;

ISR (TIMER2_OVF_vect) {RTC_TIC_M16++;} // обработка событий по прерыванию счётчика

void setup() {
///////////////////////////////////////////////////////////////////
cli(); // запрет прерываний глобально
TIMSK &= ~(_BV(TOIE2) | _BV(OCIE2)); // отключение прерывания Таймера 2
ASSR |= _BV(AS2); // перевод Таймера 2 в асинхронный режим тактирования от кварцевого резонатора 32768Гц
TCNT2 = 0x00; // начальная инициализация счётчика
TCCR2 = 0x05; // установка коэффициента деления 128
OCR2  = 0x00; // совпадение с частотой 1 Гц
while (ASSR & (_BV(TCN2UB) | _BV(OCR2UB) | _BV(TCR2UB))); // ждём готовности таймера
TIMSK |= _BV(TOIE2); // разрешаем прерывание от Таймера 2
sei(); // разрешаем прерывания глобально
///////////////////////////////////////////////////////////////////
}

void loop() {}

К каким ногам ардуино нано подключаем правильный резонатор 32768, если XTAL подключен 16 мегагерц?

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

ua6em пишет:

К каким ногам ардуино нано подключаем правильный резонатор 32768, если XTAL подключен 16 мегагерц?

#5

*так и подмывает спросить у этих шустрых и невнимательных: вами в постели довольны жёны? потому, как 30 секунд - это дурь какая-то, а не секс.

nik182
Offline
Зарегистрирован: 04.05.2015

Давайте определимся что такое программый и что такое аппаратный. Чисто программно сделать часы с хорошей точностью очень трудно. Аппаратный таймер с программной коррекцией? 

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

nik182 пишет:

Давайте определимся что такое программый и что такое аппаратный. Чисто программно сделать часы с хорошей точностью очень трудно. Аппаратный таймер с программной коррекцией? 

давайте определимся - давай.

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

ua6em пишет:

Если кто-то считает обратное скетч в студию...без бла...бла...бла...

Наториально завереный с мокрой печатью и цифровой подписю?

Думаю ограничитесь картинками.

Скоко там разница времени между фотками, 25 мин. Считаем уход при погрешности 6мсек/сек 25*60*0.006=9сек. Где они? Вы их видите. Звеняйте за фотку вверх ногами, перевернул её на мобиле и вот )))

В скетче обычный милис, без коррекций, RTC в проекте есть, раз в сутки вычитываются.

ПС. Не думайте что сказали новое слово в прорграммировании МК и весь мир ретроградов гнобит Вас. Все это старо как мир, за последнии 20 лет лично отвечаю;) 

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

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

Кстати, выложите свой код с милис, я знаю где у Вас лажа ))

 

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

я сам могу показать картинки часиков реализованных на millis c точностью хода лучше одной секунды в сутки (поправки выставлены для конкретной ардуины), ну и что?
мы говорим о часиках на таймерах без внешнего часового кварца (стандартная ардуина) с аналогичной точностью, покажите скетч

Речь идёт об алгоритме, я добиваюсь этого корректируя 2 раза в секунду, раз в минуту, раз в час и раз в 24 часа и корректирующее воздействие выражается в миллисекундах (умножаемая дробная часть от нестабильности хода)

Можно сделать и на таймерах и я даже имею представление как, хотелось бы увидеть у профессионалов, правильный ли ход моих мыслей аль заблуждаюсь - в ответ пока только ля-ля