Обсуждаем контроллеры компании Atmel.
Ответить

Atmega328p минимизация потребления...

Вт июл 17, 2018 10:43:02

Экспериментирую с оптимизацией потребления Atmega328p. Предварительно изучил материалы в инете и провел подготовительную работу, но результат определенно не устраивает. Мне удалось добиться потребления 0,8 мА в активном режиме и 0.24 мА в спящем. И если в активном режиме меня потребление устраивает (понятно, что сейчас это голый контроллер и при добавление датчиков потребление вырастет) но вот потребление 240 мкА в режиме сна - очень много. Хотелось уложиться в 10 - 20 мкА.
Вопрос как?

Что уже сделано. Вот схема.
Изображение
Голая Atmega328P-PU вообще без обвязки. Для тестирования контроллер шлет в UART информацию что он делает. Так ка эксперименты были связаны с понижением напряжения питания пришлось сделать оптическую развязку с переходником USB2UART. На схеме она для выхода TX контроллера, но была и для RX (на потребление как оказалось не влияет).

Теперь собственно про минимизацию потребления. Что сделано:
1. Напряжение питания снижено до 2.7В. Меньше не стал, т.к. датчики которые потом будут работать с контроллером меньше не могут.
2. Частота снижена до 1 Мгц. Контроллер тактируется от внутреннего генератора 8 МГц с делителем на 8. Fuse выставлены следующие:
Код:
a328p_1MHz.bootloader.tool=avrdude
a328p_1MHz.bootloader.low_fuses=0x62
a328p_1MHz.bootloader.high_fuses=0xde
a328p_1MHz.bootloader.extended_fuses=0xFF

3. brown out detector выключен. Опять же Fuse'ы выше.
4. Режим сна SLEEP_MODE_PWR_DOWN просыпаемся по watchdog
5. Перед тем как заснуть выключаем все устройства power_all_disable(); когда просыпаемся включаем только таймер 1 и UART
Код:
power_usart0_enable();
power_timer0_enable();

6. При старте контроллера аналоговые выходы устанавливаются в OUTPUT и состояние LOW
Код:
for (byte i = 0; i <= A5; i++)
{
    pinMode (i, OUTPUT);    // changed as per below
    digitalWrite (i, LOW);  //     ditto
}


И со всеми этими упражнениями мы имеем 240 мкА в режиме сна. Куда дальше копать я не знаю. Хотелось бы 10-20 мкА хотя бы....
Что еще можно сделать?

Вот полный код скетча:
Код:
#include "Test3.h"
#include <avr/io.h>
#include <avr/interrupt.h> // работа с прерываниями
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/power.h>

volatile byte watchdogCounter = 0;

void setup_watchdog(byte sleep_time)
{
  cli();                           
  wdt_enable(sleep_time);         

  MCUSR &= ~_BV(WDRF);             
  WDTCSR |= _BV(WDCE) & ~_BV(WDE);
  WDTCSR |= _BV(WDIE);             

  sei();                         
}

void arduino_sleep()
{
  cli();                             

  power_all_disable();                 
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  sei();                               

  sleep_mode();                       

}


void savePower( ) {     

        power_all_disable();

          for (byte i = 0; i <= A5; i++)
              {
               pinMode (i, OUTPUT);    // changed as per below
               digitalWrite (i, LOW);  //     ditto
              }


          DIDR1 |= _BV(AIN1D) | _BV(AIN0D);

          MCUCR = bit (BODS) | bit (BODSE);
          MCUCR = bit (BODS);
}


void setup()
{

       Serial.begin(9600);
     Serial.println("Wait 5 sec..");

        delay(5000); // Задержка, чтобы было время перепрошить устройство в случае bootloop

        savePower();

        setup_watchdog(WDTO_8S);

}



ISR (WDT_vect)
{
        WDTCSR |= _BV(WDIE);
      watchdogCounter++;
}


void doSomething() {

        Serial.print("Hello world!!!  Uptime : ");
        Serial.print(millis());
        Serial.print(" _ ");
        for( int i=0; i<100; i++ ) {

                Serial.print(".");
                delay(50);
        }
        Serial.println("");
}


void loop()
{

        power_usart0_enable();
        power_timer0_enable();
    delay(5);


        doSomething();

        Serial.println("Go to sleep....");
        delay(100);

          while (watchdogCounter < 2) //wait for watchdog counter reached the limit, WDTO_8S * 4 = 32sec.
          {
            arduino_sleep();
          }

          Serial.println("Wake up....");
          watchdogCounter = 0;        //reset counter



}

Re: Atmega328p минимизация потребления...

Вт июл 17, 2018 15:21:34

Собака-то тикает, а это и генератор и счетчик.
Хош и мизер, но кушают.
Поставь power down с пробуждением по INT0 (уровневое)/RESET и с отключением ИОН (компаратор/АЦП), собаки и BOD детекции, обеспечь полный останов тактового генератора.
:roll:
И никак не PCINT - они СИНХРОННЫЕ, требуют работы средств тактирования.
Смысл в энергосбережении тогда никакушный...
:roll:
УПС...
Это все касается ТОЛЬКО ЧИСТОГО МК ПОД СТАНДАРТНЫМ СИ,
а никак не АРДУИНЫ!!!
Ибо там половина функционала задействована по-своему.
Установив не предусмотренные режимы энергосбережения можно "подгадить" функции, связанные с таймерами, прерываниями и много чем еще неявно завязанным...
:(

Re: Atmega328p минимизация потребления...

Вт июл 17, 2018 16:44:22

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

Да и вообще, все меры написаны в разделе Minimizing Power Consumption ДШ.

Re: Atmega328p минимизация потребления...

Вт июл 17, 2018 16:47:54

Собака-то тикает, а это и генератор и счетчик.
Хош и мизер, но кушают.
Поставь power down с пробуждением по INT0 (уровневое)/RESET


Проблема в том что мне надо просыпаться периодически и что то делать.

и с отключением ИОН (компаратор/АЦП), собаки и BOD детекции, обеспечь полный останов тактового генератора.
:roll:
И никак не PCINT - они СИНХРОННЫЕ, требуют работы средств тактирования.
Смысл в энергосбережении тогда никакушный...
:roll:


Ну вроде и так все отключил.
Перед засыпанием зову power_all_disable();

УПС...
Это все касается ТОЛЬКО ЧИСТОГО МК ПОД СТАНДАРТНЫМ СИ,
а никак не АРДУИНЫ!!!
Ибо там половина функционала задействована по-своему.
Установив не предусмотренные режимы энергосбережения можно "подгадить" функции, связанные с таймерами, прерываниями и много чем еще неявно завязанным...
:(


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

Re: Atmega328p минимизация потребления...

Вт июл 17, 2018 17:10:11

Судя по схеме, перевод всех портов на вывод 0 засвечивает светодиод оптрона.

Re: Atmega328p минимизация потребления...

Вт июл 17, 2018 19:52:18

Foxhound
Если применена адурина - программа писалась в адурино-IDE - то в обязательном порядке будет подключено ТО НЕ ЗНАЮ ЧТО.
А Вы туда еще стандартно библиотек из Си подтыкнули (в адуринке оные по умолчанию уже подключены - в тексте скотча это не указывается).
Собственно делать такие "вольности" можно, но если перед тем досконально изучить не только сам GCC, но и файлы сопровождения проекта (по умолчанию скрытые от пользователя) в самой IDE.
Задача не из простых даже для специалиста - так что лучше пишите или под чистым СИ в АВР студии или под ассемблером.
Адуринка рассчитывалась для мощной обработки данных и "стандартных" (в понимании простого пользователя) инструментов ввода-вывода.
А "спецэфекты" с прерываниями, собака, BOD и расширенные функции периферии используйте те, что в референсе даны.
Может и повезет активировать, но не факт, что программа без сбоев выполняться будет.
А уж став гуру по работе с самой IDE копайте поглубше.
:beer:

Re: Atmega328p минимизация потребления...

Ср июл 18, 2018 10:17:32

Ну похоже на правду....
Попробовал вот такую программку
Код:
#include <avr/sleep.h>
#include <util/delay.h>

int main(void){

        for(int i=0; i<10000; i++) {
                _delay_us(500);
        }

    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_mode();
    while(1);
}


После старта потребление 0.8 mA, потом падает в 0. Видимо потребление меньше 10 uA, а мой мультиметр это померить уже не может.
Дальше чуть сложнее.
Код:
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/wdt.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>

ISR (WDT_vect) {

        WDTCSR |= _BV(WDIE);
}

int main(void) {

        for(int i=0; i<10000; i++) {
                        _delay_us(500);
        }


    wdt_reset();
    wdt_enable(WDTO_1S);
    WDTCSR |= _BV(WDIE);
    sei();

    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    while(1) {
            sleep_enable();
            sleep_cpu();
    }

}


Хотел просыпаться по watchdog, но похоже что watchdog не включается потому что контроллер засыпает (судя по потреблению упавшему в 0) и больше не просыпается.
И не понятно где и что не так.

И еще, если отказаться от Arduino IDE, то что использовать под Linux.
Я использовал Eclipse + Sloeber плагин, но он тоже в большей степени ориентирован на Adruino style.
Смотрел на связку Eclipse + AVR plugin но похоже он с 2012 года не обновлялся....
Еще какие то альтернативы для Linux?

Re: Atmega328p минимизация потребления...

Ср июл 18, 2018 10:49:55

Foxhound писал(а):Смотрел на связку Eclipse + AVR plugin но похоже он с 2012 года не обновлялся....
и в чем проблема? что с тех пор поменялось?

Re: Atmega328p минимизация потребления...

Ср июл 18, 2018 14:51:17

Это все касается ТОЛЬКО ЧИСТОГО МК ПОД СТАНДАРТНЫМ СИ,
а никак не АРДУИНЫ!!!
Ибо там половина функционала задействована по-своему.
Установив не предусмотренные режимы энергосбережения можно "подгадить" функции, связанные с таймерами, прерываниями и много чем еще неявно завязанным...
:(


С Ардуиной там все хорошо. У автора потребление независимо от Ардуины, потребляет Watch Dog Timer 250 uA, куда меньше? Периферия отключается как ардуиновской библиотекой, так можно и напрямую в регистры писать, хоть на ассемблере вставки делать.
Если нарушить работу таймеров ничего страшного не будет, изменится частота ШИМ и время будет считать не корректно.
Нормальная среда программирования, работать можно.

Контроллер тактируется от внутреннего генератора 8 МГц с делителем на 8.


Я специально для этих целей искал кварцы на минимальную частоту, нашел распространенные на 3.xxxx Мгц от телевизоров, что-то связанное с цветностью, более низкочастотных нет доступных. Хотя можно и на 4МГц ставить проще так, почти стандартная частота.
Поправил загрузчик под эту частоту, есть онлайн генераторы загрузочной прошивки. Но будет ли потребление ниже, чем с внутренним генератором тут вопрос...

Была еще идея использовать внешний RC генератор вместо встроенного WDT. Просыпаемся и на выход R ставим состояние обратное имеющемуся. Засыпаем, через время RC цепочки (например 0.1 секунда) состояние пина меняется, срабатывает прерывание и всё по новой. С резистором на 1 МОм потребление будет 2 uA. Но если переключить не корректно пин (из-за помехи например), микроконтроллер уснет навсегда.

Добавлено after 1 hour 44 minutes 14 seconds:
Напряжение питания снижено до 2.7В. Меньше не стал, т.к. датчики которые потом будут работать с контроллером меньше не могут.


Можно теоретически снизить питание до 2.5 .. 2.4В, логически уровни останутся совместимы, и утечки токов от периферии в микроконтроллер еще не будет, не откруются диоды внутрениие от пинов к +VCC, приток и паразитное питание начнется если на пинах больше на 0.7 вольта чем подано питание, да и страшного в этом ничего нет обычно, если токи небольшие.
Другое дело что экономия мизерна, даже при 1.8В, а сложность подключения растет...

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

Re: Atmega328p минимизация потребления...

Ср июл 18, 2018 15:17:54

Еще какие то альтернативы для Linux?

VSCode + PlatformIO
https://platformio.org

Re: Atmega328p минимизация потребления...

Ср июл 18, 2018 21:06:12

Вот это почитайте: https://www.gammon.com.au/power -- своего рода хрестоматия с примерами и иллюстрациями по минимизации энергопотребления атмеги.

Re: Atmega328p минимизация потребления...

Чт июл 19, 2018 21:05:13

Вот это почитайте: https://www.gammon.com.au/power -- своего рода хрестоматия с примерами и иллюстрациями по минимизации энергопотребления атмеги.


Ну собственно все в точности по этой статье и делалось....
В итоге после того как было проделано все что написано в статье потребление в режиме сна получалось 240 мкА.
Проблема решилась только отказом от программного Arduino окружения. Сейчас потребление в активном режиме 800 мкА в режиме сна меньше 10 мкА. Реально измерить не могу т.к. прибор не позволяет - показывает 0.
Решилась проблема переходом вот к такому "скетчу":
Код:
#include <avr/delay.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>

volatile int interruptCount=0;

ISR (WDT_vect) {
   WDTCSR |= _BV(WDIE);
    interruptCount++;
}

void doSomething() {
   for(int i=0; i<10000; i++)    _delay_us(500);
}

void sleep() {
   interruptCount=0;
   while(interruptCount<5) {
      sleep_cpu();
      wdt_reset();
   }
}

void setup() {
   wdt_reset();
   wdt_enable(WDTO_1S);
   WDTCSR |= _BV(WDIE);
   sei();
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
   sleep_enable();
}




int main(void) {

   setup();

    while(1) {
       doSomething();
       sleep();
    }
}

Re: Atmega328p минимизация потребления...

Пт июл 20, 2018 00:05:45

Подаете питание через резистор 1000 ом, при 800 мка будет падение 800 мВ, при 10 мка - 10 мВ. При еще меньшем токе резистор 10 кОм, как засыпает переключать на него временно, иначе если проснется тока не хватит для работы...
Странно, что в Ардуине мешало снизить потребление. АЦП? Прерывания от таймера 1?

Re: Atmega328p минимизация потребления...

Пт июл 20, 2018 06:00:40

АРДУИНО это ОПЕРАЦИОННАЯ СИСТЕМА/гибрид компилятора с интерпретатором.
Суть однако в следующем -
ежли в проекте использовано чего из спецфункций референса, подключающих/конфигурирующих выводы портов, UART, таймеры, SPI, I2C, АЦП то в начальной конфигурации автоматически проставляются соответствующие прописи (не факт, что в самом начале программы в разделе "холодной конфигурации")
Как данный момент реализован - надо изучать саму IDE и дополнительные файлы - конфигураторы - я не спец в Си до такого уровня -
Х/З как те файлы/разделы именуются... но то,что оные там в изобилии это ФАКт.
Поставьте во вкладке НАСТРОЙКИ флажокв строчке ПОКАЗАТЬ ПОДРОБНЫЙ ВЫВОД -> КОМПИЛЯЦИЯ
и в окошке СООБЩЕНИЯ КОМПИЛЯТОРА -> ВСЕ.
Потом запустите компиляцию рабочего скотча в десяток строчек и полюбуйтесь тем, что пробегает быстрехонько в нижнем окошке.
Как беленькими, так и красненькими строчками (можно позднее просмотреть используя движок прокрутки того окна).
:wink:
Аналогию имеем при работе не с компилятором а с интерпретатором - в состав средств референса включены расширенные функции, кои сделаны авторами/разработчиками IDE - пользоваться ими весьма удобно, а как оные созданы - скрыто от рядового пользователя - да вобщем-то и особо того пользователя этот вопрос и не интересует, так же как и минимальный набор стандартно подключаемых *.h файлов.
Так что или пользуемся тем, что предоставлено (и весьма солидно/достаточно) или переходим на работу с "чистыми" компиляторами.
:beer:

Re: Atmega328p минимизация потребления...

Пт июл 20, 2018 15:18:11

Странно, что в Ардуине мешало снизить потребление. АЦП? Прерывания от таймера 1?


Ну вот это для меня загадка....
Я вроде перед тем как заснуть звал power_all_disable() что должно было таймер 1 выключить.
И исходники int man() в библиотеки ардуины посмотрел.... Ничего там криминального нет....

Но вот почему то контроллер не засыпал. Как только перестал использовать ардуиновские библиотеки, потребление сразу стало адекватным.

Добавлено after 19 minutes 9 seconds:
Ну то что библиотеки ардуины что то делают с режимом работы контроллера, похоже факт. Добиться экономии с ними не получилось

АРДУИНО это ОПЕРАЦИОННАЯ СИСТЕМА/гибрид компилятора с интерпретатором.


Вот тут вы народ в заблуждение не вводите. Arduino IDE это в чистом виде среда разработки, которая использует внешний компилятор avr-gcc
Я, кстати, не пользуюсь Arduino IDE, я использую Eclipse.
И в первом варианте скетча использовал библиотеки Arduino. Собственно с чем и проблема была.
Да, вы правы.... похоже эти библиотеки много чего ненужного включают. Там макросами включаются/выключаются разные куски кода в зависимости от того с каким железом работаем.

Так что или пользуемся тем, что предоставлено (и весьма солидно/достаточно) или переходим на работу с "чистыми" компиляторами.


Так что решение это не "переход к компиляторам"а отказ от использования библиотек arduinno. :))
Кстати скетч который я приводил выше (c функцией main и без setup, loop и библиотек arduino) можно прямо в Arduino IDE откомпилировать и залить в Arduino UNO и все будет работать.

Re: Atmega328p минимизация потребления...

Сб июл 21, 2018 03:48:24

Теоретически, можно было отредактировать файл main.cpp на предмет блокирования вызова функций init() и serialEventRun(). Другой вариант -- отредактировать код wiring.c, если какие-то действия внутри init() необходимо оставить.

С программной точки зрения Ардуино -- это обертка над GCC, облегчающая жизнь тем, кто не считает себя продвинутым программистом, но все же желает писать несложные программы для МК. Аналоговые измерения, генерация ШИМ-сигнала, интерфейсы SPI, I2C, UART доступны там в виде "бери и пользуй", причем, независимо от аппаратной платформы. Чуваков, которые долгими ночами со словарем читали пухлые даташиты различных микроконтроллеров, такая простота страшно раздражает.

Re: Atmega328p минимизация потребления...

Сб июл 21, 2018 04:42:02

Теоретически, можно было отредактировать файл main.cpp на предмет блокирования вызова функций init() и serialEventRun(). Другой вариант -- отредактировать код wiring.c, если какие-то действия внутри init() необходимо оставить.

Так никто не мешает не использовать штатный loop, написав свой while (1).
Можно также отключить системный таймер 0, если не используются delay.
Вообще, в power down без проблем получается менее 10 мка, а все эти дополнительные действия нужны для того что бы уменьшить время нахождения в активном режиме. Если это важно.)

Re: Atmega328p минимизация потребления...

Сб июл 21, 2018 05:19:36

...

С программной точки зрения Ардуино -- это обертка над GCC, облегчающая жизнь тем, кто не считает себя продвинутым программистом, но все же желает писать несложные программы для МК. Аналоговые измерения, генерация ШИМ-сигнала, интерфейсы SPI, I2C, UART доступны там в виде "бери и пользуй", причем, независимо от аппаратной платформы. Чуваков, которые долгими ночами со словарем читали пухлые даташиты различных микроконтроллеров, такая простота страшно раздражает.


Или как вариант получения сложной обработки данных без громадных подпрограмм на ассемблере в случае минимальной загрузки аппаратных ресурсов (стандартный минимум таймеров/приемопередатчиков в системе обработки данных). - Устройство второго уровня - старше прикладного периферийного модуля с мозгами, но младше основного ПК.
Насчет "пухлых даташитов"...
Зря так уж за то направление...
На сегодня "система-на-кристалле" - нашпигованный расширенной периферией АРМ (оные кстати включены в поддержку ардуино-IDE, как и платки с интеловскими i586/i686) и подобное направление явно требуют среды подобной ардуино, да еще и интегрированного в МК подвида "биос" - необходимого минимума при смене семейства и единой среде разработки (аналогия операционной системы для ПК).
Собственно разницы в начинке и в направлении применения более - менее оснащенных разновидностей АРМ и ПК уже все меньше.
В то же время для решения прикладных задач, которые в большинстве случаев требуют незначительных ресурсов, приоритет остается за относительно простыми МК с минимальным специализированным набором периферии и одно-двухзадачным прикладным ПО, созданным или на ассемблере или на Си.
Вот те даташиты действительно перечитывать надо.
По аналогии -
КТО ИЗ ПОЛЬЗОВАТЕЛЕЙ/РАЗРАБОТЧИКОВ ПРОСТОГО ПО ДЛЯ ПК
ЧИТАЕТ ПОЛНЫЕ ДАТАШИТЫ НА СЕВЕРНЫЙ/ЮЖНЫЙ МОСТЫ И НА ПРИМЕНЯЕМЫЕ ПРОЦЕССОРЫ В КОМПЛЕКТЕ С ОСТАЛЬНОЙ НАЧИНКОЙ МАТЕРИНКИ?
от силы читают описание регистров LPT и COM портов без привязки в той микросхеме, где ныне оные регистры обитают.
:wink:

Re: Atmega328p минимизация потребления...

Вс июл 22, 2018 01:35:42

[uquote="a5021",url="/forum/viewtopic.php?p=3423004#p3423004"]
Собственно разницы в начинке и в направлении применения более - менее оснащенных разновидностей АРМ и ПК уже все меньше


Это всё подходит для Raspberry Pi Zero, по цене чуть выше Ардуины на борту операционная система со всем программно-аппаратным фаршем.
Ассемблер "душевно", но не практично ))

Re: Atmega328p минимизация потребления...

Пн июл 23, 2018 03:15:04

Так никто не мешает не использовать штатный loop, написав свой while (1).Можно также отключить системный таймер 0, если не используются delay.

loop() и даже setup() вызываются после init(), когда практически вся периферия под нужды ардуины уже проинициализирована. Вот чтобы ненужное не инитить зря, а потом не останавливать, надо либо не вызывать init(), либо вызывать его модифицированную версию.

Насчет "пухлых даташитов"...
Зря так уж за то направление...

Помнить, что значат сотни и сотни битов -- это конечно офигетительно, но лучше бы иметь хорошие средства разработки, которые этими бы битами манипулировали автоматически. Ведь что получается, если, скажем, я хочу включить тот же I2C. Сначала я должен посмотреть, какие регистры есть и за что они отвечают. Потом я должен в правильном порядке занести нужные значения в нужные регистры и ничего не перепутать. Ну нафига столько счастья сразу? По хорошему, я должен в софтине воткнуть галку включить I2C, выбрать ему режим из ниспадающего списка, а еще бы хорошо произвольные ноги назначить. Нафиг мне сначала водить пальцем по даташиту, выясняя, где и что включает это I2C, потом из заголовков копировать оперделения и делать прочую обезьянью работу? Шизофрения какая-то.
Ответить