не правильно работает время

sasken
Offline
Зарегистрирован: 28.10.2015

Скажите, пожалуйста, а вот такая программа:

void loop() {
  Serial.println(millis());

  delay(2000);
      wdt_enable(WDTO_500MS); //Задаем интервал сторожевого таймера (0.5с)
      WDTCSR |= (1 << WDIE); //Устанавливаем бит WDIE регистра WDTCSR для разрешения прерываний от сторожевого таймера
      set_sleep_mode(SLEEP_MODE_EXT_STANDBY);
      sleep_mode();
      digitalWrite(test_pin, f);
}
ISR (WDT_vect) {
  wdt_disable(); 
f=!f;
}

в мониторе порта выводит значение каждые 2 с, а по идее должно 2.5 с. в спящем режиме функция millis не пашет?
как же быть, если надо считать время, когда мк спит?

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

На то он и спящий, чтобы в это время ничего не делать. Соответственно, функция millis показывает только то время, которое было проведено в режиме бодрствования. 

Использовать внешний источник времени.

sasken
Offline
Зарегистрирован: 28.10.2015

а кроме внешнего источника времени есть какие-нибудь варианты?

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

sasken пишет:

а кроме внешнего источника времени есть какие-нибудь варианты?

вариант очень простой - при пробуждении прибавлять установленную задержку WDT к счетчику миллис - как раз и получите 2.5с

sasken
Offline
Зарегистрирован: 28.10.2015

b707 пишет:

вариант очень простой - при пробуждении прибавлять установленную задержку WDT к счетчику миллис - как раз и получите 2.5с

но тогда ни о какой точности в плюс/минус 1 мс и речи быть не может.

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

sasken пишет:

b707 пишет:

вариант очень простой - при пробуждении прибавлять установленную задержку WDT к счетчику миллис - как раз и получите 2.5с

но тогда ни о какой точности в плюс/минус 1 мс и речи быть не может.

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

sasken
Offline
Зарегистрирован: 28.10.2015

Подскажите какую-нибудь простую миниатюрную микросхему генератора импульсов. Не ds1307. Она просит батарейку

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Таймер NE555 ?

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

Jeka_M пишет:

Таймер NE555 ?

у него точность будет ровно такая же, как у встроенного WDT

sasken
Offline
Зарегистрирован: 28.10.2015

Таймер555 ппц какой не точный. Там плюс 5 градусов температура окружающей среды и точность ушла.

sasken
Offline
Зарегистрирован: 28.10.2015

Видимо акромя ds1307 ничего больше и нет

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

sasken пишет:

не правильно работает время

Время - оно такое ...

sasken пишет:

ни о какой точности в плюс/минус 1 мс и речи быть не может.

Так ото ж ...

sasken
Offline
Зарегистрирован: 28.10.2015

ЕвгенийП, может посоветуете что-нибудь? Есть варианты акромя ds1307?

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

Волшебства не бывает. Все, что гоняет электроны - жрет энергию. Есть ли смысл погружать МК в сон, оставляя счет времени чипу RTC - вопрос с эмпирическим ответом.

sasken
Offline
Зарегистрирован: 28.10.2015

sadman41 пишет:

Волшебства не бывает. Все, что гоняет электроны - жрет энергию. Есть ли смысл погружать МК в сон, оставляя счет времени чипу RTC - вопрос с эмпирическим ответом.

Я ж не говорю, что хочу чуда. я спрашиваю чем заменить ds1307 ? мне от нее надо только выход генератора, который настраевается по spi от мк.

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

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

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

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

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

Любой генератор на кварце. Да хоть бы и Atmel328.

svm
Offline
Зарегистрирован: 06.11.2016

К176ИЕ12

sasken
Offline
Зарегистрирован: 28.10.2015

sadman41 пишет:

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

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

согласен. не подумал. питание от 2 до 5v. потребление менее 1 мА. скорость чего? нужны импульсы порядка 100мс. точность - хмммм. 1 мс на 2 минуты времени. видимо это дикая точность.

есть какие-нибудь осмысленные рекомендации?

 

andriano пишет:

Любой генератор на кварце. Да хоть бы и Atmel328.

это прикол такой?

 

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

Ну, хорошо, генератор генерит. А считать его тики кто будет? Ещё один контроллер заводить?

sasken
Offline
Зарегистрирован: 28.10.2015

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

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

Ну, тогда вернёмся к первому посту. Кто ему мешает раз в секунду просыпаться по вочдогу и прибавлять секунду? Или Вам по прежнему нужна точность " плюс/минус 1 мс"?

Вы бы вообще сказали что у Вас за окружение? Например, МК голый или ардуина? Если ардуина, то вообще забейте на это - ничего Вы её сном не сэкономите.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

PIC16F627A

Operating Current:
- 12μA @ 32 kHz, 2.0V, typical
- 120μA @ 1 MHz, 2.0V, typical
используйте. 
sasken
Offline
Зарегистрирован: 28.10.2015

ЕвгенийП пишет:
Ну, тогда вернёмся к первому посту. Кто ему мешает раз в секунду просыпаться по вочдогу и прибавлять секунду? Или Вам по прежнему нужна точность " плюс/минус 1 мс"?

мешает точность wd которая вообще никакая. а так идея: перед сном запускаем генератор импульсов ds1307 и просыпаемся по тику через точный промежуток времени и его уже учитываем в программе.

ЕвгенийП пишет:
Вы бы вообще сказали что у Вас за окружение? Например, МК голый или ардуина? Если ардуина, то вообще забейте на это - ничего Вы её сном не сэкономите.

голый мк atmega328, тактирующийся кварцем 8 мгц и с делителем на 8 (1мгц минимум необходим для общения с соседями). в таком режиме потребление порядка 2-3 мА, при спящем режиме stand режиме потребление порядка 0,2-0,3 мА - это устраивает, но мк должен считать время и по прошествии этого времени выполнить команду.

 

mykaida пишет:
- 12μA @ 32 kHz, 2.0V, typical

- 120μA @ 1 MHz, 2.0V, typical
фантастические цифры. это в режиме работы? но мне надо минимум 3 вольта для открытия мосфета с ноги мк. видимо пора переходить на пик. но его надо изучать, а проект стоит. надо побыстрее сделать.
b707
Offline
Зарегистрирован: 26.05.2017

sasken - изучите внимательнее даташит атмеги328 на предмет спящих режимов. В режиме Idle millis остается активным, при этом типичное потребление при VCC =3v и такте 1 МГц порядка 0.3мА

 

sasken
Offline
Зарегистрирован: 28.10.2015

Спасибо. Почитаю. Это моё первая работа со спящими режимами.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Почему бы не считать время .. самим таймером watchdog-а? :)

sasken
Offline
Зарегистрирован: 28.10.2015

Потому что wd не точный ппц как что.
Переход в спящий режим занимает кучу времени. По крайней мере мне осциллограф показал около 10 мс. Сам wd считает от своего внутреннего такта, который зависит и от напряжения и от температуры. Выход быстрый около 6 тактов. Но суммарно время хз какое получается.

sasken
Offline
Зарегистрирован: 28.10.2015
void loop() {
      wdt_enable(WDTO_500MS); //Задаем интервал сторожевого таймера (0.5с)
      WDTCSR |= (1 << WDIE); //Устанавливаем бит WDIE регистра WDTCSR для разрешения прерываний от сторожевого таймера
      set_sleep_mode(SLEEP_MODE_IDLE);
      sleep_mode();
      digitalWrite(test_pin, f);
}

ISR (WDT_vect) {
  wdt_disable(); 
f=!f;
}

хмммм. не дрыгается нога при таком режиме. что я делаю не так? если поменять set_sleep_mode(SLEEP_MODE_IDLE) на set_sleep_mode(SLEEP_MODE_EXT_STANDBY) то все работает хорошо, но это не тот режим, что мне надо.

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

А чо, нельзя у DS1307 настроить SQW? И пусь раз в секунду будит Дуню по прерыванию. 

sasken
Offline
Зарегистрирован: 28.10.2015

DetSimen пишет:

А чо, нельзя у DS1307 настроить SQW? И пусь раз в секунду будит Дуню по прерыванию. 

ну так это и было идеей. пока не выяснилось, что в режиме IDLE функция millis работает. теперь не понятно почему по wd не выходит из режима IDLE

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

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

sasken
Offline
Зарегистрирован: 28.10.2015

голый камень у меня с обвязкой: кварц, два кондера 22 пф и резистор на ресет

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

тогда я вапще не понимаю. Загонять можно в более глубокий SLEEP, чем IDLE и по прерыванию с часов будить.  Да, выходить из прерывания будет дольше в масштабах процессорного времени, ну дак и жрать будет меньше существенно.  А DS1307 можно и от ионистора питать некоторое время (~около недели).

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

DetSimen пишет:

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

Автор выше в теме написал  "ds1307 не предлагать. Она просит батарейку"

sasken
Offline
Зарегистрирован: 28.10.2015

блин. нет. вариант с ds1307 возможен, но если можно обойтись без rtc, то почему бы и нет? а получается что с режимом IDLE это можно. только вот не понимаю почему он не срабатывает от wd

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

b707 пишет:

DetSimen пишет:

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

Автор выше в теме написал  "ds1307 не предлагать. Она просит батарейку"

тогда ладно. я сливаюсь, автору удачи.  пусть городит неведому хрень. 

sasken
Offline
Зарегистрирован: 28.10.2015

DetSimen пишет:

я сливаюсь, автору удачи.  пусть городит неведому хрень. 

удачи.

Советчик из вас как из ... молоко.
про ds1307 уже все обсудили и решили выше. зачем вы ее опять предлагаете? видимо не захотели читать ветку полностью.

уже было сказано, что ds1307 нужна ТОЛЬКО для генерации импульсов через точный промежуток времени. остальное, чем обладает микросхема - нафиг не надо для этой задачи. (это как использовать автобус для перевозки одного листа бумаги) соответственно был задан вопрос - а если ли какие-нибудь микросхемы типа ds1307, но только в качестве генератора. остальное все не надо. видимо таких не существует. ок. значит ставим ее.

НО !!!! далее мой косяк - не увидел, что функция millis работает в режиме IDLE. это значит, что бы посчитать время, включая то, что находится мк в режиме сна, достаточно использовать этот режим. это ж даже лучше - не надо никаких дополнительных обвесов типа DS1307, но вот запара - не выходит atmega328 из IDLE по wd. вопрос - почему?
и тут на счену приходит DetSimen и предлагает ВНИМАНИЕ ВНИМАНИЕ -  поставить DS1307!!!!

а потом сваливает со словами:"пусть городит неведому хрень".

ну что ж сказать? ок. до свидания.

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

sasken пишет:

а получается что с режимом IDLE это можно. только вот не понимаю почему он не срабатывает от wd

Ну, если из POWER DOWN от WDT просыпается, то уж из IDLE подавно.)

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

удалюсь в скит, посыпав лысину пеплом

sasken
Offline
Зарегистрирован: 28.10.2015
void loop() {
      wdt_enable(WDTO_500MS); //Задаем интервал сторожевого таймера (0.5с)
      WDTCSR |= (1 << WDIE); //Устанавливаем бит WDIE регистра WDTCSR для разрешения прерываний от сторожевого таймера
      set_sleep_mode(SLEEP_MODE_IDLE);
      sleep_mode();
      digitalWrite(test_pin, f);
}

ISR (WDT_vect) {
  wdt_disable(); 
f=!f;
}

хмммм. не дрыгается нога при таком режиме. что я делаю не так? если поменять set_sleep_mode(SLEEP_MODE_IDLE) на set_sleep_mode(SLEEP_MODE_EXT_STANDBY) то все работает хорошо.

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

sasken пишет:
хмммм. не дрыгается нога при таком режиме. что я делаю не так?

а если так:

void loop() {
      wdt_enable(WDTO_500MS); //Задаем интервал сторожевого таймера (0.5с)
      WDTCSR |= (1 << WDIE); //Устанавливаем бит WDIE регистра WDTCSR для разрешения прерываний от сторожевого таймера
      set_sleep_mode(SLEEP_MODE_IDLE);
      sleep_mode();
      f=!f;
      digitalWrite(test_pin, f);
}

ISR (WDT_vect) {
  wdt_disable(); 
}

 

sasken
Offline
Зарегистрирован: 28.10.2015

неа. не взлетело. на тестовом пине меандр с частотой 30.53 Гц.

так а ничего и не поменялось, кроме как f теперь можно обьявлять не как volatile bool ?

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

sasken пишет:

 ничего и не поменялось, кроме как f теперь можно обьявлять не как volatile bool ?

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

 

добавка - а что-то я не понял, почему там 30 Гц? У вас МК вообще не спит. что ли?

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

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

загружаю через ISP

// пробуждение по WatchDog

#include <avr/sleep.h>
#include <avr/wdt.h>

const byte LED = LED_BUILTIN;

uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
void get_mcusr(void) \
__attribute__((naked)) \
__attribute__((used)) \
__attribute__((section(".init3")));
void get_mcusr(void)
{
  mcusr_mirror = MCUSR;
  MCUSR = 0;
  wdt_disable();
}

void flash () {
  pinMode (LED, OUTPUT);
  for (byte i = 0; i < 10; i++){digitalWrite (LED, HIGH);delay (50);digitalWrite (LED, LOW);delay (50);}
  pinMode (LED, INPUT);
}  // end of flash

// watchdog interrupt
ISR (WDT_vect)
{
  wdt_disable();  // disable watchdog
}  // end of WDT_vect

void setup () {
  MCUSR = 0;
  wdt_disable();
}

void loop ()
{
  flash ();
  // disable ADC
  ADCSRA = 0;
  // clear various "reset" flags
  MCUSR = 0;
  // allow changes, disable reset
  WDTCSR = bit (WDCE) | bit (WDE);
  // set interrupt mode and an interval
  WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0);    // set WDIE, and 8 seconds delay
  wdt_reset();  // pat the dog
  //set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  set_sleep_mode (SLEEP_MODE_IDLE);
  noInterrupts ();           // timed sequence follows
  sleep_enable();
  // turn off brown-out enable in software
  MCUCR = bit (BODS) | bit (BODSE);
  MCUCR = bit (BODS);
  interrupts ();             // guarantees next instruction executed
  sleep_cpu ();
  // cancel sleep as a precaution
  sleep_disable();
} // end of loop

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

andycat пишет:

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

Загрузчик кривой?

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

DIYMan пишет:

andycat пишет:

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

Загрузчик кривой?

не знаю, может быть, загрузчик Optiboot

но как он может влиять на режим сна не понятно

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

andycat, если в нано загружен оптибут -то она уже становится Уно :) Так что видимо у вас загрузчик родной , от Нано.

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

да бог бы с ним с загрузчиком, интересно почему спящий режим SLEEP_MODE_IDLE не работает

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

andycat, где не работает? Если речь про Arduino IDE то вероятно потому, что просыпается от любого чиха. А чихает как минимум нулевой таймер, его ж никто не останавливал..

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015