Великое переполнение millis()

maxvalin
Offline
Зарегистрирован: 22.02.2016

А для нуб-использования нужно начинать с вот этой небольшой книжки, ее то я и читал. Скажу честно, становится скучно в виду того что в ней удар идет далеко не в сторону МК. Да, вы сейчас скажете что если такой баран что не вижу что это все одно и тоже и что конкретно под писанину МК книгу мне и никогда не найти,  тоже скажу да.  Ибо я уже такую искал)))  Почитал,  принцип понял,  тонкости в разжовывании синтекса там нет.  Даже и не пахнет.  Для людей-железяк, тоисть таких как я сложно "перефразировать" язык для "текста" в язык для "железа" Хоть это одно и тоже.  По этому мы и здесь,  на форуме.  Что для вас программеров пол пинка то для нас пол-дня.  А возраст уже не позволяет сколько времени уделять.  Да и смысл нашего с вами здесь сосуществования,  мы железяки никогда вашу нишу программеров не займем- склад ума разный.  А учим лишь для мелочных задумок которые вам не составят конкуренции ну никак.  Вот вы послали в эту книжку за то что я попросил расписать по принципу обучения первый пост.  Это уже реакция невозвратима- не напишет никто из вас эти несчастные 5 строчек. Тогда нужно перекраивать ввесь форум,  везде убирать,  уровень блинка и отсылать всех в книгу.  Вопрос:в чем изъян именно моего вопроса?  Он такой же как и остальные.  Отличается только тем что пошел против шерсти.  

И хватит Ваньку чмырить)))  мы тут большая половина не программисты,  и ничего.  Есть другое в жизни. Не лишайте человека познать кайф от рыбалки только изза того что он рыбой не пахнет

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

maxvalin пишет:

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

чем ты занят, старик? - геморрой и альцгеймер лечишь?

maxvalin пишет:

мы железяки никогда вашу нишу программеров не займем- склад ума разный. 

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

не понятно тебе? - твои действия:

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

2. далее: бросить или курить тему до полного излечения альцгеймера.

maxvalin
Offline
Зарегистрирован: 22.02.2016

Ты вообще своеобразный чел) 

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

Без обид). Мы же ведь образованные люди и не будем бежать водку пить изза того что чего то не можем осилить

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

maxvalin пишет:

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

у меня четыре недоенных козы - почему я должен заставлять жывотину мучитьсся и тратить на твоих детей своё личное время?

maxvalin пишет:

Если тебе изза этого жалко оторвать от мозга какуюто строку с подсказкой...

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

ven-til
Offline
Зарегистрирован: 13.02.2018

ЕвгенийП пишет:

но вот хотя бы вот такую малюсенькую книжку для совсем чайников изучите - ну себя же больше уважать будете.

Ой, а там очепятка -

Примечание: Целые переменные будут переполняться, если форсировать их
переход через максимум или минимум при присваивании или сравнении.
Например, если x = 32767 и следующее выражение добавляет 1 к x, x = x +1 или
x++, в этом случае x переполняется и будет равен -32678.

Как раз на великом переполнении

maxvalin
Offline
Зарегистрирован: 22.02.2016

Клапауцый,  ну ты уж точно ничего не должен,  заметь, тебя редко кто о чем просит.  Ты бы людей от скотов отличил для начала бы.  На тебя никто вилы тут не наставлял,  зачем на себя одеяло перетягиваешь.  Я конкретно задал вопрос автору темы,  никого не трогал.  Есть желание оторвать оторвет он или кто другой,  если ты захочешь то и ты.  Но зачем отрывать себя от важных дел как скотина на людей?  Давай будем прекращать этот глупый разговор,  я не прав в виду своего вопроса и только.  Мог бы удалил свои посты.  За это уже извинился. 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

maxvalin, не тут здесь программеров вообще. Им здесь скучно с нами. И не существует человек железчников и все что вы тут написали. Это все просто просто издержки недоучивания и прочего. Вам как хорошо воспринимать объянения учителя : лежа на правом ухе или на левом , с отрытыми глазами или их закрыть.  А если вам скажут что надо сесть ровно , смотреть на доску и внимательно слушать учителя, то вы запоете , что вы не учится пришли, а так поспать, потому что под объсянение спится замечательно. 

  Так что вы решайте. Или вы серьезно учитесь и через не могу, или вы так посвистеть пришли. А если посвистеть, то не жалуйтесь, что вас так воспринимают. ПС: мне тоже в этой жизни не стать программером, ну ни как. Так я не вою.

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

maxvalin пишет:

Но зачем отрывать себя от важных дел как скотина на людей?

верно - люди сами о себе способны позаботиться, а домашняя скотина - нет.

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

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

maxvalin,  ваш "пример" из сообщения #35 по смыслу полностью аналогичен тому тексту Евгения. что вы просите обьяснить.

А код Евгения кажется сложным, потому что он не предназначен быть заготовкой скетчей для новичков. Он написан для того, чтобы наглядно показать разницу между сложением и вычитанием миллис. Поэтому в нем нет комментрариев "вставлять свой код сюда" - это не шаблон для ваших скетчей, это пособие для изучения.

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

А еще вот длинные список по IT книжкам на самые разные темы. Можно посмотреть оглавление, почитать выложенные для просмотра главы - чтобы решить стоит ли искать эту книжку целиком или нет:

http://it-ebooks.info/

Только не спрашивайте, где потом эти книги скачать :)  - это сами

 

maxvalin
Offline
Зарегистрирован: 22.02.2016

Ну,  надеюсь все довольны остались. 

 

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

maxvalin пишет:

Ну,  надеюсь все довольны остались. 

смотри - сухая статистика:

твой первый пост Пнд, 19/03/2018 - 16:08

твой последний пост Пнд, 19/03/2018 - 20:09
 
я - подоил коз, ты - ******* 4 часа.
maxvalin
Offline
Зарегистрирован: 22.02.2016

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

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

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

смотри - сухая статистика:

твой первый пост Пнд, 19/03/2018 - 16:08

твой последний пост Пнд, 19/03/2018 - 20:09
 
 

Сухая статистика в другом - человек "увлекается ардуиной" более 2х лет....

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

maxvalin пишет:

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

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

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

maxvalin пишет:

А для нуб-использования нужно начинать с вот этой небольшой книжки, ее то я и читал. Скажу честно, становится скучно в виду того что в ней удар идет далеко не в сторону МК.

Наоборот, в ней слишком много "в сторону МК". Т.е. свалка отрывочных сведений без какого-либо фундамента.

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

Цитата:

Почитал,  принцип понял,  тонкости в разжовывании синтекса там нет.  Даже и не пахнет.

Для "тонкости в разжовывании синтекса" - это Кернига и Ритчи.

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

Цитата:

 Вопрос:в чем изъян именно моего вопроса?  

В том, что он на этом форуме оффтопик.

Форум посвящен Ардуино. Даже не программированию. И тем более - не обучению программированию.

Цитата:

Он такой же как и остальные.

Забавная логика: если другие пишут чушь, то и мне позволительно писать чушь. Что ж тогда жаловаться на реацию окружающих?

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

Требовать, чтобы Вас стали обучать азбуке в литературном кржке, - минимум, неуважение к окружающим.

PS. Для ненаблюдательных отмечу: профессиональные литераторы в литературные кружки не ходят. Литрертурные кружки - удел исключительно любителей.

maxvalin
Offline
Зарегистрирован: 22.02.2016

Адриано,  я уже не понимаю по чем этот форум вообще.  Не программирование,  не обучаемости.. Наверное болше по быдлотолканию. То что я спросил не может по сути так выворачивать все наизнанку.  При том что уже извинился и не один раз,  продолжаете заниматься "быдлотолканием" как для меня,  то лично пофиг на те миллисы я и так разберусь.  Но этож жуть так ПОпереть всем стадом.  Никто даже и не подумал просто "замять" тему.  

 

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

maxvalin - вы ж сами подталкиваете тему именно к флуду. Отвечаете только на пустой треп, а между тем я в сообщении #59 попытался ответить на ваши вопросы... Реакции - ноль.

Толи все понятно, толи "быдлотолканье" интереснее...

maxvalin
Offline
Зарегистрирован: 22.02.2016

Я внимательно читал ваше сообщение.  Адекватный ответ,  за это большое спасибо!

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

maxvalin, это форум показывания своего опыта, а не получения отсюда. Придумали "гениальную идею", реалиализавали, заболели "звезной болезнью". выложили сюда, вас обхаяли и вы дальше уже тянете лямку , без всякого "зазвездется". Так что скетчи выклыдывайте сюда и вас вылечат. https://www.youtube.com/watch?v=OE584H8xYaM

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

qwone пишет:

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

))) А ведь так!

maxvalin
Offline
Зарегистрирован: 22.02.2016

Евгений, вопрос именно к вам, третий вывод, в двух словах: из-за чего?

это уж точно не "офтопик"

//////////////////////////////////////////////////////////////////////
//
// ПРАВИЛЬНОЕ использование millis() - плевать на переполнение
//
// Сделано так, чтобы millis() переполнился через 5 секунд после старта
// программа же отсчитывает двухсекундные интревалы (в функции make2SecondsInterval)
// Так что переполнение millis  придётся на середину интервала
// Запускаем и смотрим на происходящую "катастрофу"
//
template <typename T> inline Print & operator << (Print &s, T n) { s.print(n); return s; }
extern volatile unsigned long timer0_millis;

static void make2SecondsInterval(void) {
  uint32_t startTime = millis(), currentMillis;
  while ((currentMillis = millis()) - startTime < 3000ul); // ТАК НАДО !!!
  Serial << " start: " << startTime << "\nmillis: " << currentMillis <<
          "\ndiffer: " << (currentMillis - startTime) << "\n---\n";
}

void setup (void) {
  Serial.begin(115200);
  //
  // Устанавливаем счётчик millis так, чтобы он переполнился через 5 секунд
  timer0_millis = UINT32_MAX - 19000ul;
  //
  // Отсчитываем 5 двухсекундных интервалов
  for (int i=0; i < 15; i++) make2SecondsInterval();
}

void loop(void) {}
//
// РЕЗУЛЬТАТ

 start: 4294948295
millis: 4294951295
differ: 3000
---
 start: 4294951296
millis: 4294954296
differ: 3000
---
 start: 4294954297
millis: 4294957298
differ: 3001
---
 start: 4294957299
millis: 4294960299
differ: 3000
---

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

maxvalin пишет:

третий вывод, в двух словах: из-за чего?

Ничего не понял :(

maxvalin
Offline
Зарегистрирован: 22.02.2016

3001

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Нецелыми частями накопилось, лишний раз прерывание попалось (Ваша программа прерывается каждые 4 микросекунды для внутренних нужд среды) и т.п. Мало ли что.

Pyotr
Offline
Зарегистрирован: 12.03.2014

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

if(millis() - prevMillis >= 4){ 
  prevMillis = millis(); 
  //сюда будем попадать через 4096 и иногда  3072 мксек
}  

Вот код, который показывает первые 256 возвращаемых значений миллис() в процессе "тиканья".
 

byte arr[256];
void setup() {
  for(word i=0; i<256; i++){
    arr[i] = millis();
    while(arr[i] == byte(millis()));//ждём пока "тикнет" millis()
  }
  Serial.begin(9600);
  for(word i=0; i<256; i++)  Serial.println(arr[i]);  
}

void loop(){}

millis() не возвращает 42, 85, 127, 170, 213, 255 и т.д.
 

maxvalin
Offline
Зарегистрирован: 22.02.2016

вчера когда эксперементировал с переполнением и подсчетом скорости выполнения самого скетча, заметил. Особенно в "счетчике цикла" я его на микросы настроил.

Микросы тоже не равномерны?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

maxvalin пишет:

Микросы тоже не равномерны?

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

maxvalin
Offline
Зарегистрирован: 22.02.2016

почти, скорее кратны 8-ми

4
12
20
24
32
40
48
56
64
68
76
84
88
96
104
112
120
128
132
140
148
152
160
168
172
180
188
196
204
212
216
224
232
236
244
252

ну и плюс неравномерность

Pyotr
Offline
Зарегистрирован: 12.03.2014

maxvalin пишет:

Микросы тоже не равномерны?

Думаю мой пример для микрос слишком медлителен. Сама функция микрос выполняется 3-4 мкс. 
А микрос "равномерен", там учитывается значение счетного  регистра TCNT0, который инкреминируется каждые 4 мкс.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

про микрос

On 16 MHz Arduino boards (e.g. Duemilanove and Nano), this function has a resolution of four microseconds (i.e. the value returned is always a multiple of four).

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

и мне как-та странна, этот микрос переполняется раз в 70 минут и ни одна жывая душа на этом форуме не задаеца вопросом "А есть ли жизнь после переполнения micros()?"

Olej
Olej аватар
Offline
Зарегистрирован: 05.03.2018

Pyotr пишет:

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

Вот это место сильно интересное... Так же (время системного тика чуть меньше 1mc) имеет место во всех процессорных семействах и всех операционных системах (или средах выполнения). Но это в точности соответствует представлениям реального времени и требованиям стандарта POSIX 1003b для реального времени: "фактические значения временных интервалов может быть сколь угодно больше заказанных, но никогда не может оказаться меньше". Или то же самое: единица шкалы измерения времени (1мс.) может быть меньше, но не смеет быть больше.

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

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

О, как!

Pyotr
Offline
Зарегистрирован: 12.03.2014

Вот мы и подошли к интересному моменту: а не "допилить" ли нам millis(), а точнее инструмент отсчета временных интервалов в Ардуино?

Навскидку что можно сделать.
Нужно переписать обработчик ISR(TIMER0_OVF_vect) из wiring.c

ISR(TIMER0_OVF_vect)
{
	// copy these to local variables so they can be stored in registers
	// (volatile variables must be read from memory on every access)
/*	unsigned long m = timer0_millis;
	unsigned char f = timer0_fract;

	m += MILLIS_INC;
	f += FRACT_INC;
	if (f >= FRACT_MAX) {
		f -= FRACT_MAX;
		m += 1;
	}

	timer0_fract = f;
	timer0_millis = m;
	timer0_overflow_count++;
*/
  //допишем две строки
  TCNT0 = 6;//подводим счетчик. Можно корректировать ход миллис, меняя константу (3-9)
  timer0_millis++;
}

Для плат 16 МГц. Теперь миллис не перескакивает. Но микрос работать правильно не будет и ШИМ от ТС0 тоже немного изменится.

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Pyotr пишет:

а не "допилить" ли нам millis(), а точнее инструмент отсчета временных интервалов в Ардуино?

А нада? Каму?

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

От молодец. Пришёл, сломал миллис, микрос, ШИМ и свалил. А нам что теперь со всем этим делать?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:

А нам что теперь со всем этим делать?

Как что? Принять 200-250 кубиков патентованного среццтва от DetSimen (внутриглоточно) и наблюдать за развитием событий.

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

Pyotr пишет:

Вот мы и подошли к интересному моменту: а не "допилить" ли нам millis(), а точнее инструмент отсчета временных интервалов в Ардуино?

Навскидку что можно сделать.

Нужно ввести 

uint64_t mibis(); // возвращает время в 4-мкс единицах

при этом mibis() << 2 будет равен micros(), а mibis() >> 8 будет примерно равен millis(), но без "перескоков".

Заодно раз и навсегда решает проблему ТОПИКА (по крайней мере, на ближайшие два миллиона лет).

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

andriano пишет:
решает проблему ТОПИКА (по крайней мере, на ближайшие два миллиона лет).

Ну, да. Сделаем изделие, вроде работает, а через 2 397 574 лет - бамс! Приехали! Нельзя так безответсвенно подходить к проектированию!

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

ЕвгенийП пишет:

andriano пишет:
решает проблему ТОПИКА (по крайней мере, на ближайшие два миллиона лет).

Ну, да. Сделаем изделие, вроде работает, а через 2 397 574 лет - бамс! Приехали! Нельзя так безответсвенно подходить к проектированию!

Неправда Ваша.

У нас еще больше 2 месяцев в запасе.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

andriano пишет:

У нас еще больше 2 месяцев в запасе.

Этой отмазкой Вы пытаетсь прикрыть безответсвенность и халтруру! :)

Olej
Olej аватар
Offline
Зарегистрирован: 05.03.2018

Pyotr пишет:

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

Вообще то, то как это происходит, в большинстве случаев, не важно. Но интересно представлять как они производят эту корректировку (изредка это может дать эффекты, которые сильно трудно будет толковать на отладке). Сделал специально такой тестовый код:

#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;  
}

Вот что он даёт:

 

Olej
Olej аватар
Offline
Зарегистрирован: 05.03.2018

Olej пишет:

Вот что он даёт:

Вот как это происходит по умолчанию (если не влазить в этот процесс): коррекция производится чаще через 43, реже через 42 последовательных вызовов millis().

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Olej пишет:

Вот что он даёт:

Вы и впрямь здесь что-то видите? Или прикидываетесь?

Pyotr
Offline
Зарегистрирован: 12.03.2014

Ну вобщем дурная голова рукам покоя не дает..)

Покажу что получилось. Даже работает...

//кусок кода из wiring.c
#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ISR(TIM0_OVF_vect)
#else
ISR(TIMER0_OVF_vect)
#endif
{
/*	// copy these to local variables so they can be stored in registers
	// (volatile variables must be read from memory on every access)
	unsigned long m = timer0_millis;
	unsigned char f = timer0_fract;

	m += MILLIS_INC;
	f += FRACT_INC;
	if (f >= FRACT_MAX) {
		f -= FRACT_MAX;
		m += 1;
	}

	timer0_fract = f;
	timer0_millis = m;
	timer0_overflow_count++;
*/
    //допишем две строки
  TCNT0 = 5;//подводим счетчик.
  timer0_millis++;
}

unsigned long millis()
{
	unsigned long m;
	uint8_t oldSREG = SREG;

	// disable interrupts while we read timer0_millis or we might get an
	// inconsistent value (e.g. in the middle of a write to timer0_millis)
	cli();
	m = timer0_millis;
	SREG = oldSREG;

	return m;
}

unsigned long micros() {
/*	unsigned long m;
	uint8_t oldSREG = SREG, t;
	
	cli();
	m = timer0_overflow_count;
#if defined(TCNT0)
	t = TCNT0;
#elif defined(TCNT0L)
	t = TCNT0L;
#else
	#error TIMER 0 not defined
#endif

#ifdef TIFR0
	if ((TIFR0 & _BV(TOV0)) && (t < 255))
		m++;
#else
	if ((TIFR & _BV(TOV0)) && (t < 255))
		m++;
#endif

	SREG = oldSREG;
	
	return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
*/
//новая функция
  unsigned int m;
  uint8_t oldSREG = SREG, t;
  t = TCNT0;//5-255
  cli();
  m = timer0_millis;
  SREG = oldSREG;
  return (((m & 0x3F) * 1000) + 4*(t-5));
}

void delay(unsigned long ms)
{
  /*	uint16_t start = (uint16_t)micros();
  
  	while (ms > 0) {
  		yield();
  		if (((uint16_t)micros() - start) >= 1000) {
  			ms--;
  			start += 1000;
  		}
  	}
  */
  //новая функция
  uint16_t k = 64000;
  uint32_t start = micros();
  uint32_t carrMicros = start;
  while (ms > 0) {
    yield();
    carrMicros = micros();
    if((carrMicros + k - start) % k >= 1000) {
      ms--;
      start = carrMicros;
    }
  }
}

Прерывание по переполнению ТС0 теперь каждые 1000 мкс. Было 1024 мкс. Обработчик стал короче.
millis() без изменения. Не "перескакивает".
micros() переполняется чез 64 мс.

Код показывает возвращаемые значения миллис и микрос

unsigned long a, b;
void setup() {
  {
  byte arr[256];
  for(word i=0; i<256; i++){
    arr[i] = millis();
    while(arr[i] == byte(millis()));//ждём пока "тикнет" millis()
  }
  Serial.begin(9600);
  for(word i=0; i<256; i++)  Serial.println(arr[i]); 
  }
  Serial.println(); 
  delay(5);//чтоб микрос() переполнился
  
  word arr[500];
  a = micros();//возвращает MAX=64000, шаг 4 мкс
  for(word i=0; i<500; i++)  arr[i] = micros();
  b = micros();
  
  for(word i=0; i<500; i++)  Serial.println(arr[i]); 
  Serial.println();
  Serial.println(a);
  Serial.println(b);
  Serial.println(float((b+64000u-a)%64000u)/500.);//длительность вызова микрос()=3.58мкс
}

void loop(){}

 

Pyotr
Offline
Зарегистрирован: 12.03.2014

Чтоб корректно работал ШИМ на 5 и 6 пинах, нужно передавать в функцию 
analogWrite(led, pwm); значение pwm=(5--255) вместо 0--255
Пример плавного разгорания-затухания лед.

const byte led = 5;          
word i, pwm;

void setup()  { } 

void loop()  { 
 for(i=0; i<255; i++){
  pwm = i + (255-i)/50;
  analogWrite(led, pwm);
  delay(10);    
 }
  delay(2000); 
  
  for(i=255; i>0; i--){
  pwm = i + (255-i)/50;
  analogWrite(led, pwm);
  delay(10);    
 }
  delay(2000); 
}

 

ZugDuk
Offline
Зарегистрирован: 18.10.2018

Первый день ковыряю ардуину - могу уверенно сказать, что написанное в первом посте новичку не понятно вообще. Именно синтаксис написанного. Нужно было написать скетч как можно проще (как новички пишут), но акцентировать внимание на ключевом моменте - вычислении разницы времен.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Не нраица - добро пожаловать отсюда.  Открывай свой форум с очком и путинскими женщинами. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ZugDuk пишет:

могу уверенно сказать, что написанное в первом посте новичку не понятно вообще. Именно синтаксис написанного. Нужно было написать скетч как можно проще (как новички пишут),

Напишите.

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

ZugDuk пишет:

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

Вам-то откуда знать, если до новичка Вам минимум еще 3-4 месяца?