Как бэ, кто как хочет, так и... Только по уму всё нужно делать. Общеизвестно как это делается (и ЕвгенийП это объяснил), достаточно двух строк всего. Ну, только если есть желание поговорить...)
У меня другой вопрос к ЕвгенийП. Евгений, как вы узнали о существовании переменной timer0_millis? Как новичку узнать что она существует имея Arduino IDE и интернет конечно. Я в platformIO перешел к определению типа millis(); Не уверен что это единственный способ.
У меня другой вопрос к ЕвгенийП. Евгений, как вы узнали о существовании переменной timer0_millis? Как новичку узнать что она существует имея Arduino IDE
Ответ все в том же сообщении #73, которое вы цитируете - а именно - нафик это новичку не надо.
Можете привести хоть один реальный пример, когда новичку понадобится обнулять миллис?
У меня другой вопрос к ЕвгенийП. Евгений, как вы узнали о существовании переменной timer0_millis? Как новичку узнать что она существует имея Arduino IDE
Ответ все в том же сообщении #73, которое вы цитируете - а именно - нафик это новичку не надо.
Можете привести хоть один реальный пример, когда новичку понадобится обнулять миллис?
Приведенный вами вопрос p-a-h-a - "как узнали". И можно ли это узнать используя Arduino IDE.
На определенном уровне "новичку" становится полезным умение оперативно находить определения и реализации функций.
Я не знаю, как это сделать в IDE Arduino и использую для этого другие IDE, но возможно и в Arduino есть способ посмотреть на определение и реализацию функции .
Да просто полезно исследовать содержимое файлов Ардуино ядра, которые в папке \Arduino\hardware\arduino\avr\cores\arduino\. Только начинающим это даже вредно.)
Я имел в виду удобный способ быстро перейти к реализации, как в "старших" IDE. Щелкнул правой кнопкой по функции или переменной, выбрал пункт "перейти к реализации" и смотришь.
Я имел в виду удобный способ быстро перейти к реализации, как в "старших" IDE. Щелкнул правой кнопкой по функции или переменной, выбрал пункт "перейти к реализации" и смотришь.
Все верно. И таких ИДЕ полно - Visual Studio, VS Code... да в принципе любая продвинутая ИДЕ если ек правильно настроить. Я читал что даже в QT Creator народ умудряется Ардуино программировать :)
ЕвгенийП, Лично я этим вопросом озадачился в автоналивайке питьевой воды в стакакан.
Кнопочку тыцнул atmega вышла из сна, отработала, уснула. Просто удобно при каждом пробуждении иметь часы с момента пробуждения. Если не сбрасывать - переполнение 100% наступит когда-либо, а там где-то накосячу, помпа не выключиться, прийдется все 20 литров залпом выпить)
До этого esp8266 использовал и банально привык что после глубокого сна идет полный сброс контроллера за исключением rtc памяти.
переполнение 100% наступит когда-либо, а там где-то накосячу,.
как я и предполагал - обнуление миллис костыль, средство против рукожопости.
Паша, вы когда-то отсюда сбежали, потому что вам не понравилась что вас тыкают носом в ваше невежество. И вы там на Гайвере даже какой-то проект ведете (или вели). А вот видно, что тыканья носом вам очень не хватает - остались бы здесь - глядишь за эти три года и научились бы чему-то
На самом деле темка то полезная. Не обнуление миллис конечно(решение по типу "гордиева узла" так себе идея), а вот для выставления в сетапе начального значения для проверки, - а, что антяресна будет после дня, недели, месяца работы. А как перенесёт программа переполнение счетчика? И не надо ждать в реальном времени :)
А необходимость появилась после того как заметил что ШИМ плавно меняюшийся по синусу(косинусу:) через дней десять становится каким то дёрганым. И чем дальше тем хуже. Реализация типа такой
int periode = 5000;
time = millis();
value = 128+127*cos(2*PI/periode*time);
analogWrite(ledpin, value) ;
Раньше тупо не замечал, т.к. аптайм не превышал недели. А тут поставил на постоянку и на тебе подстава - чем больше миллис - тем больше пропуски. Сходу пришла мысля о том, что-бы сделать переменную "time" не uint32_t, а uint16_t. Автоматом получается обновление каждую минуту и прекрасно работает, что удалось проверить благодаря этой теме и ЕвгениюП( и др). Сыпасиба всем:)
Но раз в минуту в любом случае происходит резкое изменение значения. Использовать int32_t улучшает ситуацию, но 25 дней слишком много, так что думаю как сократить дерганье до хотя бы раз в день без лишних вычислений.
На самом деле темка то полезная. Не обнуление миллис конечно(решение по типу "гордиева узла" так себе идея), а вот для выставления в сетапе начального значения для проверки, - а, что антяресна будет после дня, недели, месяца работы. А как перенесёт программа переполнение счетчика? И не надо ждать в реальном времени :)
если алгоритм не рассчитан на длительную работу, значит "прокладка между рулем и сиденьем мешает", а миллис тут вообще ни при чем.
Полностью согласен:) Но, вот лично Вы, в предложенной реализации видите подвох? А эта конструкция частенько встречается на просторах инета. И, да, я в курсе про " гарантированно рабочие схемы из инета" :)
Моя думать, что бяда в том, что деление вообще ресурсозатратная операция(а на агромадные цифры в частности), но если если есть варианты(не понял про "мучение", то с радостью выслушаю:)
Окромя уже предложенного тупо использования меньшего типа переменных, думается вариант ограничить значение времени до восьмого знака(чуть больше суток). Вопррос как сделать это красиво:)
восьмого знака(чуть больше суток). Вопррос как сделать это красиво:)
обнулить переменную через сутки или что то сделать?
куда уж проще - посчитать количество миллисекунд в сутках :) и при превышении что то сделать
// если в течении 7 дней не были востребованы счетчики или они не обнулялись - очишаем счетчики
if ((currentMillis - timetClearGetInfo) >= periodClearGetIndoModem) {
timetClearGetInfo = currentMillis; // сбрасываем таймер
totalReconnectGPRS = 0; totalReconnectMQTT = 0; totalCmdStart1 = 0; // чистим счетчики
}
толстый, мне кажется нет никакой надобности каждую миллисекунду производить такие тяжёлые вычисления. Результат в любом случае 8 битный, форма синус. Поэтому достаточно заранее высчитанной фиксированной таблицы всего из 256 байт. Считывать очередной отсчёт раз в сколько надо миллисекунд, считая время таймером или через миллис -по вкусу.
толстый, мне кажется нет никакой надобности каждую миллисекунду производить такие тяжёлые вычисления. Результат в любом случае 8 битный, форма синус. Поэтому достаточно заранее высчитанной фиксированной таблицы всего из 256 байт. Считывать очередной отсчёт раз в сколько надо миллисекунд, считая время таймером или через миллис -по вкусу.
Спасибо. Для новой программы идеально. А для исправления старой ... Но вариант хороший. Можно попробовать.
Толстый, 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++]);
}
За правильный синтаксис не ручаюсь.
На порядок быстрее будет.
А необходимость появилась после того как заметил что ШИМ плавно меняюшийся по синусу(косинусу:) через дней десять становится каким то дёрганым. И чем дальше тем хуже. Реализация типа такой
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() {
}
Как бэ, кто как хочет, так и... Только по уму всё нужно делать. Общеизвестно как это делается (и ЕвгенийП это объяснил), достаточно двух строк всего. Ну, только если есть желание поговорить...)
Green, Дааа. Слона то я и не заметил. Действительно ЕвгенийП писал как все делать красиво в сообщении #73.
Сказал "А", говори "Б".
Больше не имеет смысл. Просто напишу "Б", но это совершенно не правильный подход:
У меня другой вопрос к ЕвгенийП. Евгений, как вы узнали о существовании переменной timer0_millis? Как новичку узнать что она существует имея Arduino IDE и интернет конечно. Я в platformIO перешел к определению типа millis(); Не уверен что это единственный способ.
У меня другой вопрос к ЕвгенийП. Евгений, как вы узнали о существовании переменной timer0_millis? Как новичку узнать что она существует имея Arduino IDE
Ответ все в том же сообщении #73, которое вы цитируете - а именно - нафик это новичку не надо.
Можете привести хоть один реальный пример, когда новичку понадобится обнулять миллис?
У меня другой вопрос к ЕвгенийП. Евгений, как вы узнали о существовании переменной timer0_millis? Как новичку узнать что она существует имея Arduino IDE
Ответ все в том же сообщении #73, которое вы цитируете - а именно - нафик это новичку не надо.
Можете привести хоть один реальный пример, когда новичку понадобится обнулять миллис?
Приведенный вами вопрос p-a-h-a - "как узнали". И можно ли это узнать используя Arduino IDE.
На определенном уровне "новичку" становится полезным умение оперативно находить определения и реализации функций.
Я не знаю, как это сделать в IDE Arduino и использую для этого другие IDE, но возможно и в Arduino есть способ посмотреть на определение и реализацию функции .
Да просто полезно исследовать содержимое файлов Ардуино ядра, которые в папке \Arduino\hardware\arduino\avr\cores\arduino\. Только начинающим это даже вредно.)
Я имел в виду удобный способ быстро перейти к реализации, как в "старших" IDE. Щелкнул правой кнопкой по функции или переменной, выбрал пункт "перейти к реализации" и смотришь.
Я имел в виду удобный способ быстро перейти к реализации, как в "старших" IDE. Щелкнул правой кнопкой по функции или переменной, выбрал пункт "перейти к реализации" и смотришь.
Все верно. И таких ИДЕ полно - Visual Studio, VS Code... да в принципе любая продвинутая ИДЕ если ек правильно настроить. Я читал что даже в QT Creator народ умудряется Ардуино программировать :)
Другой вопрос, "зачем это новичку узнавать?", но он, как я понимаю, здесь не обсуждается.
ЕвгенийП, Лично я этим вопросом озадачился в автоналивайке питьевой воды в стакакан.
Кнопочку тыцнул atmega вышла из сна, отработала, уснула. Просто удобно при каждом пробуждении иметь часы с момента пробуждения. Если не сбрасывать - переполнение 100% наступит когда-либо, а там где-то накосячу, помпа не выключиться, прийдется все 20 литров залпом выпить)
До этого esp8266 использовал и банально привык что после глубокого сна идет полный сброс контроллера за исключением rtc памяти.
У нас сегодня чо, атака клоунов? Вроде не пятница...
как я и предполагал - обнуление миллис костыль, средство против рукожопости.
Паша, вы когда-то отсюда сбежали, потому что вам не понравилась что вас тыкают носом в ваше невежество. И вы там на Гайвере даже какой-то проект ведете (или вели). А вот видно, что тыканья носом вам очень не хватает - остались бы здесь - глядишь за эти три года и научились бы чему-то
Паха, а может с логикой что то? Зачем часы с момента пробуждения? Ну ладно, а зачем сбрасывать миллис при этом?
Ой, не успел.)
Деда срочно нужно два сертификата !!!
Тут именная серебряная пуля от государства больше подойдёт.
На самом деле темка то полезная. Не обнуление миллис конечно(решение по типу "гордиева узла" так себе идея), а вот для выставления в сетапе начального значения для проверки, - а, что антяресна будет после дня, недели, месяца работы. А как перенесёт программа переполнение счетчика? И не надо ждать в реальном времени :)
А необходимость появилась после того как заметил что ШИМ плавно меняюшийся по синусу(косинусу:) через дней десять становится каким то дёрганым. И чем дальше тем хуже. Реализация типа такой
Раньше тупо не замечал, т.к. аптайм не превышал недели. А тут поставил на постоянку и на тебе подстава - чем больше миллис - тем больше пропуски. Сходу пришла мысля о том, что-бы сделать переменную "time" не uint32_t, а uint16_t. Автоматом получается обновление каждую минуту и прекрасно работает, что удалось проверить благодаря этой теме и ЕвгениюП( и др). Сыпасиба всем:)
Но раз в минуту в любом случае происходит резкое изменение значения. Использовать int32_t улучшает ситуацию, но 25 дней слишком много, так что думаю как сократить дерганье до хотя бы раз в день без лишних вычислений.
На самом деле темка то полезная. Не обнуление миллис конечно(решение по типу "гордиева узла" так себе идея), а вот для выставления в сетапе начального значения для проверки, - а, что антяресна будет после дня, недели, месяца работы. А как перенесёт программа переполнение счетчика? И не надо ждать в реальном времени :)
если алгоритм не рассчитан на длительную работу, значит "прокладка между рулем и сиденьем мешает", а миллис тут вообще ни при чем.
Полностью согласен:) Но, вот лично Вы, в предложенной реализации видите подвох? А эта конструкция частенько встречается на просторах инета. И, да, я в курсе про " гарантированно рабочие схемы из инета" :)
Толстый, явное приведение типа в формуле используй и не нужно будет миллис мучать...
вот лично Вы, в предложенной реализации видите подвох?
Лично мне лень вечером мозг включать и решать математическую задачу :)
Моя думать, что бяда в том, что деление вообще ресурсозатратная операция(а на агромадные цифры в частности), но если если есть варианты(не понял про "мучение", то с радостью выслушаю:)
Окромя уже предложенного тупо использования меньшего типа переменных, думается вариант ограничить значение времени до восьмого знака(чуть больше суток). Вопррос как сделать это красиво:)
толстый, у меня встречный вопрос: чему равен икс в квадрате?
восьмого знака(чуть больше суток). Вопррос как сделать это красиво:)
обнулить переменную через сутки или что то сделать?
куда уж проще - посчитать количество миллисекунд в сутках :) и при превышении что то сделать
Ну это решение в лоб. А хотелось типа: берём миллис и отрубаем первые восемь разрядов одной командой(скромный смайлик)
Х умноженное на Х :)
Ну это решение в лоб. А хотелось типа: берём миллис и отрубаем первые восемь разрядов одной командой(скромный смайлик)
Читаем булева алгебра
А-а-а-а-а. Я думал, что bool - это только false и true. А туть оказывается https://www.youtube.com/watch?v=4vKDrHE0wAQ
Х умноженное на Х :)
Ну так и для вашего косинуса описанное поведение - нормально.
На балу Наташа Ростова отводит поручика Ржевского в сторону и говорит:
- Поручик, какая сегодня романтическая ночь...
- Да? И что?..
- Настоящая ночь для любви, не находите?
- Да? И что?...
- А у меня сегодня родители уезжают на дачу...
- Да? И что?...
- Поручик, ПРИХОДИТЕ ТРАХАТЬСЯ!!!
- Намек понял - буду!
Ну это решение в лоб. А хотелось типа: берём миллис и отрубаем первые восемь разрядов одной командой(скромный смайлик)
Ну, я догадывался, что проще перевести в бинарную систему и отсекать маской, но предполагал, что есть готовые ассемблерные вставки.
Такой вариант вроде должен сработать для восьмибитной переменной, но для 32-х битной наверное не прокатит.
А чем плох вариант?
толстый, мне кажется нет никакой надобности каждую миллисекунду производить такие тяжёлые вычисления. Результат в любом случае 8 битный, форма синус. Поэтому достаточно заранее высчитанной фиксированной таблицы всего из 256 байт. Считывать очередной отсчёт раз в сколько надо миллисекунд, считая время таймером или через миллис -по вкусу.
А чем плох вариант?
Ну как бы это опять же деление, но, спасибо попробую.
толстый, мне кажется нет никакой надобности каждую миллисекунду производить такие тяжёлые вычисления. Результат в любом случае 8 битный, форма синус. Поэтому достаточно заранее высчитанной фиксированной таблицы всего из 256 байт. Считывать очередной отсчёт раз в сколько надо миллисекунд, считая время таймером или через миллис -по вкусу.
Спасибо. Для новой программы идеально. А для исправления старой ... Но вариант хороший. Можно попробовать.
А чем плох вариант?
Ну как бы это опять же деление, но, спасибо попробую.
Не, те же тормоза(пропуски).
time = millis() % 100000000;
Не, те же тормоза(пропуски).
Если я правильно понял алгоритм, -то нет смысла считать миллисекунд больше, чем значение period. То бишь
int time =(uint32_t)millis()%period;
Толстый, 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++]);
}
За правильный синтаксис не ручаюсь.
На порядок быстрее будет.
time = millis() % 100000000;
Не, те же тормоза(пропуски).
Если я правильно понял алгоритм, -то нет смысла считать миллисекунд больше, чем значение period. То бишь
int time =(uint32_t)millis()%period;
Ну дык тож на тож выходит - ограничение по типу int, т.е. резкая смена шим через минуту (uint)
математику пересматривай, где-то ты перемудрил
time = millis() % 100000000;
Не, те же тормоза(пропуски).
Если я правильно понял алгоритм, -то нет смысла считать миллисекунд больше, чем значение period. То бишь
int time =(uint32_t)millis()%period;
Ну дык тож на тож выходит - ограничение по типу int, т.е. резкая смена шим через минуту (uint)
Какие ограничения? Будет циклический счёт от 0 до 5000 . И ваш алгоритм будет отрисовывать один период синуса за 5 секунд.
математику пересматривай, где-то ты перемудрил
Всё возможно:) Вывел в сериал миллис и вэлью - вроде гладенько. Однако ж вызуально на светодиоде явно рвётся раз в минуту(когда переполняется таймес).
To dimax: гляну повнимательней, спасибо. Нюанс в том, что из программы период можно/нужно менять.
А необходимость появилась после того как заметил что ШИМ плавно меняюшийся по синусу(косинусу:) через дней десять становится каким то дёрганым. И чем дальше тем хуже. Реализация типа такой
Раньше тупо не замечал, т.к. аптайм не превышал недели. А тут поставил на постоянку и на тебе подстава - чем больше миллис - тем больше пропуски.
Давайте посчитаем, чему будет равно через 10 дней:
24 * 60 * 60 * 1000 = 864000000
123456789 - десятичные разряды числа, начиная с первой цифры
Как известно, точно числа типа float составляет 7-8 десятичных знаков. Чем больше абсолютное значение числа, тем больше абсолютная погрешность. В данном случае погрешность больше единицы [приращения]. Можно оценить, что она лежит между 10 и 100, причем, ближе к 100. (единицы 8 и 7 десятичных разрядов соответственно)
результат: