Пишу программу на мегу 2560, для авто. Очень нужен спящий режим, с выходом из него по прерыванию.
Скетч из поста #5 заливал и модифицировал безчисленное количество раз. Результат всегда один - мега легко входит в спячку по прерыванию, но никогда из неё не выходит. В борьбе с даташитом победил даташит, я лиш понял что вроде бы нужно использовать прирывание INT7, коего ненашел.
По ее мотивам переписал код для вас. Проверить не на чем пока, должно работать:
#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() для засыпания
}
}
Почему при нажатии кнопки (wakePin = 2;) во время бодорствования Arduino UNO зависает?
Чуть переделанный мною код для пробуждения не только по кнопке, но и по WDT.
Вроде работает (в рабочем режиме кушает 8,6 мА, в спящем - 2,28 мА), но гляньте, вдруг есть что оптимизировать. В частности, по нажатию кнопки "Welcome" иногда выводится два раза подряд.
// Просыпаемся по таймеру раз в 8 сек, либо по кнопке, делаем 10 вспышем и снова спим.
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
#define BUTTON 3 // Пин используемый для пробуждения (использует прерывание 1)
int count; // Счетчик
// watchdog interrupt
ISR (WDT_vect)
{
wdt_disable(); // disable watchdog
} // end of WDT_vect
void setup()
{
config(); // настраиваем входы/выходы
attachInterrupt(1, wakeUpNow, FALLING); // Используем прерывание 1 (pin 3) для выполнения функции wakeUpNow (FALLING - прерывание вызывается только при смене значения на порту с HIGH на LOW)
Serial.begin(9600);
delay(5000); // на всякий случай, если войдет в бесконечный цикл, можно будет перепрошить
Serial.println("Start!");
}
void loop()
{
// Отображаем информацию о счетчике
Serial.print(count);
Serial.print(", ");
count++;
//delay(1000); // Ждем секунду
digitalWrite(LED_BUILTIN, HIGH);
delay(50);
digitalWrite(LED_BUILTIN, LOW);
delay(50);
// Проверяем - если прошло 10 миганий - засыпаем
if (count >= 10)
{
Serial.println("\nEntering Sleep mode");
delay(100); // Этот делэй необходим, чтоб функция sleep не вызывала ошибку по Serial
count = 0; // Обнуляем счетчик вспышек
sleepNow(); // Вызов функции sleep() для засыпания
}
}
void sleepNow() // Функция увода ардуины в спячку
{
digitalWrite(LED_BUILTIN, LOW); // Выключаем светодиод
/*
for (byte i = 0; i <= A5; i++) // переводим пины в режим выхода (закомментировано, т.к. виснет после засыпания)
{
pinMode (i, OUTPUT); // changed as per below
digitalWrite (i, LOW); // ditto
}
*/
ACSR |= (1 << ACD); // отключаем Аналоговый компаратор
ADCSRA = 0; // отключаем Аналоговый компаратор (такой код в других скетчах)
power_all_disable(); // отключаем все внутренние блоки ЦП. (требуется <avr/power.h> + эта строчка должн быть после ADCSRA=0)
// power_adc_disable(); // ADC converter
// power_spi_disable(); // SPI
// power_usart0_disable();// Serial (USART)
// power_timer0_disable();// Timer 0
// power_timer1_disable();// Timer 1
// power_timer2_disable();// Timer 2
// power_twi_disable(); // TWI (I2C)
// отключаем BOD
noInterrupts (); // cli(); // отключение прерываний
uint8_t x = (MCUCR & ~(1 << BODSE)) | (1 << BODS); // подготовка бит
MCUCR = x | (1 << BODSE); // процедура отключения BOD
MCUCR = x;
interrupts (); //sei(); // включение прерываний
// конец отключения BOD
// подготовка WatchDog
MCUSR = 0; // clear various "reset" flags
WDTCSR = bit (WDCE) | bit (WDE); // allow changes, disable reset
// set interrupt mode and an interval
WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE, and 8 seconds delay
//WDTCSR = bit (WDIE) | bit (WDP2) | bit (WDP1); // set WDIE, and 1 second delay
wdt_reset(); // pat the dog
// конец подготовки WatchDog
attachInterrupt(1,wakeUpNow, FALLING); // назначаем прерывание 1 (pin 3) для выполнения функции wakeUpNow при нажатии кнопки
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // устанавливается режим сна (это не вход в сон! Только установка режима!)
sleep_enable(); // включаем sleep-бит в регистре mcucr. Теперь возможен сон
sleep_mode(); //sleep_cpu(); // Здесь устройство перейдет в режим сна. Внешние прерывания и WDT продолжают работать.
// -----------------------------------------------ПОСЛЕ ПРОСЫПАНИЯ ВЫПОЛНЕНИЕ КОДА ПРОДОЛЖИТСЯ ОТСЮДА!!!
wakeUpNow();
}
void wakeUpNow() // Пробуждение по внешнему прерыванию
{
// Код, который здесь, выполнится перед возвращением в цикл loop()
// Таймеы и код, использующий таймеры (serial.print и др...) здесь не будут работать
// Также мы не должны выполнять какие-то спец. функции, здесь мы просто просыпаемся
sleep_disable(); // отключаем спящий режим
power_all_enable(); // включаем все внутренние блоки ЦП
// power_adc_enable(); // ADC converter
// power_spi_enable(); // SPI
// power_usart0_enable(); // Serial (USART)
// power_timer0_enable(); // Timer 0
// power_timer1_enable(); // Timer 1
// power_timer2_enable(); // Timer 2
// power_twi_enable(); // TWI (I2C)
wdt_disable(); // нужно ли здесь это?
config(); // настраиваем входы/выходы
detachInterrupt(1); // Выключаем прерывание - при нормальном режиме wakeUpNow() не будет вызываться
}
void config() // Настраиваем входы/выходы
{
pinMode(LED_BUILTIN, OUTPUT);
pinMode(BUTTON, INPUT_PULLUP);
Serial.println("Welcome!");
}
/*
у ардуино есть 5 спящих режимов:
* 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.
на момент ухода в сон все ноги мк включая не использованные должны быть в одном из состояний:
- настроены на выход
- настроены на вход и включена внешняя подтяжка
- настроены на вход и присоеденена внешняя подтяжка
- настроены на вход и закорочены на GND - это вариант длянеиспользованных пинов, но можно и с внутренней подтяжкой
еще важно определиться с тем нужно ли просыпаться от таймеров. Таймеры много жрут
ждет ацп
жрет watch dog (0,1 мА)
жрет детектор напряжения, который фьюзами включается
*/
Можно корректный пример перевода, просыпания ардуины в спящий режим. Все что сдесь есть работает некорректно. Либо намертво засыпает, либо работает через раз и засыпает намертво(((
Доброго времени суток. Подскажите, как на Ардуино нано(Atmega328p) сделать следующее: уходить в сон по нажатию кнопки и просыпаться по нажатию той же кнопки(подключенной к D2) и по таймеру, если в ходе обработки прерывания от таймера выполнилось условие равенства между моими константами и данными прочитанными по SPI, то необходимо выйти из сна и запретив прервания перейти к выполнению основной программы.
* Потребление на частоте 1 МГц + sleep + выходы в LOW: 4,59 мА 3,03 мА
*/
Почему так много? А потому что используется Arduino IDE. Оказывается, при использовании конструкции setup и loop подгружается масса ардуиновских библиотек. Они включают таймеры, ацп, и прочее, и никто не считал сколько всего меняется. Если использовать чистый Си, то можно снизить до микроампер.
А каким образом можно реализовать не спящий режим а отключение питания (почти полностю), принцип как в электронных устройствах, плеерах, мобилках, чтоб при нажатии допустим 5с включался аппарат и при таком же нажатии вырубался???
а с чего ты взял, что они полностью выключаются? Там скорее всего такой же сон, с микроамперным потреблением.
Но если очень надо, то можно и полное отрубание.
Вот схема на реле:
Можно и средствами Arduino - кнопкой напрямую подаем питание на Vcc, Arduino включается, в setup прописываем - сразу же после включения: подать на пин X сигнал, который через транзистор скоммутирует питание (параллельно кнопке), после этого кнопку можно отпускать. Недостаток тут есть - надо чуть подержать кнопку (0,5-2 сек), чтобы Arduino успел загрузиться.
Посоветуйте пожалуйста как лучше сделать. Нужно сделать чтоб ардуина просыпалась по внешнему сигналу, и по времени. С внешним сигналом я разобрался, а вот с таймером возникли вопросы. Во всех примерах пробуждения во Watсhdog-у используются корткие интервалы (от миллисекунд до десятков секунд), мне же нужны интервалы поболее (1ч. 2ч. 4ч. 8ч. и 16ч.). Всвязи с этим встаёт резонный вопрос, можно ли настроить сторожевой таймер на такие интервалы, и если да, то будет ли это правильно. Или рациональней будет использовать часы реального времени?
сторожевой таймер имеет максимальный интервал 8 сек.
Но никто тебе не мешает завести переменную, куда каждые 8 сек записывать приращение на единичку.
Как только значение переменной превысит 450/900/1800/3600,значит пора просыпаться ;)
сторожевой таймер имеет максимальный интервал 8 сек.
важно понимать, что 8сек относятся именно к atmega328, у других МК надо даташит смотреть, может быть меньше
здесь дело такое. просыпаться по времени можно от обычного таймера, но обычный таймер требует использования менее экономного режима сна, т.е. если пробуждаться от обычного таймера потребление во время сна будет в разы больше
watchdog изначально придуман для другого поэтому не расчитан на длительное время между прерываниями, но его фишка как раз в том что для его работы требуется меньше энергии
НО. если RTC уже есть и они уже жрут свои микроватты энергии, то просыпание по RTC позволит сэкономить еще чуточку, ибо хоть watchdog есть мало, но все равно ест. Если его отключить то можно довести потребление во сне до почти абсолютного минимума, особенно если еще все остальное отключить (в частности детектор низкого напряжения)
RTC нету, но скорее всего придётся ставить. Так как нужно определять время сработки датчика. Я на каком то форуме, недели 2 назад читал что у часов можно запрограммировать какой то выход, чтоб на нём раз в час менялся лог. уровень. Буду весьма признателен если кто нибудь подскажет как, и где можно посмотреть пример использования RTC для этих целей. Облазил пол инета и ни где ни чего вразумительного не нашёл...
PCF8563, это RTC с таймером. Таймер весьма гибок (256 отсчетов от ~2мкс до 1 мин на отсчёт), выход таймера настраивается (изм. лог. уровня / импульс), низкое потребление (~500 nA). Подробности в техдоке.
Вопрос такой: вот кнопками или по таймеру - это понятно более-менее. А вот такая задача: имеем устройство на ардуине которое транслирует с использованием модуля RX 433 последовательности символов - в течение часа - "а", второго часа - "b", третьего - "с" и т.п. Второе устройство, с ресивером, находится в зоне приема в спящем режиме. Можно ли сделать так, чтобы оно просыпалось во время трансляции определенного символа и засыпало по окончании трансляции или выходе устройства-приемника из зоны сигнала (либо отключении передатчика)
Код подкорректировал по своему разумению, получилось так:
#include <avr/wdt.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#define WDTO_INFINITE 255
#define SLEEP_PERIOD WDTO_8S
#define SKIP_WDT_WAKEUPS 14 // x SLEEP_PERIOD + SLEEP_PERIOD (14 ~= 120 sec)
#define LIGHT_PIN 3
volatile bool light_pcint = false;
volatile byte wakeup_counter = 0;
// Вектор (функция) прерывания PCINT, у ATtiny85 один порт (B), следовательно только один вектор PCINT
ISR(PCINT0_vect)
{
light_pcint = true;
}
// Вектор прерывания таймера WDT
ISR(WDT_vect)
{
wakeup_counter++;
}
void sleep()
{
GIMSK = _BV(PCIE); // Включить Pin Change прерывания
// if (SLEEP_PERIOD == WDTO_INFINITE || payload.light != LIGHT_FUZZY)
PCMSK |= _BV(LIGHT_PIN); // PCINT3; включить если нет проблем с освещением или иначе нет шансов проснуться
ADCSRA &= ~_BV(ADEN); // отключить ADC; уменьшает энергопотребление
if (SLEEP_PERIOD != WDTO_INFINITE) {
wdt_enable(SLEEP_PERIOD); // установить таймер
WDTCR |= _BV(WDIE); // включить прерывания от таймера; фикс для ATtiny85
}
// Установить режим сна Power-down; MCUSR &= ~_BV(SM0); MCUSR |= _BV(SM1);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable(); // разрешить режим сна; MCUSR |= _BV(SE);
sei(); // включить прерывания
sleep_cpu(); // заснуть
cli(); // отключить прерывания; для безопасного отключения PCINT3
PCMSK &= ~_BV(LIGHT_PIN); // PCINT3; отключить
sleep_disable(); // запретить режим сна; MCUSR &= ~_BV(SE);
ADCSRA |= _BV(ADEN); // включить ADC
sei(); // включить прерывания; иначе таймеры не будут работать
}
void setup() {
// put your setup code here, to run once:
pinMode(1, OUTPUT); //LED on Model B
pinMode(0, INPUT);
pinMode(1, INPUT);
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);
pinMode(5, INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(1, HIGH); // turn the LED on (HIGH is the voltage level)
delay(5000); // wait for a 5 second
digitalWrite(1, LOW); // turn the LED off by making the voltage LOW
sleep();
}
С этим скетчем Digispark выходит из спящего режима по Watchdog или по высокому уровню на третьем пине.
Ток, потребляемый платой в режиме SLEEP_MODE_PWR_DOWN - 7 мкА (семь микроампер).
То есть тысячу миллиампер-часов энергии плата съест в этом режиме за 16 лет.
Продолжил эксперименты со спящим режимом в Digispark. У меня в нём навернулся загрузчик (сам не понял, почему). Я восстановил его, подробнее здесь. Теперь с загрузчиком micronucleus-1.06.hex минимальный ток составляет 28 мкА (что тоже неплохо).
Кстати, как я понял, для экономного спящего режима нужно отправить (digitalWrite) перед засыпанием на использовавшиеся пины уровень LOW.
Вернул энергопотребление Digispark на уровень 7 мкА. Для этого прошил загрузчик micronucleus-1.06.hex (см. ссылку на моё описание этого процесса в предыдущем посте), но с другими значениями fuses. Фрагмент моего файла boards.txt:
Здесь отключены детекторы низкого напряжения питания.
Как оказалось, включение "Brown-out Detector trigger level" на уровень 2.7 В (BODLEVEL1) увеличивало энергопотребление в SLEEP_MODE_PWR_DOWN режиме с 7 до 28 мкА.
7мка для голой атмеги многовато. У меня беспроводной сенсор, состоящий из МК, трех I2C датчиков, передатчика NRF24L01 и DC-DC преобразователя, в периоды, когда все это хозяйство включено, но "спит", потребляет 4.5мка.
7мка для голой атмеги многовато. У меня беспроводной сенсор, состоящий из МК, трех I2C датчиков, передатчика NRF24L01 и DC-DC преобразователя, в периоды, когда все это хозяйство включено, но "спит", потребляет 4.5мка.
можете пример привести что и как использовали?
У меня менее пары милиампер чтото не получалось на 328, хотя паял только проц на отдельной плате.
Моя Ардуина, с которой я так долго воевал, сейчас потребляет в спящем режиме 0,7 мкА. Добился такого так:
Вместо WatchDog-а использую часы реального времени, пробуждение происходит по прерыванию которое генерится часами (будильником).
В Атмеге при уходе в сон, отключается всё что может отключаться.
На плате Ардуино про мини, отпаял практически всю обвязку контроллера (светодиоды, стабилизатор на 3,3v, оставил только саму Атмегу, кварц с двумя кондёрами на 22пФ, подтягивающий резитор на ноге Reset (увеличил с 10к до 220к) и кондёр для формирования импульса сброса при программировани.
При уходе в сон, тактовая частота понижается до 1мГц, а напряжение питания Ардуины, падает практически до предела 1,9v (предел по даташиту 1,8v, хотя мне попадались образцы, прекрасно работающие и на 0,7v.
Отключаются все элементы схемы кроме МК и одного датчика (приёмник-пришлось купить японский с потреблнием 1,2мкА, и доработать его под собственные нужды, нужен он чтоб постоянно слушать эфир. Когда кто нибудь подходит с передатчиком он будит МК и последний ждёт кодовой посылки).
Все датчики, кроме дымового я использовал типа "сухой контакт" без всяких микросхем, диодов и т.д. Дымовой датчик установил изотопный, ток потребления у него в рабочем состоянии 0,4мкА в состоянии "Пожар" 5мА.
Вот и все хитрости...
З.Ы. вся схема в итоге потребляет около 2,5мкА в спящем режиме, а у моей схемы это основной режим.
При уходе в сон, тактовая частота понижается до 1мГц, а напряжение питания Ардуины, падает практически до предела 1,9v (предел по даташиту 1,8v, хотя мне попадались образцы, прекрасно работающие и на 0,7v.
Вы либо что-то путаете, либо неправильно измерения производили. От 0.7в атмега не будет работать в принципе. Скорее всего паразитное питание откуда-то заходило. Например, от программатора.
Цитата:
приёмник-пришлось купить японский с потреблнием 1,2мкА, и доработать его под собственные нужды, нужен он чтоб постоянно слушать эфир.
Тоже что-то совсем необычное. Какие-то данные по модели этого приемника вы можете озвучить?
Пришёл к выводу, что для моей поделки потребуется Pro Mini, а Digispark не подойдёт (у него всего одно прерывание, его не хватит). В связи с этим просьба к знающим людям: не могли бы вы привести образец скетча, который бы переводил Pro Mini с Atmega328p в режим SLEEP_MODE_PWR_DOWN с минимальным энергопотреблением (понятно, что лишнюю обвязку я с платы уберу) и обеспечивал бы всего две вещи:
- выход из сна через, например, 2*8=16 секунд;
- выход из сна подачей высокого уровня на INT0 или INT1.
Ещё вопрос, если позволите. Имею сейчас в наличии пару NANO китайских (c CH340G, естественно). Есть ли у кого опыт по отключению на ней лишнего - намного ли больше резать-паять, чем у Pro Mini?
По первому вопросу, да, возможно заходило с программатора, возможно в схеме вместо конденсатора был ионистор запаян. Давно это было, достался нам пакет Атмег, штук 2000 или больше, вот мы над ними и издевались.
По второму вопросу: У меня знакомый живёт в Японии, я попросил его посмотреть приёмопередатчик, типа как от автомобильных брелоков. Там то приёмник потребляет 1-3 мкА. Он присылает мне игрушку, кошачьи ушки, такой обруч с двумя ушами и маленький пультик к ним, говорит отдельно можно купить только партию а поштучно не продают, но в игрушке стоит. В итоге я стал счастливым обладателем 2х трансиверов, работают они на нестандартной частоте 3,65гГц, дальность около 50м (что мне и нужно). 6 дипазонов в каждом диапазоне 65536 каналов. Настройки производятся по интерфейсу I2С, по нему также передаются данные принятые и на отправку. Есть вывод на котором появляется лог. 1 если к приёмнику было обращение, я его использовал для того чтобы будить контроллер. С настройками я не разобрался, работает на 1 дипазоне 1 канале по дефолту. Питание 2 - 5 вольт. Я дал питание 2,2 вольта, потому что чем больше напряжение тем соответсвенно и ток. Имеет вид железной коробочки 1,5х1 см. Похож на SIM800 название прочесть не могу, так как не силён в японском.
Для dimax
Мультиметром конечно, а чем их ещё меряют? Не линейкой же :) Мультиметр дорогой, не китайский за 250р. Я думаю, ему можно верить.
А как, ставлю мультиметр на 2000 мА, подключаю его последовательно с тем где хочу померить ток, и источником питания. Жду минуту, чтоб закончились все переходные процессы. И начинаю на мультиметре плавно уменьшать значение, так дохожу до микроамперов.
Разобрался с отключением лишних элементов обвеса у NANO с CH340G на борту. Оказалось, на этой плате отключить лишнее ещё проще, чем на Digispark.
1. Перерезать одну дорожку возле резистора RX светодиода:
Этим самым мы отключаем сразу стабилизатор питания AMS1117, светодиод питания, светодиоды RX и TX. Два последних светодиода, как я понимаю, тоже нужно отключать: они сидят на +5В, а для экономии энергии нужно переводить выводы в LOW. То есть в таком случае они окажутся под напряжением.
2. Перерезать дорожку питания у CH340G. Конечно, понадобится провод для подключения этой микросхемы при заливке скетчей:
Вот и всё! Со включенным WatchDog этот скетч
// пробуждение по WatchDog
#include <avr/sleep.h>
#include <avr/wdt.h>
const byte LED = LED_BUILTIN;
void flash ()
{
pinMode (LED, OUTPUT);
for (byte i = 0; i < 10; i++)
{
digitalWrite (LED, HIGH);
delay (50);
digitalWrite (LED, LOW);
delay (50);
}
pinMode (LED, INPUT);
} // end of flash
// watchdog interrupt
ISR (WDT_vect)
{
wdt_disable(); // disable watchdog
} // end of WDT_vect
void setup () { }
void loop ()
{
flash ();
digitalWrite (0, LOW);
// disable ADC
ADCSRA = 0;
// clear various "reset" flags
MCUSR = 0;
// allow changes, disable reset
WDTCSR = bit (WDCE) | bit (WDE);
// set interrupt mode and an interval
WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE, and 8 seconds delay
wdt_reset(); // pat the dog
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
noInterrupts (); // timed sequence follows
sleep_enable();
// turn off brown-out enable in software
MCUCR = bit (BODS) | bit (BODSE);
MCUCR = bit (BODS);
interrupts (); // guarantees next instruction executed
sleep_cpu ();
// cancel sleep as a precaution
sleep_disable();
} // end of loop
даёт энергопотребление 7 мкА (обратите внимание, что здесь пин 0 переводится в LOW - если этого не сделать, ток будет около 80 мкА).
На скетче с пробуждением от прерывания на втором пине (WatchDog не используется)
// пробуждение по прерыванию
#include <avr/sleep.h>
const byte LED = LED_BUILTIN;
void blink(int cnt)
{
for (int i = 0; i < cnt; i++) {
digitalWrite (LED, HIGH);
delay (50);
digitalWrite (LED, LOW);
delay (50);
}
}
void wake ()
{
// cancel sleep as a precaution
sleep_disable();
// precautionary while we do other stuff
detachInterrupt (0);
} // end of wake
void setup ()
{
digitalWrite (2, HIGH); // enable pull-up
} // end of setup
void loop ()
{
pinMode (LED, OUTPUT);
blink (10);
digitalWrite (0, LOW); // отправка на pin D0 значения LOW, иначе там остаётся около 2.5 В
delay (50);
pinMode (LED, INPUT);
// disable ADC
ADCSRA = 0;
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_enable();
// Do not interrupt before we go to sleep, or the
// ISR will detach interrupts and we won't wake.
noInterrupts ();
// will be called when pin D2 goes low
attachInterrupt (0, wake, FALLING);
EIFR = bit (INTF0); // clear flag for interrupt 0
// turn off brown-out enable in software
// BODS must be set to one and BODSE must be set to zero within four clock cycles
MCUCR = bit (BODS) | bit (BODSE);
// The BODS bit is automatically cleared after three clock cycles
MCUCR = bit (BODS);
// We are guaranteed that the sleep_cpu call will be done
// as the processor executes the next instruction after
// interrupts are turned on.
interrupts (); // one cycle
sleep_cpu (); // one cycle
} // end of loop
мой китайский тестер за 250 рублей :) на диапазоне с разрешением 1 мкА показывает ноль.
Кстати, чтобы не паять чёрный провод, пытался сделать так:
но диод Шоттки на входе USB питания имеет утечку в обратном направлении больше 1 мА, так что этот вариант не прошёл. Конечно, можно было паять вместо этого диода обычный, но по Datasheet на CH340G напряжение питания 4.5 - 5.5 В, и чего он мне напрошивает при четырёхвольтовом питании - неизвестно.
Я было засомневался, что подобное вообще существует в природе, слишком уж необычные характеристики, но потом погуглил слегка и был вынужден умерить скепсис. Оказалось, что существует класс устройств под названием "Wake Up Receiver", где в режиме постоянного прослушивания эфира находится не полноценный трансивер, а некая схема по принципу детекторного радиоприемника, часто настренная на иную частоту, нежели та, что используется для передачи данных. Детектор на СВЧ-диоде Шоттки вылавливает из эфира "пробуждающий" импульс, который потом усиливается сверхэкономичным ОУ, выход которого является линией внешнего прерывания для МК. Микроконтроллер пробуждается и запускает вполне себе традиционный передачик типа CC2540 или даже NRF24L01. Вобщем, "Wake Up Receiver" выглядеть может примерно так:
Собственное потребление TLV2401 -- 0.8мка, еще какие-то микротоки утекают через прочие элементы схемы и совокупное потребление чуть больше микроампера для данного "радио-пробудителя" представляется вполне достижимым.
Мультиметром конечно, а чем их ещё меряют? Не линейкой же :) Мультиметр дорогой, не китайский за 250р. Я думаю, ему можно верить.
А как, ставлю мультиметр на 2000 мА, подключаю его последовательно с тем где хочу померить ток, и источником питания. Жду минуту, чтоб закончились все переходные процессы. И начинаю на мультиметре плавно уменьшать значение, так дохожу до микроамперов.
позвольте вопрос - вот в этом случае, при измерении потребления - ваше устройство как запитано?
от батарейки?
у меня похожий мультиметр - MASTECH MS8268, но если я его включаю в цепь питания, чтобы измерить потребляемый ток - то моя ардуина постоянно перезагружается.
При каком напряжении питания Вам удалось завести вашу Nano? Как я смотрю по даташиту на 328Р, о питании от CR2030 (3V) или Li-Ion (3.7V) можно забыть со штатным кварцем на 16 МГц....
При каком напряжении питания Вам удалось завести вашу Nano? Как я смотрю по даташиту на 328Р, о питании от CR2030 (3V) или Li-Ion (3.7V) можно забыть со штатным кварцем на 16 МГц....
Нелогично покупать готовую плату (Нано), а потом удалять с нее элементы и резать дорожки и тд. Если нужно низкое потребление - купите микроконтроллер отдельно и запустите его на той частоте, на какой хотите.
ASK-list
При каком напряжении питания Вам удалось завести вашу Nano? Как я смотрю по даташиту на 328Р, о питании от CR2030 (3V) или Li-Ion (3.7V) можно забыть со штатным кварцем на 16 МГц....
Со спящими режимами на пониженном питании не экспериментировал, но вот нарушения обычной работы Nano при питании от Li-Ion у меня не происходило (в том числе при разряде аккумулятора до 3.6V).
b707 пишет:
Нелогично покупать готовую плату (Нано), а потом удалять с нее элементы и резать дорожки и тд. Если нужно низкое потребление - купите микроконтроллер отдельно и запустите его на той частоте, на какой хотите.
Подумывал о покупке микроконтроллера отдельно. Для домашней поделки проще перерезать две дорожки и получить энергопотребление в спящем режиме меньше 1 мкА, чем распаять на самодельной плате микроконтроллер и шить его программатором. К тому же цена платы теперь совсем небольшая.
Если купить Pro Mini - не факт, что резать ничего не придётся, а отдельный программатор также нужно будет подключать.
Подумывал о покупке микроконтроллера отдельно. Для домашней поделки проще перерезать две дорожки и получить энергопотребление в спящем режиме меньше 1 мкА, чем распаять на самодельной плате микроконтроллер и шить его программатором.
Самодельную плату так и так делать - что под готовую Нано, что под микроконтроллер. Вы же не станете собирать готовое изделие на бредборде с проводками, правильно? А "отдельный программатор" не нужен, достаточно другой Нано/Уно.
Привет ребята., помогите разобраться ... Сетуация такая Заганяю в спящий режим, но после выхода из него одна из функций (определения питания на входе в Ардуину).. Хочу следить за акамулятором допустим раз в 15 мин..
Короче пока в сон не отправил всё работает, как в сон загнал.То после просыпания по Watchdog, функция readVcc() выводит последние показания перед сном, и больше не меняеться, только перезагрузка спасает.
Хоть по прерыванию бужу Ардуино или по количеству спящих режимов..
Вот код функций (определения напрежения на в ходе в Ардуину).
const long InternalReferenceVoltage = 1062; // Adjust this value to your board's specific internal BG voltage
// Code courtesy of "Coding Badly" and "Retrolefty" from the Arduino forum
// results are Vcc * 100
// So for example, 5V would be 500.
int readVcc()
{
// REFS0 : Selects AVcc external reference
// MUX3 MUX2 MUX1 : Selects 1.1V (VBG)
ADMUX = bit(REFS0) | bit(MUX3) | bit(MUX2) | bit(MUX1);
ADCSRA |= bit(ADSC); // start conversion
while (ADCSRA & bit(ADSC))
{
} // wait for conversion to complete
int results = (((InternalReferenceVoltage * 1024) / ADC) + 5) / 10;
return results;
} // end of getBandgap
А вот кот sleepNow(), после которого функция readVcc() не работает..
ADCSRA = 0; // отключаем Аналоговый компаратор (такой код в других скетчах)
void sleepNow() // Функция увода ардуины в спячку
{
pr_Li_ion_Bat++;// переменая для проверки батареи через определённый периуд времени (считаем сколько раз уснули)
digitalWrite(LED_BUILTIN, LOW); // Выключаем светодиод
//
// for (byte i = 0; i <= A5; i++) // переводим пины в режим выхода (закомментировано, т.к. виснет после засыпания)
//
// pinMode (i, OUTPUT); // changed as per below
// digitalWrite (i, LOW); // ditto
// }
//
ACSR |= (1 << ACD); // отключаем Аналоговый компаратор
ADCSRA = 0; // отключаем Аналоговый компаратор (такой код в других скетчах)
power_all_disable(); // отключаем все внутренние блоки ЦП. (требуется <avr/power.h> + эта строчка должн быть после ADCSRA=0)
// power_adc_disable(); // ADC converter
// power_spi_disable(); // SPI
//power_usart0_disable();// Serial (USART)
// power_timer0_disable();// Timer 0
// power_timer1_disable();// Timer 1
// power_timer2_disable();// Timer 2
// power_twi_disable(); // TWI (I2C)
// отключаем BOD
noInterrupts(); // cli(); // отключение прерываний
uint8_t x = (MCUCR & ~(1 << BODSE)) | (1 << BODS); // подготовка бит
MCUCR = x | (1 << BODSE); // процедура отключения BOD
MCUCR = x;
interrupts(); //sei(); // включение прерываний
// конец отключения BOD
// подготовка WatchDog
MCUSR = 0; // clear various "reset" flags
WDTCSR = bit(WDCE) | bit(WDE); // allow changes, disable reset
// set interrupt mode and an interval
WDTCSR = bit(WDIE) | bit(WDP3) | bit(WDP0); // set WDIE, and 8 seconds delay
//WDTCSR = bit (WDIE) | bit (WDP2) | bit (WDP1); // set WDIE, and 1 second delay
wdt_reset(); // pat the dog
// конец подготовки WatchDog
attachInterrupt(0, wakeUpNow, LOW); // назначаем прерывание 0 (pin 2) для выполнения функции wakeUpNow при нажатии кнопки
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // устанавливается режим сна (это не вход в сон! Только установка режима!)
sleep_enable(); // включаем sleep-бит в регистре mcucr. Теперь возможен сон
sleep_mode(); //sleep_cpu(); // Здесь устройство перейдет в режим сна. Внешние прерывания и WDT продолжают работать.
// -----------------------------------------------ПОСЛЕ ПРОСЫПАНИЯ ВЫПОЛНЕНИЕ КОДА ПРОДОЛЖИТСЯ ОТСЮДА!!!
wakeUpNow();
}
void wakeUpNow() // Пробуждение по внешнему прерыванию
{
//}
// Таймеы и код, использующий таймеры (serial.print и др...) здесь не будут работать
// Также мы не должны выполнять какие-то спец. функции, здесь мы просто просыпаемся
sleep_disable(); // отключаем спящий режим
power_all_enable(); // включаем все внутренние блоки ЦП
wdt_disable(); // нужно ли здесь это?
config(); // настраиваем входы/выходы
detachInterrupt(0); // Выключаем прерывание - при нормальном режиме wakeUpNow() не будет вызываться
}
Короче помогите разобраться.. Всем кто ответил на мою просьбу, огромное спасибо..
Люди добрые, помогите!
Пишу программу на мегу 2560, для авто. Очень нужен спящий режим, с выходом из него по прерыванию.
Скетч из поста #5 заливал и модифицировал безчисленное количество раз. Результат всегда один - мега легко входит в спячку по прерыванию, но никогда из неё не выходит. В борьбе с даташитом победил даташит, я лиш понял что вроде бы нужно использовать прирывание INT7, коего ненашел.
Help, как вывести из спячки мегу?
По ее мотивам переписал код для вас. Проверить не на чем пока, должно работать:
Почему при нажатии кнопки (wakePin = 2;) во время бодорствования Arduino UNO зависает?
Чуть переделанный мною код для пробуждения не только по кнопке, но и по WDT.
Вроде работает (в рабочем режиме кушает 8,6 мА, в спящем - 2,28 мА), но гляньте, вдруг есть что оптимизировать.
В частности, по нажатию кнопки "Welcome" иногда выводится два раза подряд.
Можно корректный пример перевода, просыпания ардуины в спящий режим. Все что сдесь есть работает некорректно. Либо намертво засыпает, либо работает через раз и засыпает намертво(((
вот 100% работающий код (вчера был загружен в две платки для тестов):
https://bigdanzblog.wordpress.com/2014/08/10/attiny85-wake-from-sleep-on...
P.S. watchdog используется? В этом случае возможны такие проблемы со стандартным загрузчиком: https://geektimes.ru/post/255800/
Может кто из вас поделится библиотекой <avr/sleep.h> ???
Облазил пол интернета и фиг
Может кто из вас поделится библиотекой <avr/sleep.h> ???
Облазил пол интернета и фиг
если у вас есть программа Arduino, то у вас уже есть эта библиотека.
Доброго времени суток. Подскажите, как на Ардуино нано(Atmega328p) сделать следующее: уходить в сон по нажатию кнопки и просыпаться по нажатию той же кнопки(подключенной к D2) и по таймеру, если в ходе обработки прерывания от таймера выполнилось условие равенства между моими константами и данными прочитанными по SPI, то необходимо выйти из сна и запретив прервания перейти к выполнению основной программы.
А какое потребление енергии в спящем режиме ардуины? можно ли приравнять к отключеному питанию?
http://www.polesite.ru/?p=1273
Использование режима сна для экономии энергии
http://www.gammon.com.au/power
3 years on one set of batteries
http://jeelabs.org/2013/09/08/3-years-on-one-set-of-batteries/
https://www.drive2.ru/b/1282902/
Понижение тактовой частоты, режимы энергосбережения:
http://student-proger.ru/2013/10/energopotreblenie-arduino/
http://inet-deal.mpa.ru/articles/arduino-003.html
https://www.reddit.com/r/arduino/comments/o5443/so_you_want_an_easy_way_to_save_power/
http://arduino.ru/forum/apparatnye-voprosy/rezhim-energosberezheniya
Пробуждение Arduino из спящего режима по нажатию кнопки
https://bigdanzblog.wordpress.com/2014/08/10/attiny85-wake-from-sleep-on-pin-state-change-code-example/
https://sites.google.com/site/vanyambauseslinux/arduino/ispolzovanie-preryvanij-arduino#p5
http://arduino.ru/forum/obshchii/spyashchii-rezhim
А каким образом можно реализовать не спящий режим а отключение питания (почти полностю), принцип как в электронных устройствах, плеерах, мобилках, чтоб при нажатии допустим 5с включался аппарат и при таком же нажатии вырубался???
а с чего ты взял, что они полностью выключаются? Там скорее всего такой же сон, с микроамперным потреблением.
Но если очень надо, то можно и полное отрубание.
Вот схема на реле:
Можно и средствами Arduino - кнопкой напрямую подаем питание на Vcc, Arduino включается, в setup прописываем - сразу же после включения: подать на пин X сигнал, который через транзистор скоммутирует питание (параллельно кнопке), после этого кнопку можно отпускать. Недостаток тут есть - надо чуть подержать кнопку (0,5-2 сек), чтобы Arduino успел загрузиться.
Посоветуйте пожалуйста как лучше сделать. Нужно сделать чтоб ардуина просыпалась по внешнему сигналу, и по времени. С внешним сигналом я разобрался, а вот с таймером возникли вопросы. Во всех примерах пробуждения во Watсhdog-у используются корткие интервалы (от миллисекунд до десятков секунд), мне же нужны интервалы поболее (1ч. 2ч. 4ч. 8ч. и 16ч.). Всвязи с этим встаёт резонный вопрос, можно ли настроить сторожевой таймер на такие интервалы, и если да, то будет ли это правильно. Или рациональней будет использовать часы реального времени?
сторожевой таймер имеет максимальный интервал 8 сек.
Но никто тебе не мешает завести переменную, куда каждые 8 сек записывать приращение на единичку.
Как только значение переменной превысит 450/900/1800/3600,значит пора просыпаться ;)
О! Спасибо за подсказку. Отличная идея, а то у меня на ардуинке всего 3 ноги свободных осталось, и с часами реального времени будет проблемка...
сторожевой таймер имеет максимальный интервал 8 сек.
важно понимать, что 8сек относятся именно к atmega328, у других МК надо даташит смотреть, может быть меньше
здесь дело такое. просыпаться по времени можно от обычного таймера, но обычный таймер требует использования менее экономного режима сна, т.е. если пробуждаться от обычного таймера потребление во время сна будет в разы больше
watchdog изначально придуман для другого поэтому не расчитан на длительное время между прерываниями, но его фишка как раз в том что для его работы требуется меньше энергии
НО. если RTC уже есть и они уже жрут свои микроватты энергии, то просыпание по RTC позволит сэкономить еще чуточку, ибо хоть watchdog есть мало, но все равно ест. Если его отключить то можно довести потребление во сне до почти абсолютного минимума, особенно если еще все остальное отключить (в частности детектор низкого напряжения)
RTC нету, но скорее всего придётся ставить. Так как нужно определять время сработки датчика. Я на каком то форуме, недели 2 назад читал что у часов можно запрограммировать какой то выход, чтоб на нём раз в час менялся лог. уровень. Буду весьма признателен если кто нибудь подскажет как, и где можно посмотреть пример использования RTC для этих целей. Облазил пол инета и ни где ни чего вразумительного не нашёл...
Ds3231 имеет два будильника, можно на конкретное время настроить
Victor1306
PCF8563, это RTC с таймером. Таймер весьма гибок (256 отсчетов от ~2мкс до 1 мин на отсчёт), выход таймера настраивается (изм. лог. уровня / импульс), низкое потребление (~500 nA). Подробности в техдоке.
Использую весьма давно.
Вопрос такой: вот кнопками или по таймеру - это понятно более-менее. А вот такая задача: имеем устройство на ардуине которое транслирует с использованием модуля RX 433 последовательности символов - в течение часа - "а", второго часа - "b", третьего - "с" и т.п. Второе устройство, с ресивером, находится в зоне приема в спящем режиме. Можно ли сделать так, чтобы оно просыпалось во время трансляции определенного символа и засыпало по окончании трансляции или выходе устройства-приемника из зоны сигнала (либо отключении передатчика)
какой минимальный ток потребления удавалось достичь?
а если остальные ноги нагружены чемто, то тогда как с величиной потребления кристала по питанию?
Насчёт минимального потребляемого тока.
Экспериментировал с Digispark.
На этой плате три пассивных потребителя энергии:
- светодиод питания: выпаял его резистор;
- стабилизатор напряжения 78M05 - отпаял его выходную ногу;
- подтягивающий резистор, обеспечивающий работу с USB: переставил его и подпаял пару проводков, чтобы их замыкать при заливке скетчей.
Получилось вот так:
За основу кода взял пример отсюда.
Код подкорректировал по своему разумению, получилось так:
С этим скетчем Digispark выходит из спящего режима по Watchdog или по высокому уровню на третьем пине.
Ток, потребляемый платой в режиме SLEEP_MODE_PWR_DOWN - 7 мкА (семь микроампер).
То есть тысячу миллиампер-часов энергии плата съест в этом режиме за 16 лет.
Продолжил эксперименты со спящим режимом в Digispark. У меня в нём навернулся загрузчик (сам не понял, почему). Я восстановил его, подробнее здесь. Теперь с загрузчиком micronucleus-1.06.hex минимальный ток составляет 28 мкА (что тоже неплохо).
Кстати, как я понял, для экономного спящего режима нужно отправить (digitalWrite) перед засыпанием на использовавшиеся пины уровень LOW.
Вернул энергопотребление Digispark на уровень 7 мкА. Для этого прошил загрузчик micronucleus-1.06.hex (см. ссылку на моё описание этого процесса в предыдущем посте), но с другими значениями fuses. Фрагмент моего файла boards.txt:
Здесь отключены детекторы низкого напряжения питания.
Как оказалось, включение "Brown-out Detector trigger level" на уровень 2.7 В (BODLEVEL1) увеличивало энергопотребление в SLEEP_MODE_PWR_DOWN режиме с 7 до 28 мкА.
7мка для голой атмеги многовато. У меня беспроводной сенсор, состоящий из МК, трех I2C датчиков, передатчика NRF24L01 и DC-DC преобразователя, в периоды, когда все это хозяйство включено, но "спит", потребляет 4.5мка.
7мка для голой атмеги многовато. У меня беспроводной сенсор, состоящий из МК, трех I2C датчиков, передатчика NRF24L01 и DC-DC преобразователя, в периоды, когда все это хозяйство включено, но "спит", потребляет 4.5мка.
можете пример привести что и как использовали?
У меня менее пары милиампер чтото не получалось на 328, хотя паял только проц на отдельной плате.
Так с мегой вообще ничего не нужно делать. Все, что требуется, она сама с рождения умеет:
Остается только внимательно все поотключать перед отправкой в сон, снизить тактовую и пусть она дремлет на наноамперах.
Моя Ардуина, с которой я так долго воевал, сейчас потребляет в спящем режиме 0,7 мкА. Добился такого так:
Вместо WatchDog-а использую часы реального времени, пробуждение происходит по прерыванию которое генерится часами (будильником).
В Атмеге при уходе в сон, отключается всё что может отключаться.
На плате Ардуино про мини, отпаял практически всю обвязку контроллера (светодиоды, стабилизатор на 3,3v, оставил только саму Атмегу, кварц с двумя кондёрами на 22пФ, подтягивающий резитор на ноге Reset (увеличил с 10к до 220к) и кондёр для формирования импульса сброса при программировани.
При уходе в сон, тактовая частота понижается до 1мГц, а напряжение питания Ардуины, падает практически до предела 1,9v (предел по даташиту 1,8v, хотя мне попадались образцы, прекрасно работающие и на 0,7v.
Отключаются все элементы схемы кроме МК и одного датчика (приёмник-пришлось купить японский с потреблнием 1,2мкА, и доработать его под собственные нужды, нужен он чтоб постоянно слушать эфир. Когда кто нибудь подходит с передатчиком он будит МК и последний ждёт кодовой посылки).
Все датчики, кроме дымового я использовал типа "сухой контакт" без всяких микросхем, диодов и т.д. Дымовой датчик установил изотопный, ток потребления у него в рабочем состоянии 0,4мкА в состоянии "Пожар" 5мА.
Вот и все хитрости...
З.Ы. вся схема в итоге потребляет около 2,5мкА в спящем режиме, а у моей схемы это основной режим.
Вы либо что-то путаете, либо неправильно измерения производили. От 0.7в атмега не будет работать в принципе. Скорее всего паразитное питание откуда-то заходило. Например, от программатора.
Тоже что-то совсем необычное. Какие-то данные по модели этого приемника вы можете озвучить?
Пришёл к выводу, что для моей поделки потребуется Pro Mini, а Digispark не подойдёт (у него всего одно прерывание, его не хватит). В связи с этим просьба к знающим людям: не могли бы вы привести образец скетча, который бы переводил Pro Mini с Atmega328p в режим SLEEP_MODE_PWR_DOWN с минимальным энергопотреблением (понятно, что лишнюю обвязку я с платы уберу) и обеспечивал бы всего две вещи:
- выход из сна через, например, 2*8=16 секунд;
- выход из сна подачей высокого уровня на INT0 или INT1.
Заранее спасибо.
Power saving techniques for microprocessors
Viktor1306, а можно полюбопытствовать чем и как вы измеряете микроамперы? Задача то нетривиальная :)
Power saving techniques for microprocessors
Как раз то, что надо, спасибо! Буду пробовать.
Ещё вопрос, если позволите. Имею сейчас в наличии пару NANO китайских (c CH340G, естественно). Есть ли у кого опыт по отключению на ней лишнего - намного ли больше резать-паять, чем у Pro Mini?
Для a5021
По первому вопросу, да, возможно заходило с программатора, возможно в схеме вместо конденсатора был ионистор запаян. Давно это было, достался нам пакет Атмег, штук 2000 или больше, вот мы над ними и издевались.
По второму вопросу: У меня знакомый живёт в Японии, я попросил его посмотреть приёмопередатчик, типа как от автомобильных брелоков. Там то приёмник потребляет 1-3 мкА. Он присылает мне игрушку, кошачьи ушки, такой обруч с двумя ушами и маленький пультик к ним, говорит отдельно можно купить только партию а поштучно не продают, но в игрушке стоит. В итоге я стал счастливым обладателем 2х трансиверов, работают они на нестандартной частоте 3,65гГц, дальность около 50м (что мне и нужно). 6 дипазонов в каждом диапазоне 65536 каналов. Настройки производятся по интерфейсу I2С, по нему также передаются данные принятые и на отправку. Есть вывод на котором появляется лог. 1 если к приёмнику было обращение, я его использовал для того чтобы будить контроллер. С настройками я не разобрался, работает на 1 дипазоне 1 канале по дефолту. Питание 2 - 5 вольт. Я дал питание 2,2 вольта, потому что чем больше напряжение тем соответсвенно и ток. Имеет вид железной коробочки 1,5х1 см. Похож на SIM800 название прочесть не могу, так как не силён в японском.
Для dimax
Мультиметром конечно, а чем их ещё меряют? Не линейкой же :) Мультиметр дорогой, не китайский за 250р. Я думаю, ему можно верить.
А как, ставлю мультиметр на 2000 мА, подключаю его последовательно с тем где хочу померить ток, и источником питания. Жду минуту, чтоб закончились все переходные процессы. И начинаю на мультиметре плавно уменьшать значение, так дохожу до микроамперов.
Viktor1306, а что за мультиметр у вас?
Первый Mastech MS8240D на столе стоит а второй Mastech MAS830 для того, чтоб с собой носить
Разобрался с отключением лишних элементов обвеса у NANO с CH340G на борту. Оказалось, на этой плате отключить лишнее ещё проще, чем на Digispark.
1. Перерезать одну дорожку возле резистора RX светодиода:
Этим самым мы отключаем сразу стабилизатор питания AMS1117, светодиод питания, светодиоды RX и TX. Два последних светодиода, как я понимаю, тоже нужно отключать: они сидят на +5В, а для экономии энергии нужно переводить выводы в LOW. То есть в таком случае они окажутся под напряжением.
2. Перерезать дорожку питания у CH340G. Конечно, понадобится провод для подключения этой микросхемы при заливке скетчей:
Вот и всё! Со включенным WatchDog этот скетч
даёт энергопотребление 7 мкА (обратите внимание, что здесь пин 0 переводится в LOW - если этого не сделать, ток будет около 80 мкА).
На скетче с пробуждением от прерывания на втором пине (WatchDog не используется)
мой китайский тестер за 250 рублей :) на диапазоне с разрешением 1 мкА показывает ноль.
Кстати, чтобы не паять чёрный провод, пытался сделать так:
но диод Шоттки на входе USB питания имеет утечку в обратном направлении больше 1 мА, так что этот вариант не прошёл. Конечно, можно было паять вместо этого диода обычный, но по Datasheet на CH340G напряжение питания 4.5 - 5.5 В, и чего он мне напрошивает при четырёхвольтовом питании - неизвестно.
Я было засомневался, что подобное вообще существует в природе, слишком уж необычные характеристики, но потом погуглил слегка и был вынужден умерить скепсис. Оказалось, что существует класс устройств под названием "Wake Up Receiver", где в режиме постоянного прослушивания эфира находится не полноценный трансивер, а некая схема по принципу детекторного радиоприемника, часто настренная на иную частоту, нежели та, что используется для передачи данных. Детектор на СВЧ-диоде Шоттки вылавливает из эфира "пробуждающий" импульс, который потом усиливается сверхэкономичным ОУ, выход которого является линией внешнего прерывания для МК. Микроконтроллер пробуждается и запускает вполне себе традиционный передачик типа CC2540 или даже NRF24L01. Вобщем, "Wake Up Receiver" выглядеть может примерно так:
Собственное потребление TLV2401 -- 0.8мка, еще какие-то микротоки утекают через прочие элементы схемы и совокупное потребление чуть больше микроампера для данного "радио-пробудителя" представляется вполне достижимым.
Спасибо CityCat за рабочий код.
Мультиметром конечно, а чем их ещё меряют? Не линейкой же :) Мультиметр дорогой, не китайский за 250р. Я думаю, ему можно верить.
А как, ставлю мультиметр на 2000 мА, подключаю его последовательно с тем где хочу померить ток, и источником питания. Жду минуту, чтоб закончились все переходные процессы. И начинаю на мультиметре плавно уменьшать значение, так дохожу до микроамперов.
позвольте вопрос - вот в этом случае, при измерении потребления - ваше устройство как запитано?
от батарейки?
у меня похожий мультиметр - MASTECH MS8268, но если я его включаю в цепь питания, чтобы измерить потребляемый ток - то моя ардуина постоянно перезагружается.
вот тут тема моя с деталями:
http://arduino.ru/forum/apparatnye-voprosy/mk-na-baze-atmega328-izmereni...
может подскажете чтото?
ASK-list
При каком напряжении питания Вам удалось завести вашу Nano? Как я смотрю по даташиту на 328Р, о питании от CR2030 (3V) или Li-Ion (3.7V) можно забыть со штатным кварцем на 16 МГц....
ASK-list
При каком напряжении питания Вам удалось завести вашу Nano? Как я смотрю по даташиту на 328Р, о питании от CR2030 (3V) или Li-Ion (3.7V) можно забыть со штатным кварцем на 16 МГц....
Нелогично покупать готовую плату (Нано), а потом удалять с нее элементы и резать дорожки и тд. Если нужно низкое потребление - купите микроконтроллер отдельно и запустите его на той частоте, на какой хотите.
При каком напряжении питания Вам удалось завести вашу Nano? Как я смотрю по даташиту на 328Р, о питании от CR2030 (3V) или Li-Ion (3.7V) можно забыть со штатным кварцем на 16 МГц....
Самодельную плату так и так делать - что под готовую Нано, что под микроконтроллер. Вы же не станете собирать готовое изделие на бредборде с проводками, правильно? А "отдельный программатор" не нужен, достаточно другой Нано/Уно.
Вот код функций (определения напрежения на в ходе в Ардуину).
А вот кот sleepNow(), после которого функция readVcc() не работает..
Я думаю что это связано с этой проблемай
ACSR |= (1 << ACD);
// отключаем Аналоговый компаратор
ADCSRA = 0;
// отключаем Аналоговый компаратор (такой код в других скетчах)
Короче помогите разобраться.. Всем кто ответил на мою просьбу, огромное спасибо..
ruslan_rachinsk, а что тут разбираться? Копипастить с умом нужно. Засыпая вы отрубаете АЦП (18 строка) , а кто его включать будет обратно?
Понял почему не работает readVcc() ,после спящего режима..
Короче после спящего пежима константа (переменная) ADCSRA = 0;остаётся пустой
А перед спящим режимом константа работает и она не пустая..
Так вот вопрос, как вернуть константt (переменная) ADCSRA нужное значение..
ruslan_rachinsk, а что тут разбираться? Копипастить с умом нужно. Засыпая вы отрубаете АЦП (18 строка) , а кто его включать будет обратно?
Я начинающий, слабо сдесь понемаю, а разве вот это строка не включает всё сразу..
power_all_enable(); // включаем все внутренние блоки ЦП
Токда подскажи как включить..
Тема закрыта, разобрался..
Всем пока спасибо...
ruslan_rachinsk, ADCSRA=(1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2)|(1<<ADEN)|(1<<ADSC);