спящий режим

crecker
Offline
Зарегистрирован: 15.12.2013

Всем привет,
хочу с помощью кнопки выводить 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()
{
...
 
}

 

axill
Offline
Зарегистрирован: 05.09.2011

Класс! Ваш ардуино проснется от нажатии кнопки и закружится, закружится... Только не в танце, а в бесконечном цикле. Нафига она такая кому то нужна?

Идея правильная, только скетч кривой. 

Тут важно как кнопка подключена, если она подключена на GND, то нужно позаботиться о подтяжке входа на плюс питания или внешним или внутренним регистром

еще полезно в даташите на МК прочитать раздел про режимы питания/сна, чтобы понимать разницу между разными режимами

crecker
Offline
Зарегистрирован: 15.12.2013
Кнопку подключил к массе, скетч изменил.  Светотодиод горит при нажатии,  только не понятно как сделать, как вводит Arduino в спящий режим с помощью кнопки, а не только выводить

#include <avr/sleep.h>
#include <avr/power.h>
 
int Switchpin = 2;
int pinled=13; 
 

 
void wakeup()              //
{
  Serial.print("Wake"); //
  detachInterrupt(0); //
  digitalWrite(13,HIGH);
 
}
 
void EnterSleep()          // 
{
 
  attachInterrupt(0, wakeup,LOW); //
  sleep_enable(); //
  sleep_mode(); //
  sleep_disable(); //
}
 
void setup()
{
  Serial.begin(9600);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); //
  pinMode(Switchpin , INPUT_PULLUP);  // 
  pinMode(13, OUTPUT);
 
}
 
void loop()
{
 Serial.print("Hello World");
 delay(5000);
 Serial.print("Sleep");
 EnterSleep(); //
}
 

 

axill
Offline
Зарегистрирован: 05.09.2011

вы для начала определитесь с задачей

если хотите, чтобы кнопка работала и во время сна и во время бодрствования, то поставьте attachInterrupt после выхода из сна и прицепите прерывание к другой функции, которая будет работать от кнопки во время бодрствования. Это первый вариант. Второй вариант - тупо считывать значения порта в loop() но нужно будет "бороться" с дребезгом контактов, иначе одно нажатие кнопки у вас вызовет несколько засыпаний и несколько просыпаний и конечный результат не гарантирован))

crecker
Offline
Зарегистрирован: 15.12.2013

первый вариант интересует.

Попробовал вот так, привязал кнопку к фунциям для входа  в сон и выхода из него. Но походу не правильно (

#include <avr/sleep.h>
#include <avr/power.h>
 
int switchpin = 2;
int pinled=13; 
 

 
void wach()              //
{
  Serial.print("wakeup"); //
  attachInterrupt(0,EnterSleep,CHANGE); //
  digitalWrite(13,HIGH);
 
}
 
void EnterSleep()          // 
{
 
  attachInterrupt(0, wakeup,LOW); 
  sleep_enable(); //
  sleep_mode(); //
  sleep_disable(); //
  digitalWrite(13,LOW);
}
 
void setup()
{
  Serial.begin(9600);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); //
  pinMode(switchpin , INPUT_PULLUP);  //
  pinMode(13, OUTPUT);
 
}
 
void loop()
{
 Serial.print("Hello World");

}

wakeup серийный порт не пишет

CityCat
CityCat аватар
Offline
Зарегистрирован: 13.06.2013

crecker пишет:

первый вариант интересует.

Попробовал вот так, привязал кнопку к фунциям для входа  в сон и выхода из него. Но походу не правильно (


#include <avr/sleep.h>
#include <avr/power.h>
 
int switchpin = 2;
int pinled=13; 
 

 
void wach()              //
{
  Serial.print("wakeup"); //
  attachInterrupt(0,EnterSleep,CHANGE); //
  digitalWrite(13,HIGH);
 
}
 
void EnterSleep()          // 
{
 
  attachInterrupt(0, wakeup,LOW); 
  sleep_enable(); //
  sleep_mode(); //
  sleep_disable(); //
  digitalWrite(13,LOW);
}
 
void setup()
{
  Serial.begin(9600);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); //
  pinMode(switchpin , INPUT_PULLUP);  //
  pinMode(13, OUTPUT);
 
}
 
void loop()
{
 Serial.print("Hello World");

}

wakeup серийный порт не пишет

Посмотрите на 20-ю строчку вашего кода и скажите, а где функция wakeup (что вы вызываете прерыванием)? Да и не понятно, где вы делаете attachInterrupt при инициализации? Вот запустили вы ардуину - какая функция после запуска будет обрабатывать нулевое прерывание на 2-й ноге? Где вы инициализировали это?

Вообще, интересная статья здесь.

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

#include <avr/sleep.h>

int wakePin = 2;                 // Пин используемый для просыпания (прерывания)
int sleepStatus = 0;             // Переменная для хранения статуса (спим, проснулись) - не используется в коде
int count = 0;                   // Счетчик
int LedPin=13;                   // Светодиод


void wakeUpNow()        // Прерывание сработает после пробуждения
{
  if (sleepStatus)               // Если мы спали,
  {
    sleep_disable();             // то первое, что нужно сделать после просыпания - выключить спящий режим
    digitalWrite(LedPin, HIGH);  // Включаем светодиод
    sleepStatus = 0;             // В переменную заносим статус бодрствования
  }
  else
    {
      Serial.println("Timer: Entering Sleep mode");
      delay(100);     // Этот делэй необходим, чтоб функция sleep не вызывала ошибку по Serial
      sleepNow();     // Вызов функции sleep() для засыпания
    }
    
  // Код, который здесь выполнится перед возвращением в цикл loop()
  // Таймеы и код, использующий таймеры (serial.print и др...) здесь не будет работать
  // Также мы не должны выполнять какие-то спец. функции здесь,
  // Т.к. здесь мы просто просыпаемся
}


void setup()
{
  pinMode(LedPin, OUTPUT);
  digitalWrite(LedPin, HIGH);                // Включаем светодиод
  pinMode(wakePin, INPUT);
  digitalWrite(wakePin, HIGH);               // Подтягивем ногу к 5.
  Serial.begin(9600);
  attachInterrupt(0, wakeUpNow, FALLING);    // Используем прерывание 0 (pin 2) для выполнения функции wakeUpNow (прерывание вызывается только при смене значения на порту с HIGH на LOW - подтянуть ногу 2 на 5в.)
}


void sleepNow()         // Функция увода ардуины в спячку.
{
  digitalWrite(LedPin, LOW);             // Выключаем светодиод
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // Здесь устанавливается режим сна
  sleep_enable();                        // Включаем sleep-бит в регистре mcucr. Теперь возможен слип 

  //attachInterrupt(0,wakeUpNow, LOW);     // Используем прерывание 0 (pin 2) для выполнения функции wakeUpNow при появлении низкого уровня на пине 2

  count = 0;                             // Обнуляем счетчик прошедших секунд
  sleepStatus = 1;                       // В переменную заносим статус сна

  sleep_mode();                          // Здесь устройство перейдет в режим сна!!!
  // -----------------------------------------------ПОСЛЕ ПРОСЫПАНИЯ ВЫПОЛНЕНИЕ КОДА ПРОДОЛЖИТСЯ ОТСЮДА!!!
                           
  //sleep_disable();                       // Первое, что нужно сделать после просыпания - выключить спящий режим
  //detachInterrupt(0);                    // Выключаем прерывание - при нормальном режиме wakeUpNow() не будет вызываться
}


void loop()
{
  // Отображаем информацию о счетчике
  Serial.print("Awake for ");
  Serial.print(count);
  Serial.println("sec");
  count++;
  delay(1000);                           // Ждем секунду


  // Проверяем - если прошло 10 секунд - засыпаем
  if (count >= 10)
  {
    Serial.println("Timer: Entering Sleep mode");
    delay(100);     // Этот делэй необходим, чтоб функция sleep не вызывала ошибку по Serial
    count = 0;
    sleepNow();     // Вызов функции sleep() для засыпания
  }
}
crecker
Offline
Зарегистрирован: 15.12.2013

Спасибо за помощь, работает  как надо. 

Только такой вопрос, есть темп.сенсор, записываю его показания на SD карту.  Командные строчки для инициализации SD карты нужно забросить в фунцкию wakeUpNow или в setup?  И то, и другое контроллер выполняет один раз.

Serial.begin(9600);  
  while (!Serial) 
  {
    ;
  }
  setSyncProvider(RTC.get);    //
 
  Serial.print("SD Initializing...");
  pinMode(10, OUTPUT);
  if (!SD.begin(10)) 
  {
    Serial.println("Feilure, SD not initialized");
    digitalWrite(A0, HIGH);
    analogWrite(3,0);   // мотор не  стартует, если инициализация не прошла
    return;
  }
  Serial.println("SD initialized.");
  analogWrite(3,pwm);  // мотор  стартует, если инициализация успещна

 

CityCat
CityCat аватар
Offline
Зарегистрирован: 13.06.2013

Ну если по коду, который я вам дал, то функция wakeUpNow выполняется каждый раз после "пробуждения".

Делайте выводы.

Chubaka
Offline
Зарегистрирован: 28.01.2014

Ребята помогите!!!

Залил код с поста #5 поправленный CityCat, ардуино ушла в сон а вывести из сна никак не могу.(((

Arduino pro micro (ATmega 32u4)

Как я понял проснутся должна от нажатия кнопки. Кнопка подключена к выводу 2 замыкание на минус. Также подключен резистор 220Ом от вывода 2 к +5В. Так должно быть?

p/s вообще по замеру тока она вроде как просыпается если удержиать кнопку в замкнутом состоянии, но ком порт не подключается.

CityCat
CityCat аватар
Offline
Зарегистрирован: 13.06.2013

Chubaka пишет:

Ребята помогите!!!

Залил код с поста #5 поправленный CityCat, ардуино ушла в сон а вывести из сна никак не могу.(((

Arduino pro micro (ATmega 32u4)

Как я понял проснутся должна от нажатия кнопки. Кнопка подключена к выводу 2 замыкание на минус. Также подключен резистор 220Ом от вывода 2 к +5В. Так должно быть?

p/s вообще по замеру тока она вроде как просыпается если удержиать кнопку в замкнутом состоянии, но ком порт не подключается.


Она не просыпается. Вы просто просаживаете питание на землю. Уберите резистор вообще или поставьте резистор побольше (килоОм на 10). В 36-й строке кода видно как нога подтягивается к плюсу программно. Зачем там еще резистор, тем более такого номинала?

crecker
Offline
Зарегистрирован: 15.12.2013
Подскадите, почему мотор останавливается, только если я функцию sleep() analogWrite(9,0 ) вставляю. Разве в режиме Power dowm таймер не выключается?


#include <avr/sleep.h>
int motorPin=9;
int Pin=8;

byte pwm=150;

void setup()
{
 Serial.begin(9600);
  

  pinMode(motorPin, OUTPUT);
  pinMode(Pin, OUTPUT);
  pinMode(3,INPUT_PULLUP);

}
void wake ()       // 
{
  sleep_disable();
  detachInterrupt(1);
  Serial.println("waking up");
  ADCSRA = _BV(ADEN);
 
}  

void loop()
{
  if(digitalRead(3)==HIGH)
  {analogWrite (9,250);
  
  }
  
 if (digitalRead(3)==LOW)
  {
    sleep();
  }
}

void sleep()              // Sleep
{
    Serial.println("going to sleep");
    delay(50);
    ADCSRA = 0;  
    set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
    sleep_enable();
    noInterrupts (); 
    analogWrite(9,0);
    attachInterrupt (1, wake, HIGH);
    MCUCR = bit (BODS) | bit (BODSE);
    MCUCR = bit (BODS); 
    interrupts ();
    sleep_cpu ();
}

 

Chubaka
Offline
Зарегистрирован: 28.01.2014

Цитата:
Она не просыпается. Вы просто просаживаете питание на землю. Уберите резистор вообще или поставьте резистор побольше (килоОм на 10). В 36-й строке кода видно как нога подтягивается к плюсу программно. Зачем там еще резистор, тем более такого номинала?

Всё равно не работает(((

Засыпает, а просыпаться не хочет. И после ресета не всегда Serial поднимается.

crecker а у Вас всё заработало по скетчу из поста #5 от CityCat. Нечего в нём не меняли?

crecker
Offline
Зарегистрирован: 15.12.2013

ничего не менял, работает все.

CityCat
CityCat аватар
Offline
Зарегистрирован: 13.06.2013

А светодиод всегда загорается/тухнет при выходе/входе в спящий режим?

crecker
Offline
Зарегистрирован: 15.12.2013

Подскажите, почему если я меняю строчку 32 из  кода в 10 ответе на вот это, то мотор не стартует при нажатии кнопки. Очень важно

 

     {  
    if ( millis ()-prev_Miliis>1000)    //
    {  
      if (x==x_alt)                        // 
      {  
        analogWrite ( 9,0);                 
        digitalWrite(A0, HIGH);   // 
        
        z=67;   
        exit(o);       


      }

      x_alt=x;                    // 
      prev_Miliis=millis();        //
      if (z<65){ 
        analogWrite(3,pwm++); Serial.println ("pwm:"); Serial.println(pwm);  // 
    }   if  (z>70) { 
      analogWrite(3,pwm--); Serial.println ("pwm:"); Serial.println(pwm); 
}

    }

  }

 

Chubaka
Offline
Зарегистрирован: 28.01.2014

CityCat пишет:
А светодиод всегда загорается/тухнет при выходе/входе в спящий режим?

В общем получается вот что:

Убрал строку 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_о

 

 

CityCat
CityCat аватар
Offline
Зарегистрирован: 13.06.2013

1. C мегой 328 работает корректно. Внимательно прочитайте код, который я приводил - в частности комментарии - для кого я писал? Там увидите и прерывание по заднему фронту на кнопке и то что прерывание нулевое, но на второй ноге (важно к пониманию для дальнейшегно рассмотрения). Здесь и далее i-й номер ноги = digital(i) pin ардуины.

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

2. Если мы посмотрим на ардуину Pro mini, то  увидим (читайте внимательнее, чтоб не приходилось обращать ваше внимание на очевидные вещи!), что пользователю доступны лишь 2 прерывания (посик на странице по слову "прерывание") - нулевое (на второй ноге) и первое (на третьей ноге).

В свою очередь, если взглянуть на описание платы arduino micro, и опять-таки поискать там слово "прерывания", то можно наблюдать, что здесь уже пользователю достыпно 4 (ЧЕТЫРЕ) прерывания: нулевое (на нулевой ноге), первое (на первой ноге), второе (на второй ноге) и третье (на третьей ноге) прерывания.

Если еще не понятно, то обратимся к описанию функции attachInterrupt() (может я не совсем популярно описал). Буквально во второй строке читаем:

Цитата:
Большинство контроллеров Arduino умеют обрабатывать до двух внешних прерываний, пронумерованных так: 0 (на цифровом порту 2) и 1 (на цифровом порту 3)

Но вот беда - наш микро - не относится к большинству (в данном контексте), посему нулевое прерывание у него на цифровой ноге ноль, а не на второй, как у про мини (или та же уно), например. А на какое прерывание мы вешаем вход и выход из спящего режима? На какой ноге?

Логика понятна? Надеюсь, что да. Оставляю для самостоятельного решения остаток проблемы.

3. Что у вас там за фантомы бродят и почему все так реагирует от внешнего источника питания - я не знаю. Возможно, вы подаете внешних 5 вольт, а не больше как рекомендовано, в том же описании - читайте внимательно. Возможно, где-то в цепи не хватает сглаживающих конденсаторов, возможно еще чего-то. Как не раз здесь говорили "гадать по кофейной гуще можно долго" (с) - не мой.

Удачи!

trembo
trembo аватар
Онлайн
Зарегистрирован: 08.04.2011

Chubaka пишет:

 Потом достаточно просто поднести палец не косаясь ноги к ноге 2 и происходит включение светодиода, начинается отсчёт, светодиод гаснет, ардуино засыпает. 0_о

Повесьте кондёр на прерывание 1-10 н

Chubaka
Offline
Зарегистрирован: 28.01.2014

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 тоже не подходит)

CityCat
CityCat аватар
Offline
Зарегистрирован: 13.06.2013

Ну, во-первых, лично я не вижу смысла в использовании 2-х МК. Разве одного не хватит?

Потом, лично я не понял - чего вы хотите и чего куда у вас подключено и при каких условиях и главное где вы собираетесь включать спящий режим? На обоих? На одной? На какой? При каких условиях? Очень мало входных данных для того, чтоб вам что-то подсказать.

Мало того, если уж так не хочется использовать нроги 0 и 1 для связи, то может слышали о замечательной библиотеке SoftwareSerial (гуглите по слову SoftwareSerial - например вот - исключительно примера ради). Опять-таки - это описано в описании платы - ну прочтите ее внимательно наконец!

P.S. Кондер по питанию повесить не лишнее, но вот на цифровую ногу я бы кондер не вешал. Личное ИМХО.

Chubaka
Offline
Зарегистрирован: 28.01.2014

CityCat пишет:

Ну, во-первых, лично я не вижу смысла в использовании 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-й МК.

CityCat
CityCat аватар
Offline
Зарегистрирован: 13.06.2013

Chubaka пишет:

Я так понимаю я могу 2-ю МК соединить с первой с помощью SoftwareSerial (не используя ноги 0 и 1 первой МК). А спящий режим прицепить на прерывание 0 1-й МК.

Правильно.

Chubaka пишет:

Скетч включения и внешнюю обвязку я уже сделал всё работает а вот при отключении всего 1-й мк потребляет около 40мА что много для автомобильного АКБ.

А светодиоды с платы пробовали отключить? :) Каждый из них "жрет" примерно 20мА :)
Chubaka
Offline
Зарегистрирован: 28.01.2014

CityCat пишет:

Chubaka пишет:

Я так понимаю я могу 2-ю МК соединить с первой с помощью SoftwareSerial (не используя ноги 0 и 1 первой МК). А спящий режим прицепить на прерывание 0 1-й МК.

Правильно.

Chubaka пишет:

Скетч включения и внешнюю обвязку я уже сделал всё работает а вот при отключении всего 1-й мк потребляет около 40мА что много для автомобильного АКБ.

А светодиоды с платы пробовали отключить? :) Каждый из них "жрет" примерно 20мА :)

Светодио только один - питание. Можно конешно попробовать но замер я делал только с скетчем питания, а как я понял чем больше будет скетч тем больше она будет потреблять.

У меня вот такая про микро и то не спарк а китайский клон))

CityCat
CityCat аватар
Offline
Зарегистрирован: 13.06.2013

Chubaka пишет:

... а как я понял чем больше будет скетч тем больше она будет потреблять...

Это где такое написано? О_о

Chubaka
Offline
Зарегистрирован: 28.01.2014

CityCat пишет:

Chubaka пишет:

... а как я понял чем больше будет скетч тем больше она будет потреблять...

Это где такое написано? О_о

Незнаю, пока изучал отложилось в голове)))

Когда пробовал Ваш скетч в спящем режиме ардуино потребляла 4,5 мА (это на ардуино про микро) и светодид питания светился, так что я не думаю что физическое отключение светодиода питания сильно снизит потребление.

CityCat
CityCat аватар
Offline
Зарегистрирован: 13.06.2013

Chubaka пишет:

Незнаю, пока изучал отложилось в голове)))

Что-то не ты вы изучали. Вообще-то есть конечно взаимосвязь того, что написано в скетче и потреблении, но не такая "прямая", как вам хотелось бы ))))

Chubaka пишет:

Когда пробовал Ваш скетч в спящем режиме ардуино потребляла 4,5 мА (это на ардуино про микро) и светодид питания светился, так что я не думаю что физическое отключение светодиода питания сильно снизит потребление.

А зря. Сильно снизит. Попробуйте отдельно светодиод запитать и измерить его потребление - скоолько вы думаете он будет потреблять? )))) Но это уж на любителя и к данной теме не относится.

Вообще, можно ж просыпаться и по приходу данных в уарт. Например вот здесь можно почитать. Это просто как вариант вам ;)

crecker
Offline
Зарегистрирован: 15.12.2013

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

 Timer1.initialize(8000000); //  
 Timer1.attachInterrupt(mesure); // 

 

из  вот этого кода, то работает как надо.  Если строчки не убираю, то программа не делает вообще ничего.

 

   #include <avr/sleep.h>
#include <TimerOne.h>
#include <LiquidCrystal_I2C.h>   // 
#include <Sensirion.h>       // 
#include <Wire.h>             
#include <DS1307RTC.h>
#include <Time.h>
#include <SD.h>

const int PWM_pin =  5;
const int Lightsensor = 2;
const int switch = 3;
const uint8_t dataPin  =  6; // 
const uint8_t clockPin =  7; // 
const int chipSelect   = 10;
static boolean Start = true;
byte pwm=200; 

float Temperature=0; //
float Humidity=0;  
float dew_point=0;   

volatile unsigned long x = 0; // 
unsigned long previousMillis = 0; 
volatile unsigned long y = 0;

Sensirion Temperatursensor = Sensirion(dataPin, clockPin);
LiquidCrystal_I2C lcd(0x20,16,2);

void setup(){
  Serial.begin(9600);
  lcd.init(); 
  lcd.backlight();
  
  pinMode(PWM_pin, OUTPUT);
  pinMode(Lightsensor, INPUT); // 
  pinMode(switch,INPUT);

  attachInterrupt(0, count, RISING);
  //attachInterrupt(1, wake, HIGH); 
 Timer1.initialize(8000000); // 
 Timer1.attachInterrupt(mesure); // 
  
}

void mesure() 
{ 
...
}
  
 void wake ()       // 
{
  sleep_disable();
  detachInterrupt(1);
  Serial.println("waking up");
  
}



void loop (){
  
  if (digitalRead(switch)==HIGH)  {    //  Включаю кнопку, мотор вращается. 
    if (Start){  // 
      y=0;
      Serial.println("Start Motor.");  // 
      analogWrite(PWM_pin,pwm);
      previousMillis = millis();          //
      
      x = 0;                              // 
      Start = false;
    }
    if (millis()-previousMillis>1000){  //  
     
      
      previousMillis = millis();         //   жду секунду, контролирую обороты
     Serial.print("RPM= ");Serial.print(x*60);Serial.println("RPM");  // 
      if ( x*60<2520) 
         { analogWrite(5,pwm++);}
       if ( x*60>2550)
          { analogWrite(5, pwm--);}
        if ( x*60==0)
        { analogWrite( 5, 0);}
      
      y+=x;
      x = 0;                                //   
  
  }
    
    
  }else {                       // кнопка выключена, ардуино спит
    Start = true;
   
   sleep();
  }  
} // end loop()

void count(){          
  x++; 
             // 
             
}


void sleep()              // 
{
    Serial.println("going to sleep");
    delay(50);
    
  
    
    set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
    sleep_enable();
    
    attachInterrupt (1, wake, HIGH);
    sleep_disable();
    detachInterrupt(1);
    
}                                                      

 

 

 

 

crecker
Offline
Зарегистрирован: 15.12.2013

Прокоментировал код, надеюсь откликов будет больще

 

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

#include <Sensirion.h>      //
#include <Wire.h>        
#include <DS1307RTC.h>
#include <Time.h>
#include <SD.h>

const int PWM_pin =  5; // мотор
const int Lightsensor = 2; // сенсор для подчсета оборотов
const int switchpin = 3;      // кнопка для активации программы
const uint8_t dataPin  =  6; // темп. сенсор
const uint8_t clockPin =  7; // темп. сенсор
const int chipSelect  = 10;  // SD карта
static boolean Start = true; //сигнал для старта
byte pwm=200;

float Temperature=0; //
float Humidity=0;
float dew_point=0;

volatile unsigned long x = 0; // для подсчета оборотов за одну петлю
unsigned long previousMillis = 0; // время
volatile unsigned long y = 0;  // для подсчета  общего количества оборотов

Sensirion Temperatursensor = Sensirion(dataPin, clockPin);


void setup(){
  Serial.begin(9600);


  pinMode(PWM_pin, OUTPUT);  // мотор на выходе
  pinMode(Lightsensor, INPUT); // датчик на входе
  pinMode(switchpin,INPUT);    // кнопка прерывание

  attachInterrupt(0, count, RISING); // прерыввание
  //attachInterrupt(1, wake, HIGH);
  Timer1.initialize(8000000); //    функция  должна вызыватся каждые 8 секунд
  Timer1.attachInterrupt(mesure); //

}

void mesure()
{

}

void wake ()      //  сон
{
  sleep_disable();
  detachInterrupt(1);
  Serial.println("waking up");

}



void loop (){

  if (digitalRead(switchpin)==HIGH)  {    //  Включаю кнопку, мотор вращается.
    if (Start){  //
      y=0;                            //  общие обороты равны нулю                          
      Serial.println("Start Motor.");  //
      analogWrite(PWM_pin,pwm);
      previousMillis = millis();          // обновление времени

      x = 0;                              //
      Start = false;                      // старт прошел
    }
    if (millis()-previousMillis>1000){  //  жду секунду, контролирую обороты


      previousMillis = millis();        //  обновляется время
      Serial.print("RPM= ");
      Serial.print(x*60);
      Serial.println("RPM");  // контроль оборотов
      if ( x*60<2520)
      {
        analogWrite(5,pwm++);
      }
      if ( x*60>2550)
      {
        analogWrite(5, pwm--);
      }
      if ( x*60==0)
      {
        analogWrite( 5, 0);
      }

      y+=x;                        // прежде чем обнулить показания датчика они сохраняются
      x = 0;                                //  обнуляю датчик

    }


  }
  else {                      // кнопка выключена, ардуино спит
    Start = true;            

    sleep();
  }
} // end loop()

void count(){          //cчитаются обороты
  x++;


}


void sleep()              //
{
  Serial.println("going to sleep");
  delay(50);



  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  //режим сна
  sleep_enable();                      // активировать сон            

  attachInterrupt (1, wake, HIGH);    // кнопка активна
  sleep_disable();                  // деактивировать сон  
  detachInterrupt(1);                //

}                                   

 

crecker
Offline
Зарегистрирован: 15.12.2013

Код работает, только при нажатии кнопки, вместо ухода в сон   прыгает между  сном и бодрствлванием, тоесть серийный порт пишет  

going to sleep
waking up
going to sleep
waking up.

 

и мотор крутится дальше, подскажите в чем ошибка.

 

CityCat
CityCat аватар
Offline
Зарегистрирован: 13.06.2013

crecker, все верно. Потому как:

sleep_enable();         // Включаем sleep-бит в регистре mcucr. Теперь возможен слип

А вот

sleep_mode();          // Здесь устройство перейдет в режим сна!!!
  //------ПОСЛЕ ПРОСЫПАНИЯ ВЫПОЛНЕНИЕ КОДА ПРОДОЛЖИТСЯ ОТСЮДА!!!

Для кого я писал комменты?

Оно просто не засыпает - оно включает и выключает бит, разрешпющий режим слип.

Где в вашем коде sleep_mode();?

crecker
Offline
Зарегистрирован: 15.12.2013

Переписал вот так, мотор крутится написано старт и больше ничего не происходит

 

#include <avr/sleep.h>

#include <TimerOne.h>

#include <Sensirion.h>       //
#include <Wire.h>             
#include <DS1307RTC.h>
#include <Time.h>
#include <SD.h>

const int PWM_pin =  5; // мотор 
const int Lightsensor = 2; // сенсор для подчсета оборотов 
const int switchpin = 3;      // кнопка для активации программы 
const uint8_t dataPin  =  6; // темп. сенсор
const uint8_t clockPin =  7; // темп. сенсор
const int chipSelect   = 10;  // SD карта
static boolean Start = true; //сиграл для старта
byte pwm=200;
int sleepStatus=0;

float Temperature=0; //  
float Humidity=0; 
float dew_point=0;   

volatile unsigned long x = 0; // для подсчета оборотов за одну петлю
unsigned long previousMillis = 0; // время 
volatile unsigned long y = 0;  // для подсчета  общего количества оборотов 

Sensirion Temperatursensor = Sensirion(dataPin, clockPin);


void setup(){
  Serial.begin(9600);


  pinMode(PWM_pin, OUTPUT);  // мотор на выходе
  pinMode(Lightsensor, INPUT); // датчик на входе 
  pinMode(switchpin,INPUT);     // кнопка прерывание 

  attachInterrupt(0, count, RISING); // прерыввание 
  attachInterrupt(1, wake, FALLING);
  Timer1.initialize(8000000); //    функция  должна вызыватся каждые 8 секунд 
  Timer1.attachInterrupt(function); //

}

void function()
{
 Serial.print("Hello");
}

void wake ()       // проснулся
{
 if (sleepStatus)
 { 
   sleep_disable();
   
  Serial.println("waking up");
  sleepStatus=0;
 }
 else
  { Serial.println ("Timer: Entering Sleep mode");
    delay(100);
    sleep();

}

}

void loop (){

  if (digitalRead(switchpin)==HIGH)  {    //  Включаю кнопку, мотор вращается.
    if (Start){  //
      y=0;                             //  общие обороты равны нулю                              
      Serial.println("Start Motor.");  //
      analogWrite(PWM_pin,pwm);
      previousMillis = millis();          // обновление времени 

      x = 0;                              //  
      Start = false;                      // старт прошел  
    }
    if (millis()-previousMillis>1000){  //  жду секунду, контролирую обороты


      previousMillis = millis();         //   обновляется время
      Serial.print("RPM= ");
      Serial.print(x*60);
      Serial.println("RPM");  // контроль оборотов
      if ( x*60<2520)
      { 
        analogWrite(5,pwm++);
      }
      if ( x*60>2550)
      { 
        analogWrite(5, pwm--);
      }
      if ( x*60==0)
      { 
        analogWrite( 5, 0);
      }

      y+=x;                         // прежде чем обнулить показания датчика они сохраняются     
      x = 0;                                //   обнуляю датчик 

    }


  }
  else {                       // кнопка выключена, ардуино спит
    Start = true;                

    sleep();
  } 
} // end loop()

void count(){           //cчитаются прерывания
  x++;


}


void sleep()              // сон
{
  
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
//attachInterrupt(0,wake, LOW);
sleepStatus=1;
sleep_mode();
  
               

}                                                

 

crecker
Offline
Зарегистрирован: 15.12.2013

Использую вот этот выключатель,  подключение 5 вольт и пин 3.

 

 

CityCat
CityCat аватар
Offline
Зарегистрирован: 13.06.2013

А что должно происходить? Вы на самом деле считаете нас телепатами и мы должны догадываться о ваших действиях? По вашему коду и должно при подключении питания писать "Hello" (каждые 8 сек.) и если включен этот, с позволения сказать "выключатель" - "Start Motor.". Что еще вам нужно? Мы гадать должны?

Про объявления - вообще интересно: читать здесь внимательно - в основном про подтяжку (подсказывать не буду - думайте сами где и почему у вас что не так с подтяжкой)

Далее - зачем вообще вот эти строки (они когда-нибудь будут выполнены? Когда?)?

109  else {                       // кнопка выключена, ардуино спит
110  Start = true;               
111  
112  sleep();
113  }

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

Внимательно изучите свой код. Поймите смысл строки:

attachInterrupt(1, wake, FALLING);

Соответственно, должно прийти понятие что не так и почему.

Еще раз прочитайте описание функции attachInterrupt. Вы уверены, что у вас правильно инициализировано прерывание? Может в вашем случае нужно не FALLING а что-то иное? 

P.S. Все о чем я писал касается спящего режима, его включения и выключения. Про ваш код отдельная история, но не в этой теме (то есть я не рассматривал и не искал ошибки в нем - он мне неинтересен).

crecker
Offline
Зарегистрирован: 15.12.2013

ок, задумка была такая. После загрузки кода  ардуино  сначала спит,  тоесть ничего не делает и потребляет минимум электроэнергии. При нажатии кнопки, программа начинает работу: делает инициализацию, вращает мотор и переодически меряет температуру и запивывает на SD карту. 

При  смене положения кнопки программа прерывается и  ардуино уходит в спящий режим до последующего нажатия кнопки.

Почему то мотор не выключается, ведь при переходе в режим 

set_sleep_mode (SLEEP_MODE_PWR_DOWN);

должны выключатся все таймеры, отвечающие за шим.

Строчки

  else {                       // кнопка выключена, ардуино спит
	110  Start = true;              
	111 
	112  sleep();
	113  }

работают, если sleep()  заменить на 

analogWrite (5, 0);

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

CityCat
CityCat аватар
Offline
Зарегистрирован: 13.06.2013

Ну, во-первых, переход в режим сна осуществляется вот этой строкой (сколько можно говорить уже):

sleep_mode();          // Здесь устройство перейдет в режим сна!!!

а не этой:

set_sleep_mode (SLEEP_MODE_PWR_DOWN);

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

Ну и в-третьих, при смене сигнала с 1 в 0 (задний фронт) на пине, на котором вы повесили прерывание (читай - при выключении кнопки) собственно и сработает функция, которая вызывается прерыванием, а она уведет ардуину в спящий режим, посему все что после else (строки 109-113 вашего кода) обрабатывать будет некому - ардуина спит. Но это было бы... Если б вы подтянули ногу к земле, т.к. при отключении от нее 5в., неизвестно что на ней будет - собственно писал вам про подтяжку. Когда же вы включите свою кнопку, на ноге будет лог.1, следовательно то, что под else тоже не будет обрабатываться. Внимание вопрос (повторяю тоже второй раз): зачем вообще вот эти строки (они когда-нибудь будут выполнены? Когда?)?

Вам сложно почитать? Нужно разжевать?

P.S. Зачем вам такие сложности? Включате кнопкой питание ардуины - все работает. Выключаете - все останавливается. В чем проблема-то?

crecker
Offline
Зарегистрирован: 15.12.2013

Ну так у ардуино есть 6 спящих режимов

set_sleep_mode (SLEEP_MODE_PWR_DOWN);

надо же указать какой именно  режим должен вызываться или не правильно.

 

 

CityCat
CityCat аватар
Offline
Зарегистрирован: 13.06.2013

crecker пишет:

Ну так у ардуино есть 6 спящих режимов

set_sleep_mode (SLEEP_MODE_PWR_DOWN);

надо же указать какой именно  режим должен вызываться или не правильно.

Всегда думал что их 5:

Цитата:

The 5 different modes are:
* SLEEP_MODE_IDLE         -the least power savings
SLEEP_MODE_ADC
SLEEP_MODE_PWR_SAVE
SLEEP_MODE_STANDBY
SLEEP_MODE_PWR_DOWN     -the most power savings
Но принцип верный - выбираем режим и включаем.
Причем, при последнем режиме вывести из сна ардуину можно только одним из прерываний на пинах 2 или 3 и срабатыванием таймера по watchdog.
Все верно, но проблема ваша в том, что похоже ардуина и не засыпает.
Поправьте код до рабочего состояния, а потом разбирайтесь с вашим серво.
Chubaka
Offline
Зарегистрирован: 28.01.2014

С засыпанием просыпанием всё заработало как часики))) Спасибо большое CityCat.

Вот только есть одно НО....

Какая то проблема с USB. При первой подачи питания, если не уводить ардуину в сон USB (COM порт) работает как пологается. А вот после просыпания никак не хочет. При чём это не зависимо от кода который у меня использует Serial, пробовал и без него всё равно такой же результат.

Возможно как то корректно деактивировать перед уходом в сон и активировать после просыпания COM порт кроме Serial.end(), Serial.begin().?

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

int ACCPin = 2;                 // Пин используемый для просыпания (прерывания), включения, отключения питания хаба и планшета
int sleepStatus = 0;             // Переменная для хранения статуса (спим, проснулись) - не используется в коде

#define relePinHUB 8 // питание HUB
#define relePinTablet 7 // питание +5 в ОТГ планшета, управление аудиоусилителя, управление усилителя радиоантены   	
#define ONHUB 500 // время включения реле HUB
#define ONTablet 5000 // время включения планшета   
#define OFFHUB 30000 // время выключения реле HUB
#define OFFTablet 3000 // время выключения планшета

unsigned long duration, millisold, off = 0;
boolean stateACC, relestate1, relestate2 = 0;

int buttonPin=6; //пин для резистивных кнопок
int data;
int flag=0;
long previousMillis = 0; 
int val=0;

void wakeUpNow()                 // Прерывание сработает после пробуждения
{
  if (sleepStatus)               // Если мы спали,
  {
    sleep_disable();             // то первое, что нужно сделать после просыпания - выключить спящий режим
    sleepStatus = 0;             // В переменную заносим статус бодрствования
    detachInterrupt(1);          // Выключаем прерывание - при нормальном режиме wakeUpNow() не будет вызываться 
  }
   
  // Код, который здесь выполнится перед возвращением в цикл loop()
  // Таймеы и код, использующий таймеры (serial.print и др...) здесь не будет работать
  // Также мы не должны выполнять какие-то спец. функции здесь,
  // Т.к. здесь мы просто просыпаемся
}


void setup()
{
  pinMode(ACCPin, INPUT);
  attachInterrupt(1, wakeUpNow, FALLING);    // Используем прерывание 1 (pin 2) для выполнения функции wakeUpNow
  pinMode(relePinHUB, OUTPUT); 
  pinMode(relePinTablet, OUTPUT);
  Keyboard.begin();
  Serial.begin(9600);
}

void sleepNow()                          // Функция увода ардуины в спячку.
{
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // Здесь устанавливается режим сна
  sleep_enable();                        // Включаем sleep-бит в регистре mcucr. Теперь возможен слип 
  
  attachInterrupt(1, wakeUpNow, FALLING);   // Используем прерывание 1 (pin 2) для выполнения функции wakeUpNow при появлении низкого уровня на пине 2
  
  sleepStatus = 1;                       // В переменную заносим статус сна
  sleep_mode();                          // Здесь устройство перейдет в режим сна!!!
  //-------------------------ПОСЛЕ ПРОСЫПАНИЯ ВЫПОЛНЕНИЕ КОДА ПРОДОЛЖИТСЯ ОТСЮДА!!!--------------------------//
}

void loop()
{
  Power();
  Knopki();
  delay(10);
}
 void Power()
 {
  if (!digitalRead(ACCPin)&&stateACC) {
    stateACC=0;
    duration = millis();
    }
  if (digitalRead(ACCPin)&&!stateACC) {
    stateACC=1;
    off = millis();
    }
  if(!digitalRead(ACCPin) && !stateACC && millis ()-duration > ONHUB){
    digitalWrite(relePinHUB, HIGH);
    relestate1 = 1;
    millisold = millis();
    }
  if(!digitalRead(ACCPin) && !stateACC &&  millis ()-duration > ONTablet){
    digitalWrite(relePinTablet, HIGH);
    relestate2 = 1;
    millisold = millis();
    }
  if(digitalRead(ACCPin) && stateACC && millis () -off> OFFHUB){
    digitalWrite(relePinHUB, LOW);
    relestate1 = 0;
    millisold = millis();
    delay (2000);
    sleepNow(); 
    } 
  if(digitalRead(ACCPin) && stateACC &&  millis ()-off > OFFTablet){
    digitalWrite(relePinTablet, LOW);
    relestate2 = 0;
    millisold = millis();     
    } 
}

void Knopki()
{
 data=analogRead(buttonPin); //читаем значение нажатой кнопки
 Serial.println(data); //для определения кодов нажатых кнопок на мониторе порта
 
  if (data<=900) //если нажата любая из кнопок начинается отсчёт
  { 
    if (millis() -previousMillis >200)    
    { 
      previousMillis = millis();     
      val++; 

//кнопка громкости +
      if (data>=210 && data<=232 && flag==0 && val==1)  //одиночное нажатие
      {
      Remote.increase(); //прибавить громкость на ед.
      Remote.clear();
      flag=1;
      val=0;
      }
      if (data>=210 && data<=232 && val>=2)  // удержание
      {
      Remote.increase(); //прибавлять громкость до отпускания
      Remote.clear();
      val=0;
      }

//кнопка громкости -
      if (data>=460 && data<=488 && flag==0 && val>=1 && val<=3)  //одиночное нажатие
      {
      Remote.decrease(); //убавить громкость на ед.
      Remote.clear();
      flag=1;
      val=0;
      }
      if (data>=460 && data<=488 && val>=4)  //удержание
      {
      Remote.decrease(); //убавлять громкость до отпускания
      Remote.clear();
      val=0;
      }

//кнопка следующий трек
      if (data==0 && flag==0 && val==1)  //одиночное нажатие
      {
      Remote.next(); //следующий трек
      Remote.clear();
      flag=1;
      val=0;
      }
      if (data==0 && val>=2)  //удержание
      {
      Remote.forward(); //перемотка вперёд
      Remote.clear();
      val=0;
      }
  
//кнопка предидущий трек
      if (data>=76 && data<=92 && flag==0 && val>=1 && val<=5)  //одиночное нажатие
      {
      Remote.previous(); //предидущий трек
      Remote.clear();
      flag=1;
      val=0;
      }
      if (data>=76 && data<=92 && val>=6)  //удержание
      {
      Remote.rewind(); //перемотка назад
      Remote.clear();
      val=0;
      }
    
//кнопка приглушения звука
      if (data>=565 && data<=594 && flag==0)  //нажата кнопка
      {
      Remote.mute();
      Remote.clear();
      flag=1;
      val=0;
      }
    }
  } 
//не нажата не одна из кнопок
   if (data>=950 && data<=960 && flag==1)
  {
   flag=0;
  }
}

 

BeeLove
Offline
Зарегистрирован: 17.06.2014

Chubaka пишет:

Какая то проблема с USB. При первой подачи питания, если не уводить ардуину в сон USB (COM порт) работает как пологается. А вот после просыпания никак не хочет. При чём это не зависимо от кода который у меня использует Serial, пробовал и без него всё равно такой же результат.

 

В этом вопросе вам может помочь изучение разных режимов сна. http://avr.ru/beginer/understand/sleep_mode

std
Offline
Зарегистрирован: 05.01.2012

Для меня detachInterrupt() так и осталась непонятной, поэтому у меня однократно в setup() ставится прерывание и всё. И если оно вдруг случилось во включенном состоянии - смотрим флаг "включаемся" - если true, подождать пару сек и если со входа кнопки всё ещё ноль (т. о. кнопа жмётся) - продолжать заводить, иначе спать. А если флаг false - то значит однозначно проснулись, если истекло более 5 сек, значит спать. Это позволяет по кнопке проснуться не сразу а её надо жать долго (2 с), а по повторному нажатию засыпать (если прошло не менее 5 с). В примере прога для фонарика с восемью выходами для светодиодов, там регулируется больше/меньше и умеет спать.

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

volatile boolean onflag=false,     // going on state
                 onflagdone=false;     // on state
int              seconds=0;
byte             lev=0;
unsigned long    last_on=millis(),
                 last_key=millis();

void waking(void){
  onflag=true;
}

void sleeping(void){
  onflag=false;
  onflagdone=false;
  seconds=0;
  lev=0;
  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
  digitalWrite(7,LOW);
  digitalWrite(8,LOW);
  digitalWrite(9,LOW);
  digitalWrite(10,LOW);
  digitalWrite(11,LOW);
  digitalWrite(12,LOW);
  delay(100);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();
  sleep_disable(); 
}

void setup(){
  pinMode(5,OUTPUT);       // outs
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(4,INPUT);        // unused
  pinMode(13,INPUT);
  pinMode(3,INPUT_PULLUP); // on
  pinMode(2,INPUT_PULLUP); // <
  pinMode(1,INPUT_PULLUP); // >
  pinMode(0,INPUT_PULLUP); // max
  attachInterrupt(1,waking,LOW);
  sleeping();
}

void loop(){
  if(onflag){
    if(millis()-last_on>=1000){
      seconds++;
      last_on=millis();
    }
    if(!onflagdone){
      delay(2000);
      if(digitalRead(3)==LOW) onflagdone=true;
      else sleeping();
    }else{
      digitalWrite(5,HIGH);
      if(lev>0) digitalWrite(6,HIGH);
       else digitalWrite(6,LOW);
      if(lev>1) digitalWrite(7,HIGH);
       else digitalWrite(7,LOW);
      if(lev>2) digitalWrite(8,HIGH);
       else digitalWrite(8,LOW);
      if(lev>3) digitalWrite(9,HIGH);
       else digitalWrite(9,LOW);
      if(lev>4) digitalWrite(10,HIGH);
       else digitalWrite(10,LOW);
      if(lev>5) digitalWrite(11,HIGH);
       else digitalWrite(11,LOW);
      if(lev>6) digitalWrite(12,HIGH);
       else digitalWrite(12,LOW);
      if(digitalRead(3)==LOW && seconds>=5){
        digitalWrite(5,LOW);
        delay(500);
        sleeping();
      }
      if(digitalRead(2)==LOW && millis()-last_key>=300){
        if(lev>0) lev-=1;
        last_key=millis();
      }
      if(digitalRead(1)==LOW && millis()-last_key>=300){
        if(lev<7) lev+=1;
        last_key=millis();
      }
      if(digitalRead(0)==LOW && millis()-last_key>=300){
        if(lev!=1) lev=1;
         else lev=7;
        last_key=millis();
      }
    }
  }
}
Pnewmoslon
Offline
Зарегистрирован: 26.07.2014

всем привет. киньте плиз ссыль на либс <avr/sleep.h> и на ее описание

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

Какую ссыль? Эта либа уже есть в IDE.

Кое-какое описание есть внутри самой либы, которая находится в "C:\Program Files\Arduino\hardware\tools\avr\avr\include\avr\"

Вот ещё нашлось: http://inet-deal.mpa.ru/articles/arduino-003.htmlhttp://playground.arduino.cc/Learning/ArduinoSleepCode

 

Pnewmoslon
Offline
Зарегистрирован: 26.07.2014

жека спасиб, но у меня в иде  1.5.7 нет либы авр , где ее слитьможно в архиве но, чтоб в ней была либа слип

Pnewmoslon
Offline
Зарегистрирован: 26.07.2014

народ, киньте пример. как загнать уно в сон (пофиг в каком режиме), чтоб она выходила из сна после снятия и последующей подачи питания. не используя прерывания, таймеры и прочее. но!!!!! чтоб скетч начинал стартовать как обычно с инклюда, а не с места засыпания.

Pnewmoslon
Offline
Зарегистрирован: 26.07.2014

хотя и на то в каком месте проснется тоже пофиг))) главное покажите как отключать сон)) плиз

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

Pnewmoslon пишет:

жека спасиб, но у меня в иде  1.5.7 нет либы авр , где ее слитьможно в архиве но, чтоб в ней была либа слип

Ну не правда же... Сейчас специально скачал 1.5.7 и проверил - всё там есть.

Pnewmoslon
Offline
Зарегистрирован: 26.07.2014

жека, впрограм файлах в тулсе папка авр есть. но в либах нет ни авр ни слипов ни поверов

Pnewmoslon
Offline
Зарегистрирован: 26.07.2014

единственное упоминание о авр это- в либах не активная кнопка платы авр

Pnewmoslon
Offline
Зарегистрирован: 26.07.2014

 жека ткни носом как добавить к скетчу либу <avr/sleep.h> не набирая ее текстом, а выбрав из списка всех либ. мож туплю уже?

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

Pnewmoslon пишет:

 жека ткни носом как добавить к скетчу либу <avr/sleep.h> не набирая ее текстом, а выбрав из списка всех либ. мож туплю уже?

Никак, в списке либ её и не должно быть. Чтобы подключить нужно именнно вручную написать #include <avr/sleep.h>

P.S. Кстати, все либы подключаются через #include. Даже те, которые есть в списке либ. Список даёт возможность лишь выбрать готовый пример кода (example), в котором #include уже прописано.

Pnewmoslon
Offline
Зарегистрирован: 26.07.2014

Jeka_M пишет:

Pnewmoslon пишет:

 жека ткни носом как добавить к скетчу либу <avr/sleep.h> не набирая ее текстом, а выбрав из списка всех либ. мож туплю уже?

Никак, в списке либ её и не должно быть. Чтобы подключить нужно именнно вручную написать #include <avr/sleep.h>

P.S. Кстати, все либы подключаются через #include. Даже те, которые есть в списке либ. Список даёт возможность лишь выбрать готовый пример кода (example), в котором #include уже прописано.

понял спасибо. вот так мы и расширяем свой кругозор и познания