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

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

dimax пишет:

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

у меня просто камень мега328 с минимальной обвязкой и без бутлоадера.
при одном и том же коде режим standby работает, а IDLE нет. оба просыпаются от WD.

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

dimax пишет:

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

да, провел эксперимент, действительно МК просыпается, вопрос снят, спасибо.

Update: с этими экспериментами опять куда то делся загрузчик, пришлось опять записать.

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

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

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 () {
  for (byte i = 0; i < 3; i++) {
    digitalWrite (LED_BUILTIN, LOW);
    delay(500);
    digitalWrite (LED_BUILTIN, HIGH);
    delay (1000);
    digitalWrite (LED_BUILTIN, LOW);
    delay (500);
  }
}  // end of flash

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

void setup () {
  MCUSR = 0;
  wdt_disable();
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(0, OUTPUT); digitalWrite(0,HIGH);
  pinMode(1, OUTPUT); digitalWrite(1,HIGH);
}

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

 

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

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

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

sasken пишет:

 оба просыпаются от WD.

а не должны?

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

sasken пишет:

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

тогда и загрузчик вам не нужен, мне то он для экспериментов, чтоб через USB Грузить, в реальном устройстве он нафиг не нужен

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

andycat пишет:

а не должны?

конечно должны. только с режимом STANDBY мк просыпается, ножкой дергает и засыпает - все как надо, а при режиме IDLE вообще не реагирует. при этом я меняю только одну строчку set_sleep_mode(SLEEP_MODE_EXT_STANDBY) на set_sleep_mode(SLEEP_MODE_IDLE)

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

хммм. пошаманил сейчас с кодом. вроде заработало.
Только вот странно как-то: без сна атмега кушает 4.3 мА чтобы дергать ногой раз в 0.5с, а с режимом IDLE для тех же задач атмега ест 3.7 мА.
Я ожидал, что в IDLE он будет менее прожорливым.

у меня камень работает на 8 мгц с делителем на 8 во фьюзах.

ножка, на которой тестовый пин подтянута к земле через рез 100К. ресет пин через питание тоже через 100к.
по даташиту на атмегу328: Idle 8MHz,VCC = 5V и Idle 1MHz, VCC = 2V
получается что у меня всяко должно быть меньше 3.7 мА

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

andycat пишет:

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

.......

Update: с этими экспериментами опять куда то делся загрузчик, пришлось опять записать.

загрузка скетча через программатор (в том числе по ISP) удаляет загрузчик.

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

b707 пишет:

загрузка скетча через программатор (в том числе по ISP) удаляет загрузчик.

да да да....подзабыл, спасибо.

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

В принципе в режиме IDLE watchdog  лишний. Можно настроить первый таймер на нужное время, и по его  прерыванию МК будет просыпаться, выполнять свою работу, и снова спать.

#include "avr\wdt.h"
#include "avr\sleep.h"
volatile bool f=0;
void setup(){
pinMode(13,OUTPUT);  
TCCR0B=0;
TCCR1B=0;
TCNT1=0;
OCR1B=0;
TCCR1A=0;
TIMSK1=1<<OCIE1A;
OCR1A=15624; //переполнение каждые 250ms 
TCCR1B=(1<<CS12)|(1<<WGM12);
set_sleep_mode(SLEEP_MODE_IDLE);
}

void loop() {
sleep_mode();
digitalWrite(13, f);
}

ISR (TIMER1_COMPA_vect) { f=!f; }

 

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

dimax пишет:
В принципе в режиме IDLE watchdog  лишний. Можно настроить первый таймер на нужное время...

Отключение wd даст много экономии?

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

sasken пишет:

dimax пишет:
В принципе в режиме IDLE watchdog  лишний. Можно настроить первый таймер на нужное время...

Отключение wd даст много экономии?

суть не в отключении WD. а втом, что бы МК не просыпался раньше времени. В вашем коде МК вообще не спит, похоже - отсюда и потребление в 3.7мА. В IDLE должно быть 0.3 -0.8ма

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

не работает.

Добавил - извините, все работает.

но потребление такое же как и IDLE с WD

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

sasken пишет:

но потребление такое же как и IDLE с WD

значит не работает. По даташиту потребление должно быть раз в 7-10 меньше

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

sasken, в arduino ide дофига всего по умолчнию включено. Нужно всё вырубать, у Ника Гемена есть основательный разбор всего этого добра, почитайте.

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

dimax пишет:
sasken, в arduino ide дофига всего по умолчнию включено. Нужно всё вырубать

да. пробежался по этой статье.
код такой:
 

#include "avr\wdt.h"
#include "avr\sleep.h"
#include <avr/power.h>

volatile bool f=0;

void setup(){
  ADCSRA = 0; //отключаем все АЦП.
            // turn off brown-out enable in software
    MCUCR = bit (BODS) | bit (BODSE);
    MCUCR = bit (BODS);
    power_all_disable();
pinMode(13,OUTPUT);  
TCCR0B=0;
TCCR1B=0;
TCNT1=0;
OCR1B=0;
TCCR1A=0;
TIMSK1=1<<OCIE1A;
OCR1A=15624; //переполнение каждые 250ms 
TCCR1B=(1<<CS12)|(1<<WGM12);
set_sleep_mode(SLEEP_MODE_IDLE);
}

void loop() {
sleep_enable(); // разрешаем сон
sleep_cpu(); // спать!
digitalWrite(A2, f);
}

ISR (TIMER1_COMPA_vect) {
  f=!f; 
  }

потребление 3.1 мА

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

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

Хотя не, судя по даташиту , график ATmega328P: Idle Supply Current vs. Frequency (1MHz - 20MHz) это нормально

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

dimax пишет:
sasken, может неправильно измеряете? В импульсном режиме любой мультиметр будет показывать чёрти что. Нужно либо паузы большие сделать, либо осциллографом измерять мгновенный ток.

я измеряю так: питание контроллера закрыто диодом (что бы остальная схема не ела ток от мк). после него стоит резистор 5 Ом. на этот резистор повесил щуп осциллографа. он показывает среднее значение падающего напряжения, в данном случае 16.45 мвольт. их в уме делю на сопротивление резистора и получаю ток. 3.1 мА

dimax пишет:
Хотя не, судя по даташиту , график ATmega328P: Idle Supply Current vs. Frequency (1MHz - 20MHz) это нормально

как же нормально? стр 368 Idle 8MHz,VCC = 5V типовое значение тока 1.2мА, максимальное 2.7мА

а у меня частота в 8 раз меньше делителем во фьюзах.

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

sasken, лучше сделайте большие паузы и измерьте мультиметром.

OCR1A=65535; 
TCCR1B=(1<<CS10)|(1<<CS12)|(1<<WGM12);

PS про частоту я не в курсе был. Тогда с этими настройками паузы гигантские будут )

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

dimax пишет:
sasken, лучше сделайте большие паузы и измерьте мультиметром.

тоже самое. вообще не поменялось ничего.
я до этого эксперементировал с режимом STANDBY с wd. что просыпаться каждые 120 мс, что 500 мс, что 2 секуды -  ток потребления мк не меняется.

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

sasken пишет:

я до этого эксперементировал с режимом STANDBY с wd. что просыпаться каждые 120 мс, что 500 мс, что 2 секуды -  ток потребления мк не меняется.

с этого момента поподробнее. Получается, что у вас не только IDLE. но и STANDBY не работал?

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

b707 пишет:
с этого момента поподробнее. Получается, что у вас не только IDLE. но и STANDBY не работал?

нееее. со standby все ок. я писал вышел. листинг один и тот же. просто меняю одну строчку либо режим IDLE либо standby. в режиме standby все работает отлично, но!!!! функция millis не пашет. точнее она тупо сохраняет свое значение, а сон не учитывает. можно и программно учитывать, но это будет вообще не точно ибо просыпался я по WD.

а режим IDLE не дает результатов нужных. экономии практически нет. без режима IDLE потребление у меня окло 4.5-5 мА, а с режимом IDLE 3.1 получается при самом лучшем раскладе (power_all_disable() + откл. ацп + откл. детектора напряжения)

По даташиту - должно жрать меньше, а по факту - нет.

p.s. может не правильно подключать Vcc и AVcc на одну линию? хотя я ж все ацп отключил. так - мысля вслух.