Режим энергосбережения
- Войдите на сайт для отправки комментариев
Вс, 21/02/2016 - 09:33
Добый всем день!
Проясните, пожалуйста такую тему. Я пользуюсь Arduino IDE для компиляции. Сразу предвижу ответ "не пользуйтесь им", но всетаки по сути дела. Есть известный, наверное, всем скеч:
#include <avr/io.h> #include <avr/sleep.h> #include <avr/interrupt.h> #include <util/delay.h> int main(void) { DDRC |= (1 << PC2) | (1 << PC1); // leds for testing DDRD &= ~(1 << PD2); // INT0: input... PORTD |= (1 << PD2); // ...with pullup. // level interrupt INT0 (low level) MCUCR &= ~((1 << ISC01) | (1 << ISC00)); // infinite main loop while (1) { // trigger leds for testing PORTC ^= (1 << PC1); _delay_ms(500); PORTC ^= (1 << PC1); // enable external interrupt GICR |= (1 << INT0); // set sleep mode set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep_mode() has a possible race condition sleep_enable(); sei(); sleep_mode(); //sleep_cpu(); sleep_disable(); // waking up... // disable external interrupt here, in case the external low pulse is too long GICR &= ~(1 << INT0); // disable all interrupts cli(); } } ISR(INT0_vect) { // ISR might be empty, but is necessary nonetheless PORTC ^= (1 << PC2); // debugging }
Решил проверить, на сколько все верно. Использую Atmega8L для эксперимента. Все ожидания подтвердились!!! Ток меньше 1 микроАмпера
Попробовал изменить скеч заменив int main(void) на void setup() и void loop() соответственно. В самом скече больше ничего не менял. После компиляции ток в режиме сна стал 129 микроАмпер!!!
Кто нибудь может сие объяснить?
Даже не так.
Этот потребляет в режиме сна 110 мкА:
А вот этот 0.7 мкА:
Всё довольно логично, просто сказать что именно не выключено сходу сложно. При использовании конструкции setup и loop подгружается масса ардуиновских библиотек. Они включают таймеры, ацп, и прочее, и никто не считал сколько всего меняется. Где то пролетала ссылка на детальные исследования зарубежного товарища Nic Gammon, где скорее всего можно найти информацию на этот счёт.
Так Вы посмотрите что делает ардуиновский main (исходники же доступны). Он там заводит таймеры, включает ADC и делает много чего другого. Повыключайте всё это и будет значительно лучше.
Нашёл http://www.gammon.com.au/power
Нашёл http://www.gammon.com.au/power
Спасибо за ответы!
Прикольно, скетчи ведь от туда ( скечь B) :-)
А что main их не грузит?
Еще. Подключил INT0 для пробуждения, но вот кушает во время сна 270 мкА. Как снизить?
А что main их не грузит?
Ну, Вы грузите из в main? А кроме Вас этого никто не сделает. Там делается только то, что Вы напишете.
Другое дело Ардуиновская среда. У них ведь основная фишка - "Всё просто и доступно любому чайнику". Вот они всё и делают, чтобы чайник мог просто пользоваться analogRead и millis, и чтобы у него не болела голова о том. что для всего этого нужно ещё кучу всяких битов в разные места засунуть. По-моему, нормальный подход. Именно он и обеспечил популярность Ардуино. Скажите людям, что для того чтобы запустить blink им надо правильно настроить таймер - желающих помигать диодами сразу же поубавится. Никто ведь не рекламирует Ардуино как среду для профессиональной разработки промышленных изделий. Это макетная среда, где всё упрощено, а за упрощения нужно платить :)
Я просто думал, что если среда одна и та же, то стандартные библиотеки подтягиваются в любом случае.
Ок. Спасибо. А поповоду тока, потребляемого при использовании прерыванием?
Ок. Спасибо. А поповоду тока, потребляемого при использовании прерыванием?
ну сделайте внешнюю подтяжку, скажем мегаомным резюком.
Еще. Подключил INT0 для пробуждения, но вот кушает во время сна 270 мкА. Как снизить?
INT0 ничего не потребляет, дело не в нем
на момент ухода в сон все ноги мк включая не использованные должны быть в одном из состояний:
- настроены на выход
- настроены на вход и включена внешняя подтяжка
- настроены на вход и присоеденена внешняя подтяжка
- настроены на вход и закорочены на GND - это вариант длянеиспользованных пинов, но можно и с внутренней подтяжкой
еще важно определиться с тем нужно ли просыпаться от таймеров. Таймеры много жрут
ждет ацп
жрет watch dog
жрет детектор напряжения который фьюзами включается
Опыты продолжаются......
Atmega8L + nRF24L01+.
Перечитал кучу статей но так и не заработало энергосбережение.
Это работает хорошо - 1 мкА:
Но стоит сделать
и radio.powerDown(); не помогает, ток становится 7 мА. Причем с модулем или без все равно.
Посмотрел исходники - PWR_UP меняется с 1 на 0 , но толку чуть. Что делать не понимаю.
Во, интересная тема! Я радиомодуль планирую через полевик включать. С ноги низзя - на передаче жрет много((
Еще. Подключил INT0 для пробуждения, но вот кушает во время сна 270 мкА. Как снизить?
INT0 ничего не потребляет, дело не в нем
на момент ухода в сон все ноги мк включая не использованные должны быть в одном из состояний:
- настроены на выход
- настроены на вход и включена внешняя подтяжка
- настроены на вход и присоеденена внешняя подтяжка
- настроены на вход и закорочены на GND - это вариант длянеиспользованных пинов, но можно и с внутренней подтяжкой
еще важно определиться с тем нужно ли просыпаться от таймеров. Таймеры много жрут
ждет ацп
жрет watch dog
жрет детектор напряжения который фьюзами включается
Уважаемый, axill!
Не могли бы подробнее разяснить как сделать то что Вы описали?
Действительно, у меня есть такие строки кода
После них режим спячки в котором он потребляет 270 мкА. Если две последние строки закоментировать, то ток в спячке падает до 100 мкА. Пробовал подтягивать все входы А0-А5 digitalWrite(А0, HIGH); и LOW - непомогает. Вобще HIGH плохо, т.к. на входе резистор на землю (делителя). Возможно ли перевести их в начальное состояние?
To, так вы читали статью того дядьки из ссылки? Он же там всё отключает что б добиться полного минимума..
To, так вы читали статью того дядьки из ссылки? Он же там всё отключает что б добиться полного минимума..
A я и спрашиваю: "как?"
и потом везде пишут - режим powerDown отключает все!!!
Или не так?
To, ну судя по дядькиным эксперементам само ничего не отключается. Скопируйте в свой скетч все его команды, да и проверьте.. делов то.
Да, признатся, Вы были правы. У меня это первый опыт с энергосбережением. В общем удалось добиться в режиме сна 1 мкА.
Но! У меня в схеме задействовано INT1 по LOW уровню. Источником служит RC цепочка, заряжаемая импульсом. Поскольку напряжение на ноге INT1 меняется плавно, то потребление при "среднем уровне" оказывается весьма велико. Отказаться от внешнего прерывания нельзя, поскольку atmega8L пробуждается из состояния Power Down только INT. Буду думать дальше. Весьма признателен. Спасибо.
У меня в схеме задействовано INT1 по LOW уровню. Источником служит RC цепочка, заряжаемая импульсом. Поскольку напряжение на ноге INT1 меняется плавно, то потребление при "среднем уровне" оказывается весьма велико.
Несколько раз перечитал, много думал. Но так и не понял как такое может быть. Ну импульс, и что? . Из статьи дяди Ника возьмём например скетч J , я на нём лично измерял - МК потребляет в режиме сна 0,3-0,4 мка. Т.е. практически ничего не потребляет. Что нужно сделать, что-бы потребление стало велико, как часто дёргать это прерывание, каждую миллисекунду? Тогда зачем спать..
Во, интересная тема! Я радиомодуль планирую через полевик включать. С ноги низзя - на передаче жрет много((
В чем глубинный смысл включать/выключать радиомодуль через полевик? Не могу понять, зачем бы это могло потребоваться.
dimax!
Наверно я неверно обьяснил. К ножке INT1 подкючены параллельно R=2MOm и C=500мкФ. Через диод с другой ноги на эту цепочку подается короткий импульс, который заряжает кондер. Теперь на INT1 лог.1. Во время действия импульса происходит считывание информации (импульс является еще и запиткой датчиков). После окончания импульса кондер начинает разряжаться с лог. 1 до лог.0. Происходит срабатывание INT1 по LOW. Дальше процесс повторяется. Вот во время разрядки (RC определяет время разрядки, "некое реле времени" ~ нескольно минут) пока уровень плавно меняется на INT1 и возрастает ток. Это сделано потому, что разбудить из PowerDown только через внешний INT. Если бы это был скачкообразный переход, то все было бы нормально.
To, как то извратно.. А что мешает по-обычному сделать? Импульс включает МК, он даёт питание датчикам, делает свои дела и уходит спать..
To, как то извратно.. А что мешает по-обычному сделать? Импульс включает МК, он даёт питание датчикам, делает свои дела и уходит спать..
Чей импульс? Кроме МК и nrf21L01+, который то же спит, никого нет!
To, ну вот только сейчас всё понял :) да..задачка. Я б наверно часики rtc прикрутил, типа ds3231. Тогда всё будет по-человечески :)
To, ну вот только сейчас всё понял :) да..задачка. Я б наверно часики rtc прикрутил, типа ds3231. Тогда всё будет по-человечески :)
Ха! Ну ладно. Забей! Я решил проще, положил в краватку вмеcто atmega8L - atmega328P. У нее все нормально - просыпается от WDT. Железка уже работает. Конечно замена не равноценная, но что делать.
Спасибо за участие!
Во, интересная тема! Я радиомодуль планирую через полевик включать. С ноги низзя - на передаче жрет много((
В чем глубинный смысл включать/выключать радиомодуль через полевик? Не могу понять, зачем бы это могло потребоваться.
Написал же - на передаче много жрет.
Автор, открой исходники ардуины, там найдешь файл hardware/arduino/avr/cores/arduino/main.cpp. Как видно, setup() и loop() это лишь упрощение, на деле все происходит в main:
С полевиком он меньше жрать не станет. На свой вопрос я ответа не получил.
Не совсем понятно, но речь видимо о том, что МК всё равно не спит всё то время, пока на плюсе конденсатора (на выводе INT1) "где то ещё не ноль, но уже не единица". Если это так, то проблема лечится инвертором на полевом транзисторе, ну только тогда надо конденсатор не заряжать а разряжать, т. к. логика будет наоборот.
С полевиком он меньше жрать не станет. На свой вопрос я ответа не получил.
Какие полевеки? Какие лапы? Вы не пятую ли ногу пытаетесь собаке пришить?
Будучи предоставленным самому себе, NRF24L01+ находится в состоянии глубокого сна с суб-микроамперным потреблением (900нА). В процессе инициализации и подотовки приема/передачи, он сам выбирает оптимальное энергопотребление, чередуя режимы Standby-I (25 мкА) и Standby-II (320 мкА). Максимальное потребление (~14 мА) возникает непосредственно в момент работы радио-передатчика, время работы которого ограничено аппаратно и не может превышать четырех миллисекунд.
Теперь вопрос: зачем весь этот цирк с конями, полевиками и лапами, если единственное, чего можно добиться прикручивая внешнюю кустарную коммутанцию -- это усложнение схемы и увеличение потребления ? Я уж не спрашиваю, как четырнадцатью миллиамперами можно сжечь ногу ардуине.
А каким образом понизить частоту процессора, есть ли функция чтобы задавать частоту? Так как это позволит в состоянии бодрствования снизить энергопотребление.
Одним из способов может быть запись соответствующего значения в прескалер (регистр CLKPR). Частоту можно понизить в 2, 4, 8 ... 128 и 256 раз. Этой фишкой удобно пользоваться для динамического изменения скорости работы МК. Например, если МК ждет некоего события и более ничем не занят, то частоту можно понизить, а когда событие происходит, то поднять частоту обратно и обработать его на максимальной скорости.
Одним из способов может быть запись соответствующего значения в прескалер (регистр CLKPR). Частоту можно понизить в 2, 4, 8 ... 128 и 256 раз.
а поподробней где можно почитать как это с рабочим кодом увязывать
а поподробней где можно почитать
В даташите.
к сожалению я неумею в даташитах разбираться, я безнадежный новичек :)
к сожалению я неумею в даташитах разбираться, я безнадежный новичек :)
Самое время научиться.
Ну, если в даташитах не умеете, так смотрите классическую статью Гэммона, там про экономию энергии всё написано. В частности про уменьшение частоты с примером и обсуждением (начиная со слов "Altering the processor frequency")
Слава Богу, это в одну строчку делается, если power.h включить
Теперь не могу найти данную библиотеку, и еще вопрос так как слышал что не на всех платах ардуино можна реализовать спящий и подобный режим типа дело в загружчике???
Теперь не могу найти данную библиотеку,
\Program Files\Arduino\hardware\tools\avr\avr\include\avr\power.h
А частота работы SPI зависит от значения делителя прескалера?
А частота работы SPI зависит от значения делителя прескалера?
А сами-то как думаете? Конечно, зависит. У SPI нет собственного осциллятора.
так power.h должен находится в папке libraries чтоб работала библиотека но я че то недоганяю че куда(
Зависит. Только большинству устройство частота SPI не так уж и важна. В рамках разумного, конечно. Какой подается клок, с такой скоростью и идет обмен данными.
Зависит. Только большинству устройство частота SPI не так уж и важна. В рамках разумного, конечно. Какой подается клок, с такой скоростью и идет обмен данными.
так power.h должен находится в папке libraries чтоб работала библиотека но я че то недоганяю че куда(
Пусть лежит, где лежит. При подключения в тексте программы через инклюд, компилятор его находит сам.
Зависит. Только большинству устройство частота SPI не так уж и важна. В рамках разумного, конечно. Какой подается клок, с такой скоростью и идет обмен данными.
Частота SPI важна slave-устройству. Если ардуина выступает мастером, то да, пониженная частота SPI будет влиять только на скорость обмена по SPI. А вот если ардуина выступает слейвом, то принимать данные по SPI на пониженной частоте она может и не успеть. Например, для ATmega328, при 16Мгц тактовой, гарантируется прием только на частоте SCK до 4МГц, хотя передавать она может и на 8МГц.
В итоге, если ардуина мастер на SPI, то тактовая частота не влияет на работоспособность SPI. Если slave - то может привести к неработоспособности SPI.
вроди все без ошибки компилируется но если оставить значение 256 то в моем приборе экран даже не показывает ничего, максимум 4 ставил тогда работает но страшно тормозится включение в 2 самое оптимальное ;)
кстати
void
setup
(
void
) так же нельзя писать не будет работать
кстати
void
setup
(
void
) так же нельзя писать не будет работать
Не понял, можно поподробнее, что нельзя писать и как надо?
когда написал в то заработало
void setup() {
иначе ошибку писало
Т.е. Вы хотите сказать, что программа со строчкой
работает, а если вместо этой строчки написать
и ничего больше не менять, то работать перестаёт? Так?
Боюсь, Вы в чём-то ошиблись. Так не бывает. Приведите пожалуйста программу целиком.
извиняюсь вы правы, я не так все делал сначала, все работает) только вопрос в чем rfhlbyfkmyj отличие когда
void
setup
(
void
) и когда просто стандартно
void
setup
(
)?
в чем отличие когда
void
setup
(
void
) и когда просто стандартно
void
setup
(
)?
Смотря в каком языке (это довольно тонкое отличие С от С++).
В С++ разницы нет никакой.
В С разница есть:
Разница в контроле, который осуществляет компилятор. Например, если у функции реально не должно быть аргументов, то лучше явно сказать про это компилятору (написать void). Тогда, если Вы по ошибке вызовете её с аргументом (ами) (ну, например, Вы ошибочно полагаете. что аргументы ей нужны), компилятор обругается. А если не писать void, то он это молча проглотит и ошибку можно будет обнаружить только при выполнении.
Это, конечно, "на скорость не влияет", но лучше так делать. Полная аналогия, например - заземление корпуса люстры. Пока всё хорошо - нет никакой разницы заземлена она или нет. Но если вдруг почему-то фаза закоротит на корпус, то при заземлённой люстре Вы об этом сразу же узнаете (автомат вышибет) и почините. А если у Вас корпус люстры не заземлён, то о том, что на нём фаза Вы узнаете только когда лапнете рукой за корпус при смене лампочки. Видите разницу?