Как Сбросить millis()

Green
Offline
Зарегистрирован: 01.10.2015

Как бэ, кто как хочет, так и... Только по уму всё нужно делать. Общеизвестно как это делается (и ЕвгенийП это объяснил), достаточно двух строк всего. Ну, только если есть желание поговорить...)

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

Green, Дааа. Слона то я и не заметил. Действительно ЕвгенийП писал как все делать красиво в сообщении #73.

#include "Arduino.h"
extern volatile uint32_t timer0_millis;
extern volatile uint32_t timer0_overflow_count;
void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start"));
}
void loop()
{
  Serial.println(micros());
  Serial.println(millis());
  delay(1000);
  timer0_millis = 0; // millis
  timer0_overflow_count = 0; // micros
}

hugoboss317 пишет:

p-a-h-a пишет:
Можно конечно ещё адрес в памяти узнать счётчика и затирать там.

Сказал "А", говори "Б".

Больше не имеет смысл. Просто напишу "Б", но это совершенно не правильный подход:

#include "Arduino.h"
//#include "wiring.c"
void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start"));
}
void loop()
{
  Serial.println(micros());
  Serial.println(millis());
  delay(1000);
  //Serial.println((unsigned long)&timer0_millis, HEX); //0x11B
  //Serial.println((unsigned long)&timer0_overflow_count, HEX); //0x117
  cli();
  memset((void *)0x11B, NULL, sizeof(uint32_t)); // millis
  memset((void *)0x117, NULL, sizeof(uint32_t)); // micros
  sei();
}

У меня другой вопрос к ЕвгенийП. Евгений, как вы узнали о существовании переменной timer0_millis? Как новичку узнать что она существует имея Arduino IDE и интернет конечно. Я в platformIO перешел к определению типа millis(); Не уверен что это единственный способ.

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

p-a-h-a пишет:

У меня другой вопрос к ЕвгенийП.  Евгений, как вы узнали о существовании переменной timer0_millis? Как новичку узнать что она существует имея Arduino IDE

Ответ все в том же сообщении #73, которое вы цитируете - а именно - нафик это новичку не надо.

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

Upper
Offline
Зарегистрирован: 23.06.2020

b707 пишет:

p-a-h-a пишет:

У меня другой вопрос к ЕвгенийП.  Евгений, как вы узнали о существовании переменной timer0_millis? Как новичку узнать что она существует имея Arduino IDE

Ответ все в том же сообщении #73, которое вы цитируете - а именно - нафик это новичку не надо.

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

Приведенный вами вопрос p-a-h-a  - "как узнали". И можно ли это узнать используя Arduino IDE.

На определенном уровне "новичку" становится полезным умение оперативно находить определения и реализации функций.

Я не знаю, как это сделать в IDE Arduino и использую для этого другие IDE, но возможно и в Arduino есть способ посмотреть на определение и реализацию функции .

Green
Offline
Зарегистрирован: 01.10.2015

Да просто полезно исследовать содержимое файлов Ардуино ядра, которые в папке \Arduino\hardware\arduino\avr\cores\arduino\. Только начинающим это даже вредно.)

Upper
Offline
Зарегистрирован: 23.06.2020

Я имел в виду удобный способ быстро перейти к реализации, как в "старших" IDE. Щелкнул правой кнопкой по функции или переменной, выбрал пункт "перейти к реализации" и смотришь.

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

Upper пишет:

Я имел в виду удобный способ быстро перейти к реализации, как в "старших" IDE. Щелкнул правой кнопкой по функции или переменной, выбрал пункт "перейти к реализации" и смотришь.

Все верно. И таких ИДЕ полно - Visual Studio, VS Code... да в принципе любая продвинутая ИДЕ если ек правильно настроить. Я читал что даже в QT Creator народ умудряется Ардуино программировать :)

 

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

p-a-h-a пишет:
как вы узнали о существовании переменной timer0_millis?
Открыл файл wiring.c и посмотрел как оно там всё устроено.

p-a-h-a пишет:
Как новичку узнать что она существует имея Arduino IDE
Открыть в этом самом IDE файл и посмотреть (что я и сделал).

Другой вопрос, "зачем это новичку узнавать?", но он, как я понимаю, здесь не обсуждается.

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

ЕвгенийП, Лично я этим вопросом озадачился в автоналивайке питьевой воды в стакакан.
Кнопочку тыцнул atmega вышла из сна, отработала, уснула. Просто удобно при каждом пробуждении иметь часы с момента пробуждения. Если не сбрасывать - переполнение 100% наступит когда-либо, а там где-то накосячу, помпа не выключиться, прийдется все 20 литров залпом выпить)
До этого esp8266 использовал и банально привык что после глубокого сна идет полный сброс контроллера за исключением rtc памяти.

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

p-a-h-a пишет:
Если не сбрасывать - переполнение 100% наступит когда-либо

У нас сегодня чо, атака клоунов?  Вроде не пятница...

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

p-a-h-a пишет:
переполнение 100% наступит когда-либо, а там где-то накосячу,.

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

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

Green
Offline
Зарегистрирован: 01.10.2015

Паха, а может с логикой что то? Зачем часы с момента пробуждения? Ну ладно, а зачем сбрасывать миллис при этом?
Ой, не успел.)

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Деда срочно нужно два сертификата !!!

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

Тут именная серебряная пуля от государства больше подойдёт. 

толстый
Offline
Зарегистрирован: 10.02.2020

На самом деле темка то полезная. Не обнуление миллис конечно(решение по типу "гордиева узла" так себе идея), а вот для выставления в сетапе начального значения для проверки, - а, что антяресна будет после дня, недели, месяца работы. А как перенесёт программа переполнение счетчика? И не надо ждать в реальном времени :)

А необходимость появилась после того как заметил что  ШИМ плавно меняюшийся по синусу(косинусу:) через дней десять становится каким то дёрганым. И чем дальше тем хуже. Реализация типа такой

int periode = 5000;
time = millis();
value = 128+127*cos(2*PI/periode*time);
analogWrite(ledpin, value) ;

Раньше тупо не замечал, т.к. аптайм не превышал недели. А тут поставил на постоянку и на тебе подстава - чем больше миллис - тем больше пропуски. Сходу пришла мысля о том, что-бы сделать переменную "time"  не uint32_t, а  uint16_t. Автоматом получается обновление каждую минуту и прекрасно работает, что удалось проверить благодаря этой теме и ЕвгениюП( и др). Сыпасиба всем:)

Но раз в минуту в любом случае происходит резкое изменение значения. Использовать int32_t улучшает ситуацию, но 25 дней слишком много, так что думаю как сократить дерганье до хотя бы раз в день без лишних вычислений.

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

толстый пишет:

На самом деле темка то полезная. Не обнуление миллис конечно(решение по типу "гордиева узла" так себе идея), а вот для выставления в сетапе начального значения для проверки, - а, что антяресна будет после дня, недели, месяца работы. А как перенесёт программа переполнение счетчика? И не надо ждать в реальном времени :)

если алгоритм не рассчитан на длительную работу, значит "прокладка между рулем и сиденьем мешает", а миллис тут вообще ни при чем.

толстый
Offline
Зарегистрирован: 10.02.2020

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

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

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

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

толстый пишет:

 вот лично Вы, в предложенной реализации видите подвох? 

Лично мне лень вечером мозг включать и решать математическую задачу :)

 

толстый
Offline
Зарегистрирован: 10.02.2020

Моя думать, что бяда в том, что деление вообще ресурсозатратная операция(а на агромадные цифры в частности), но если если есть варианты(не понял про "мучение", то с радостью выслушаю:)

Окромя уже предложенного тупо использования меньшего типа переменных, думается вариант ограничить значение времени до восьмого знака(чуть больше суток). Вопррос как сделать это красиво:)

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

толстый, у меня встречный вопрос: чему равен икс в квадрате?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

толстый пишет:

восьмого знака(чуть больше суток). Вопррос как сделать это красиво:)

обнулить переменную через сутки или что то сделать?
куда уж проще - посчитать количество миллисекунд в сутках :) и при превышении что то сделать

  // если в течении 7 дней не были востребованы счетчики или они не обнулялись - очишаем счетчики
  if ((currentMillis - timetClearGetInfo) >= periodClearGetIndoModem) {
    timetClearGetInfo = currentMillis; // сбрасываем таймер
    totalReconnectGPRS = 0; totalReconnectMQTT = 0; totalCmdStart1 = 0; // чистим счетчики
  }

 

толстый
Offline
Зарегистрирован: 10.02.2020

Ну это решение в лоб. А хотелось типа: берём миллис и отрубаем первые восемь разрядов одной командой(скромный смайлик)  

толстый
Offline
Зарегистрирован: 10.02.2020

sadman41 пишет:
толстый, у меня встречный вопрос: чему равен икс в квадрате?

Х умноженное на Х :)

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

толстый пишет:

Ну это решение в лоб. А хотелось типа: берём миллис и отрубаем первые восемь разрядов одной командой(скромный смайлик)  


Читаем булева алгебра

толстый
Offline
Зарегистрирован: 10.02.2020

А-а-а-а-а. Я думал, что bool - это только false и  true.  А туть  оказывается https://www.youtube.com/watch?v=4vKDrHE0wAQ

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

толстый пишет:

sadman41 пишет:
толстый, у меня встречный вопрос: чему равен икс в квадрате?

Х умноженное на Х :)


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

толстый
Offline
Зарегистрирован: 10.02.2020

На балу Наташа Ростова отводит поручика Ржевского в сторону и говорит:

- Поручик, какая сегодня романтическая ночь...

- Да? И что?..

- Настоящая ночь для любви, не находите?

- Да? И что?...

- А у меня сегодня родители уезжают на дачу...

- Да? И что?...

- Поручик, ПРИХОДИТЕ ТРАХАТЬСЯ!!!

- Намек понял - буду!

толстый
Offline
Зарегистрирован: 10.02.2020

andycat пишет:
толстый пишет:

Ну это решение в лоб. А хотелось типа: берём миллис и отрубаем первые восемь разрядов одной командой(скромный смайлик)  

Читаем булева алгебра

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

Такой вариант вроде должен сработать для восьмибитной переменной, но для 32-х битной наверное не прокатит.

time = millis();
time  = time & 0b00001111;

  

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

А чем плох вариант?

time = millis() % 100000000;

 

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

толстый, мне кажется нет никакой надобности каждую миллисекунду производить такие тяжёлые вычисления. Результат в любом случае 8 битный, форма синус. Поэтому достаточно заранее высчитанной фиксированной таблицы всего из 256 байт. Считывать очередной отсчёт раз в сколько надо миллисекунд, считая время таймером или через миллис -по вкусу.

толстый
Offline
Зарегистрирован: 10.02.2020

v258 пишет:

А чем плох вариант?

time = millis() % 100000000;

 

Ну как бы это опять же деление, но, спасибо попробую.

толстый
Offline
Зарегистрирован: 10.02.2020

dimax пишет:

толстый, мне кажется нет никакой надобности каждую миллисекунду производить такие тяжёлые вычисления. Результат в любом случае 8 битный, форма синус. Поэтому достаточно заранее высчитанной фиксированной таблицы всего из 256 байт. Считывать очередной отсчёт раз в сколько надо миллисекунд, считая время таймером или через миллис -по вкусу.

Спасибо. Для новой программы идеально. А для исправления старой ... Но вариант хороший. Можно попробовать.

толстый
Offline
Зарегистрирован: 10.02.2020

толстый пишет:

v258 пишет:

А чем плох вариант?

time = millis() % 100000000;

 

Ну как бы это опять же деление, но, спасибо попробую.

Не, те же тормоза(пропуски).

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

толстый пишет:

time = millis() % 100000000;

Не, те же тормоза(пропуски).

Если я правильно понял алгоритм, -то нет смысла считать миллисекунд больше, чем значение period. То бишь 

int time =(uint32_t)millis()%period;

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

Толстый, 100% таблица вместо тригонометрии в PROGMEM
Что то вроде этого:
uint8_t sinTab[256] PROGMEM = {0,10,15,25.......255....10};// таблица должна гуглится.
void analog(){//вызываем с необходимой частотой
static uint8_t i=0;
AnalogWrite(pin,pgm_read (sinTab[i++]);
}
За правильный синтаксис не ручаюсь.
На порядок быстрее будет.

толстый
Offline
Зарегистрирован: 10.02.2020

dimax пишет:

толстый пишет:

time = millis() % 100000000;

Не, те же тормоза(пропуски).

Если я правильно понял алгоритм, -то нет смысла считать миллисекунд больше, чем значение period. То бишь 

int time =(uint32_t)millis()%period;

Ну дык тож на тож  выходит - ограничение по типу int, т.е. резкая смена шим  через минуту (uint)

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

математику пересматривай, где-то ты перемудрил

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

толстый пишет:

dimax пишет:

толстый пишет:

time = millis() % 100000000;

Не, те же тормоза(пропуски).

Если я правильно понял алгоритм, -то нет смысла считать миллисекунд больше, чем значение period. То бишь 

int time =(uint32_t)millis()%period;

Ну дык тож на тож  выходит - ограничение по типу int, т.е. резкая смена шим  через минуту (uint)

Какие ограничения? Будет циклический счёт от 0 до 5000 . И ваш алгоритм будет отрисовывать один период синуса за 5 секунд.

толстый
Offline
Зарегистрирован: 10.02.2020

v258 пишет:

математику пересматривай, где-то ты перемудрил

Всё возможно:) Вывел в сериал миллис и вэлью - вроде гладенько. Однако ж вызуально на светодиоде явно рвётся раз в минуту(когда переполняется таймес).

толстый
Offline
Зарегистрирован: 10.02.2020

To dimax: гляну повнимательней, спасибо. Нюанс в том, что из программы период можно/нужно менять.

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

толстый пишет:

А необходимость появилась после того как заметил что  ШИМ плавно меняюшийся по синусу(косинусу:) через дней десять становится каким то дёрганым. И чем дальше тем хуже. Реализация типа такой

int periode = 5000;
time = millis();
value = 128+127*cos(2*PI/periode*time);
analogWrite(ledpin, value) ;

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

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

Давайте посчитаем, чему будет равно через 10 дней:

24 * 60 * 60 * 1000 = 864000000

                                  123456789 - десятичные разряды числа, начиная с первой цифры

Как известно, точно числа типа float составляет 7-8 десятичных знаков. Чем больше абсолютное значение числа, тем больше абсолютная погрешность. В данном случае погрешность больше единицы [приращения]. Можно оценить, что она лежит между 10 и 100, причем, ближе к 100. (единицы 8 и 7 десятичных разрядов соответственно)

void setup() {
  Serial.begin(115200);
  int periode = 5000;
  
  for(long time = 864000000; time <= 864000100; time++) {
    float argument = 2*PI/periode*time;
    float value = 128+127*cos(argument);
    Serial.print(time);
    Serial.print('\t');
    Serial.print(argument);
    Serial.print('\t');
    Serial.println(value);
  }
}

void loop() {
}

результат:

864000000	1085734.37	254.87
864000001	1085734.37	254.87
864000002	1085734.37	254.87
864000003	1085734.37	254.87
864000004	1085734.37	254.87
864000005	1085734.37	254.87
864000006	1085734.37	254.87
864000007	1085734.37	254.87
864000008	1085734.37	254.87
864000009	1085734.37	254.87
864000010	1085734.37	254.87
864000011	1085734.37	254.87
864000012	1085734.37	254.87
864000013	1085734.37	254.87
864000014	1085734.37	254.87
864000015	1085734.37	254.87
864000016	1085734.37	254.87
864000017	1085734.37	254.87
864000018	1085734.37	254.87
864000019	1085734.37	254.87
864000020	1085734.37	254.87
864000021	1085734.37	254.87
864000022	1085734.37	254.87
864000023	1085734.37	254.87
864000024	1085734.37	254.87
864000025	1085734.37	254.87
864000026	1085734.37	254.87
864000027	1085734.37	254.87
864000028	1085734.37	254.87
864000029	1085734.37	254.87
864000030	1085734.37	254.87
864000031	1085734.37	254.87
864000032	1085734.37	254.87
864000033	1085734.50	254.60
864000034	1085734.50	254.60
864000035	1085734.50	254.60
864000036	1085734.50	254.60
864000037	1085734.50	254.60
864000038	1085734.50	254.60
864000039	1085734.50	254.60
864000040	1085734.50	254.60
864000041	1085734.50	254.60
864000042	1085734.50	254.60
864000043	1085734.50	254.60
864000044	1085734.50	254.60
864000045	1085734.50	254.60
864000046	1085734.50	254.60
864000047	1085734.50	254.60
864000048	1085734.50	254.60
864000049	1085734.50	254.60
864000050	1085734.50	254.60
864000051	1085734.50	254.60
864000052	1085734.50	254.60
864000053	1085734.50	254.60
864000054	1085734.50	254.60
864000055	1085734.50	254.60
864000056	1085734.50	254.60
864000057	1085734.50	254.60
864000058	1085734.50	254.60
864000059	1085734.50	254.60
864000060	1085734.50	254.60
864000061	1085734.50	254.60
864000062	1085734.50	254.60
864000063	1085734.50	254.60
864000064	1085734.50	254.60
864000065	1085734.50	254.60
864000066	1085734.50	254.60
864000067	1085734.50	254.60
864000068	1085734.50	254.60
864000069	1085734.50	254.60
864000070	1085734.50	254.60
864000071	1085734.50	254.60
864000072	1085734.50	254.60
864000073	1085734.50	254.60
864000074	1085734.50	254.60
864000075	1085734.50	254.60
864000076	1085734.50	254.60
864000077	1085734.50	254.60
864000078	1085734.50	254.60
864000079	1085734.50	254.60
864000080	1085734.50	254.60
864000081	1085734.50	254.60
864000082	1085734.50	254.60
864000083	1085734.50	254.60
864000084	1085734.50	254.60
864000085	1085734.50	254.60
864000086	1085734.50	254.60
864000087	1085734.50	254.60
864000088	1085734.50	254.60
864000089	1085734.50	254.60
864000090	1085734.50	254.60
864000091	1085734.50	254.60
864000092	1085734.50	254.60
864000093	1085734.50	254.60
864000094	1085734.50	254.60
864000095	1085734.50	254.60
864000096	1085734.62	252.37
864000097	1085734.62	252.37
864000098	1085734.62	252.37
864000099	1085734.62	252.37
864000100	1085734.62	252.37