спящий режим
- Войдите на сайт для отправки комментариев
Пнд, 20/01/2014 - 00:38
Всем привет, хочу с помощью кнопки выводить Arduino из спящего режима. Правильно я понимаю, что кнопка привязывается к выходу, отвечающему за прерывание? Вот этот скетч для этого годится?
#include <avr/sleep.h> #include <avr/power.h> int pin = 2; void wakeUp() { Serial.print("WakeUp"); //Проснулись detachInterrupt(0); //Отключаем прерывания while(1); //Бесконечный цикл } void EnterSleep() { attachInterrupt(0, wakeUp, LOW); //Если на 0-вом прерываниии - ноль, то просыпаемся. delay(100); sleep_enable(); //Разрешаем спящий режим sleep_mode(); //Спим (Прерывания продолжают работать.) Программа останавливается. sleep_disable(); //Запрещаем спящий режим } void setup() { Serial.begin(9600); set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Определяем режим сна pinMode(pin, INPUT); } void loop() { ... }
Класс! Ваш ардуино проснется от нажатии кнопки и закружится, закружится... Только не в танце, а в бесконечном цикле. Нафига она такая кому то нужна?
Идея правильная, только скетч кривой.
Тут важно как кнопка подключена, если она подключена на GND, то нужно позаботиться о подтяжке входа на плюс питания или внешним или внутренним регистром
еще полезно в даташите на МК прочитать раздел про режимы питания/сна, чтобы понимать разницу между разными режимами
вы для начала определитесь с задачей
если хотите, чтобы кнопка работала и во время сна и во время бодрствования, то поставьте
attachInterrupt
после выхода из сна и прицепите прерывание к другой функции, которая будет работать от кнопки во время бодрствования. Это первый вариант. Второй вариант - тупо считывать значения порта в loop() но нужно будет "бороться" с дребезгом контактов, иначе одно нажатие кнопки у вас вызовет несколько засыпаний и несколько просыпаний и конечный результат не гарантирован))первый вариант интересует.
Попробовал вот так, привязал кнопку к фунциям для входа в сон и выхода из него. Но походу не правильно (
wakeup серийный порт не пишет
первый вариант интересует.
Попробовал вот так, привязал кнопку к фунциям для входа в сон и выхода из него. Но походу не правильно (
wakeup серийный порт не пишет
Посмотрите на 20-ю строчку вашего кода и скажите, а где функция wakeup (что вы вызываете прерыванием)? Да и не понятно, где вы делаете attachInterrupt при инициализации? Вот запустили вы ардуину - какая функция после запуска будет обрабатывать нулевое прерывание на 2-й ноге? Где вы инициализировали это?
Вообще, интересная статья здесь.
По ее мотивам переписал код для вас. Проверить не на чем пока, должно работать:
Спасибо за помощь, работает как надо.
Только такой вопрос, есть темп.сенсор, записываю его показания на SD карту. Командные строчки для инициализации SD карты нужно забросить в фунцкию
wakeUpNow
или в setup? И то, и другое контроллер выполняет один раз.Ну если по коду, который я вам дал, то функция wakeUpNow выполняется каждый раз после "пробуждения".
Делайте выводы.
Ребята помогите!!!
Залил код с поста #5 поправленный CityCat, ардуино ушла в сон а вывести из сна никак не могу.(((
Arduino pro micro (ATmega 32u4)
Как я понял проснутся должна от нажатия кнопки. Кнопка подключена к выводу 2 замыкание на минус. Также подключен резистор 220Ом от вывода 2 к +5В. Так должно быть?
p/s вообще по замеру тока она вроде как просыпается если удержиать кнопку в замкнутом состоянии, но ком порт не подключается.
Ребята помогите!!!
Залил код с поста #5 поправленный CityCat, ардуино ушла в сон а вывести из сна никак не могу.(((
Arduino pro micro (ATmega 32u4)
Как я понял проснутся должна от нажатия кнопки. Кнопка подключена к выводу 2 замыкание на минус. Также подключен резистор 220Ом от вывода 2 к +5В. Так должно быть?
p/s вообще по замеру тока она вроде как просыпается если удержиать кнопку в замкнутом состоянии, но ком порт не подключается.
Она не просыпается. Вы просто просаживаете питание на землю. Уберите резистор вообще или поставьте резистор побольше (килоОм на 10). В 36-й строке кода видно как нога подтягивается к плюсу программно. Зачем там еще резистор, тем более такого номинала?
Всё равно не работает(((
Засыпает, а просыпаться не хочет. И после ресета не всегда Serial поднимается.
crecker а у Вас всё заработало по скетчу из поста #5 от CityCat. Нечего в нём не меняли?
ничего не менял, работает все.
А светодиод всегда загорается/тухнет при выходе/входе в спящий режим?
Подскажите, почему если я меняю строчку 32 из кода в 10 ответе на вот это, то мотор не стартует при нажатии кнопки. Очень важно
В общем получается вот что:
Убрал строку 36, сделал аппаратную подтяжку резистором 10кОм ноги 2 к +5В.
/Залил скетч в arduino pro mini (Atmega 328 5v)
После включения сразу загорается светодиод, идёт отсчёт 10 сек, по истечению 10 сек диод тухнет ардуино засыпает.
Если замкнуть ногу 2 на GND (без разницы временно или постоянно) диод загорается и начинается отсёт 10 сек, после чего ардуино опять засыпает. и.т.д. Это правельный алгоритм? Я думал что она должна бодорствовать пока на ноге 2 низкий уровень и засыпать когда на ноге 2 появляется высокий уровень.
/Залил скетч в arduino pro micro (Atmega 32u4) (на ней и планирую использовать спящйи режим)
А тут творится вообще что то непонятное
//Если питать от USB то начало правильно:
Ресет - светодиод загорается, идёт отсчёт, светодиод гаснет, ардуино засыпает. При этом USB становится не опознано.
Замыкаем ногу 2 на землю и либо нет реакции вообще либо светодиод быстро вспыхнет и дальше опять тишина(((
//Если питать от отдельного питания без подключения по USB:
Начало правильное - отсчёт, светодиод погас, ардуино засыпает.
на замыкание ноги два на GND первые пару-тройку раз работает нормально (включается светодиод, начинается отсчёт, засыпает). Потом достаточно просто поднести палец не косаясь ноги к ноге 2 и происходит включение светодиода, начинается отсчёт, светодиод гаснет, ардуино засыпает. 0_о
1. C мегой 328 работает корректно. Внимательно прочитайте код, который я приводил - в частности комментарии - для кого я писал? Там увидите и прерывание по заднему фронту на кнопке и то что прерывание нулевое, но на второй ноге (важно к пониманию для дальнейшегно рассмотрения). Здесь и далее i-й номер ноги = digital(i) pin ардуины.
Вот если, например, вы нажмете кнопку не дождавшись отсчета в 10 сек. при горящем диоде - ардуина уйдет тут же в спячку (ну либо через 10 сек. бездействия), а вот вывести ее можно только нажатием кнопки - в этом и весь смысл был. И обращаю внимание - это лишь пример работы с режимами низкого потребления и приведен он исключительно в ознакомительных целях. Если вам нужен конкретный алгоритм - никто за вас его здесь писать не будет - разбирайтесь.
2. Если мы посмотрим на ардуину Pro mini, то увидим (читайте внимательнее, чтоб не приходилось обращать ваше внимание на очевидные вещи!), что пользователю доступны лишь 2 прерывания (посик на странице по слову "прерывание") - нулевое (на второй ноге) и первое (на третьей ноге).
В свою очередь, если взглянуть на описание платы arduino micro, и опять-таки поискать там слово "прерывания", то можно наблюдать, что здесь уже пользователю достыпно 4 (ЧЕТЫРЕ) прерывания: нулевое (на нулевой ноге), первое (на первой ноге), второе (на второй ноге) и третье (на третьей ноге) прерывания.
Если еще не понятно, то обратимся к описанию функции attachInterrupt() (может я не совсем популярно описал). Буквально во второй строке читаем:
Но вот беда - наш микро - не относится к большинству (в данном контексте), посему нулевое прерывание у него на цифровой ноге ноль, а не на второй, как у про мини (или та же уно), например. А на какое прерывание мы вешаем вход и выход из спящего режима? На какой ноге?
Логика понятна? Надеюсь, что да. Оставляю для самостоятельного решения остаток проблемы.
3. Что у вас там за фантомы бродят и почему все так реагирует от внешнего источника питания - я не знаю. Возможно, вы подаете внешних 5 вольт, а не больше как рекомендовано, в том же описании - читайте внимательно. Возможно, где-то в цепи не хватает сглаживающих конденсаторов, возможно еще чего-то. Как не раз здесь говорили "гадать по кофейной гуще можно долго" (с) - не мой.
Удачи!
Потом достаточно просто поднести палец не косаясь ноги к ноге 2 и происходит включение светодиода, начинается отсчёт, светодиод гаснет, ардуино засыпает. 0_о
Повесьте кондёр на прерывание 1-10 н
CityCat, trembo спасибо, я понял ошибки. Не держите зла я только начинаю изучать ардуино. Нужен он мне для одного проекта.
Разьясните пожалйста если не трудно я правельно понял спящий режим?
Я планирую в проекте на ардуино сделать питание, резистивные кнопки, соединение ардуино pro micro с ардуино pro mini (на ардуино про мини будут висеть ещё кнопки и энкодер для управления) и управление аудиопроцессором TEA6320.
вся перефирия будет отключатся при пропадании внешнего сигнала (ACC на авто). Под напряжением останется только ардуино pro micro. В ней крутится кроме всего остально скетч управления питанием перефирии.
В результате у меня будет занято на pro micro
pin 0,1 (Rx, Tx) для соединения с arduino pro mini (ардуино будет выключатся при выключении всей системы)
pin 2,3 (sda, scl) для управления по I2c аудиопроцессором TEA6320 (тоже будет выключатся при отключении всей системы)
То есть я ни как не смогу сделать уменьшение электропотребления arduino pro micro (по таймеру и uart тоже не подходит)
Ну, во-первых, лично я не вижу смысла в использовании 2-х МК. Разве одного не хватит?
Потом, лично я не понял - чего вы хотите и чего куда у вас подключено и при каких условиях и главное где вы собираетесь включать спящий режим? На обоих? На одной? На какой? При каких условиях? Очень мало входных данных для того, чтоб вам что-то подсказать.
Мало того, если уж так не хочется использовать нроги 0 и 1 для связи, то может слышали о замечательной библиотеке SoftwareSerial (гуглите по слову SoftwareSerial - например вот - исключительно примера ради). Опять-таки - это описано в описании платы - ну прочтите ее внимательно наконец!
P.S. Кондер по питанию повесить не лишнее, но вот на цифровую ногу я бы кондер не вешал. Личное ИМХО.
Ну, во-первых, лично я не вижу смысла в использовании 2-х МК. Разве одного не хватит?
Потом, лично я не понял - чего вы хотите и чего куда у вас подключено и при каких условиях и главное где вы собираетесь включать спящий режим? На обоих? На одной? На какой? При каких условиях? Очень мало входных данных для того, чтоб вам что-то подсказать.
Мало того, если уж так не хочется использовать нроги 0 и 1 для связи, то может слышали о замечательной библиотеке SoftwareSerial (гуглите по слову SoftwareSerial - например вот - исключительно примера ради). Опять-таки - это описано в описании платы - ну прочтите ее внимательно наконец!
P.S. Кондер по питанию повесить не лишнее, но вот на цифровую ногу я бы кондер не вешал. Личное ИМХО.
Второй МК нужен только из за того что джойстик с кнопками будет удалён от первой МК на расстояние примерно 1,5 метра и не хотелось тянуть кучу проводов от джойстика до 1-ой МК. а так будет всего четыре провода Rx,Tx,+Uпит,GND
В спящий режим должна уходить только 1-ая мк вся остальная перефирия включая 2-ю мк будет отключатся по питанию.
К 1-ой мк подходит внешний сигнал. Либо +5 на ноге X когда вся переферия отключена (и 1-й МК уходит в сон) либо GND на ноге X и когда надо включить всё. (1-й МК просыпается, на нём крутится скетч по включению всей остальной перефирии включая второй МК)
Скетч включения и внешнюю обвязку я уже сделал всё работает а вот при отключении всего 1-й мк потребляет около 40мА что много для автомобильного АКБ.
Как то так
Я так понимаю я могу 2-ю МК соединить с первой с помощью SoftwareSerial (не используя ноги 0 и 1 первой МК). А спящий режим прицепить на прерывание 0 1-й МК.
Я так понимаю я могу 2-ю МК соединить с первой с помощью SoftwareSerial (не используя ноги 0 и 1 первой МК). А спящий режим прицепить на прерывание 0 1-й МК.
Правильно.
Скетч включения и внешнюю обвязку я уже сделал всё работает а вот при отключении всего 1-й мк потребляет около 40мА что много для автомобильного АКБ.
Я так понимаю я могу 2-ю МК соединить с первой с помощью SoftwareSerial (не используя ноги 0 и 1 первой МК). А спящий режим прицепить на прерывание 0 1-й МК.
Правильно.
Скетч включения и внешнюю обвязку я уже сделал всё работает а вот при отключении всего 1-й мк потребляет около 40мА что много для автомобильного АКБ.
Светодио только один - питание. Можно конешно попробовать но замер я делал только с скетчем питания, а как я понял чем больше будет скетч тем больше она будет потреблять.
У меня вот такая про микро и то не спарк а китайский клон))
... а как я понял чем больше будет скетч тем больше она будет потреблять...
Это где такое написано? О_о
... а как я понял чем больше будет скетч тем больше она будет потреблять...
Это где такое написано? О_о
Незнаю, пока изучал отложилось в голове)))
Когда пробовал Ваш скетч в спящем режиме ардуино потребляла 4,5 мА (это на ардуино про микро) и светодид питания светился, так что я не думаю что физическое отключение светодиода питания сильно снизит потребление.
Незнаю, пока изучал отложилось в голове)))
Что-то не ты вы изучали. Вообще-то есть конечно взаимосвязь того, что написано в скетче и потреблении, но не такая "прямая", как вам хотелось бы ))))
Когда пробовал Ваш скетч в спящем режиме ардуино потребляла 4,5 мА (это на ардуино про микро) и светодид питания светился, так что я не думаю что физическое отключение светодиода питания сильно снизит потребление.
А зря. Сильно снизит. Попробуйте отдельно светодиод запитать и измерить его потребление - скоолько вы думаете он будет потреблять? )))) Но это уж на любителя и к данной теме не относится.
Вообще, можно ж просыпаться и по приходу данных в уарт. Например вот здесь можно почитать. Это просто как вариант вам ;)
Помогите разобраться, пожалуйста, никак не пойму связь между спящим режимом и таймером. Если убираю строчки
из вот этого кода, то работает как надо. Если строчки не убираю, то программа не делает вообще ничего.
Прокоментировал код, надеюсь откликов будет больще
Код работает, только при нажатии кнопки, вместо ухода в сон прыгает между сном и бодрствлванием, тоесть серийный порт пишет
и мотор крутится дальше, подскажите в чем ошибка.
crecker, все верно. Потому как:
А вот
Для кого я писал комменты?
Оно просто не засыпает - оно включает и выключает бит, разрешпющий режим слип.
Где в вашем коде sleep_mode();?
Переписал вот так, мотор крутится написано старт и больше ничего не происходит
Использую вот этот выключатель, подключение 5 вольт и пин 3.
А что должно происходить? Вы на самом деле считаете нас телепатами и мы должны догадываться о ваших действиях? По вашему коду и должно при подключении питания писать "Hello" (каждые 8 сек.) и если включен этот, с позволения сказать "выключатель" - "Start Motor.". Что еще вам нужно? Мы гадать должны?
Про объявления - вообще интересно: читать здесь внимательно - в основном про подтяжку (подсказывать не буду - думайте сами где и почему у вас что не так с подтяжкой)
Далее - зачем вообще вот эти строки (они когда-нибудь будут выполнены? Когда?)?
Создается впечатление, что вы совсем не понимаете, как работает ваш код - здесь могут подсказать, а не рассказывать как работает каждая строка вашего кода.
Внимательно изучите свой код. Поймите смысл строки:
Соответственно, должно прийти понятие что не так и почему.
Еще раз прочитайте описание функции attachInterrupt. Вы уверены, что у вас правильно инициализировано прерывание? Может в вашем случае нужно не FALLING а что-то иное?
P.S. Все о чем я писал касается спящего режима, его включения и выключения. Про ваш код отдельная история, но не в этой теме (то есть я не рассматривал и не искал ошибки в нем - он мне неинтересен).
ок, задумка была такая. После загрузки кода ардуино сначала спит, тоесть ничего не делает и потребляет минимум электроэнергии. При нажатии кнопки, программа начинает работу: делает инициализацию, вращает мотор и переодически меряет температуру и запивывает на SD карту.
При смене положения кнопки программа прерывается и ардуино уходит в спящий режим до последующего нажатия кнопки.
Почему то мотор не выключается, ведь при переходе в режим
должны выключатся все таймеры, отвечающие за шим.
Строчки
работают, если sleep() заменить на
тоесть при выключении кнопки мотор останавливается.
Ну, во-первых, переход в режим сна осуществляется вот этой строкой (сколько можно говорить уже):
а не этой:
Если нужна реакция при смене положения кнопки, то очевидно, что прерывание нужно ставить по CHANGE, а не FALLING - это тоже почему-то непонятно и я уже не в первый раз об этом говорю.
Ну и в-третьих, при смене сигнала с 1 в 0 (задний фронт) на пине, на котором вы повесили прерывание (читай - при выключении кнопки) собственно и сработает функция, которая вызывается прерыванием, а она уведет ардуину в спящий режим, посему все что после else (строки 109-113 вашего кода) обрабатывать будет некому - ардуина спит. Но это было бы... Если б вы подтянули ногу к земле, т.к. при отключении от нее 5в., неизвестно что на ней будет - собственно писал вам про подтяжку. Когда же вы включите свою кнопку, на ноге будет лог.1, следовательно то, что под else тоже не будет обрабатываться. Внимание вопрос (повторяю тоже второй раз): зачем вообще вот эти строки (они когда-нибудь будут выполнены? Когда?)?
Вам сложно почитать? Нужно разжевать?
P.S. Зачем вам такие сложности? Включате кнопкой питание ардуины - все работает. Выключаете - все останавливается. В чем проблема-то?
Ну так у ардуино есть 6 спящих режимов
надо же указать какой именно режим должен вызываться или не правильно.
Ну так у ардуино есть 6 спящих режимов
надо же указать какой именно режим должен вызываться или не правильно.
Всегда думал что их 5:
С засыпанием просыпанием всё заработало как часики))) Спасибо большое CityCat.
Вот только есть одно НО....
Какая то проблема с USB. При первой подачи питания, если не уводить ардуину в сон USB (COM порт) работает как пологается. А вот после просыпания никак не хочет. При чём это не зависимо от кода который у меня использует Serial, пробовал и без него всё равно такой же результат.
Возможно как то корректно деактивировать перед уходом в сон и активировать после просыпания COM порт кроме Serial.end(), Serial.begin().?
Какая то проблема с USB. При первой подачи питания, если не уводить ардуину в сон USB (COM порт) работает как пологается. А вот после просыпания никак не хочет. При чём это не зависимо от кода который у меня использует Serial, пробовал и без него всё равно такой же результат.
В этом вопросе вам может помочь изучение разных режимов сна. http://avr.ru/beginer/understand/sleep_mode
Для меня detachInterrupt() так и осталась непонятной, поэтому у меня однократно в setup() ставится прерывание и всё. И если оно вдруг случилось во включенном состоянии - смотрим флаг "включаемся" - если true, подождать пару сек и если со входа кнопки всё ещё ноль (т. о. кнопа жмётся) - продолжать заводить, иначе спать. А если флаг false - то значит однозначно проснулись, если истекло более 5 сек, значит спать. Это позволяет по кнопке проснуться не сразу а её надо жать долго (2 с), а по повторному нажатию засыпать (если прошло не менее 5 с). В примере прога для фонарика с восемью выходами для светодиодов, там регулируется больше/меньше и умеет спать.
всем привет. киньте плиз ссыль на либс <avr/sleep.h> и на ее описание
Какую ссыль? Эта либа уже есть в IDE.
Кое-какое описание есть внутри самой либы, которая находится в "C:\Program Files\Arduino\hardware\tools\avr\avr\include\avr\"
Вот ещё нашлось: http://inet-deal.mpa.ru/articles/arduino-003.html, http://playground.arduino.cc/Learning/ArduinoSleepCode
жека спасиб, но у меня в иде 1.5.7 нет либы авр , где ее слитьможно в архиве но, чтоб в ней была либа слип
народ, киньте пример. как загнать уно в сон (пофиг в каком режиме), чтоб она выходила из сна после снятия и последующей подачи питания. не используя прерывания, таймеры и прочее. но!!!!! чтоб скетч начинал стартовать как обычно с инклюда, а не с места засыпания.
хотя и на то в каком месте проснется тоже пофиг))) главное покажите как отключать сон)) плиз
жека спасиб, но у меня в иде 1.5.7 нет либы авр , где ее слитьможно в архиве но, чтоб в ней была либа слип
Ну не правда же... Сейчас специально скачал 1.5.7 и проверил - всё там есть.
жека, впрограм файлах в тулсе папка авр есть. но в либах нет ни авр ни слипов ни поверов
единственное упоминание о авр это- в либах не активная кнопка платы авр
жека ткни носом как добавить к скетчу либу <avr/sleep.h> не набирая ее текстом, а выбрав из списка всех либ. мож туплю уже?
жека ткни носом как добавить к скетчу либу <avr/sleep.h> не набирая ее текстом, а выбрав из списка всех либ. мож туплю уже?
Никак, в списке либ её и не должно быть. Чтобы подключить нужно именнно вручную написать #include <avr/sleep.h>
P.S. Кстати, все либы подключаются через #include. Даже те, которые есть в списке либ. Список даёт возможность лишь выбрать готовый пример кода (example), в котором #include уже прописано.
жека ткни носом как добавить к скетчу либу <avr/sleep.h> не набирая ее текстом, а выбрав из списка всех либ. мож туплю уже?
Никак, в списке либ её и не должно быть. Чтобы подключить нужно именнно вручную написать #include <avr/sleep.h>
P.S. Кстати, все либы подключаются через #include. Даже те, которые есть в списке либ. Список даёт возможность лишь выбрать готовый пример кода (example), в котором #include уже прописано.