Nano+neoway590+lcd1602: вопрос по снижению электропотребления.
- Войдите на сайт для отправки комментариев
Приветствую!
Делаю проект, питается от сети, при пропадании переключается на аккумулятор и уходит в сон.
По сторожу просыпается, проверяет напряжение, если не появилось-спит дальше.
Можно было бы и без сна, вырубилось и все. Но надо сохранять настройки. Можно писать их в eeprom, но опять же, надо чтоб в режиме когда нет питания, все же иногда чтото выполняла.
Но вопрос не в этом. Это все работает и отлажено.
Вопрос в питании.
Все рабочие пины перед уходом в сон выключаю. Кроме...
Модем сидит на софтсериале(8,9), лсд через i2c.
На них продолжают гореть светодиоды.
При том, что модем вообще питается через релюшку, которая прерывает питание. А лсд если рубить питание, то заново не инициализируется.
Что делать? Как вырубить эти два светика?
Паяльник не предлагать
Без паяльника - никак. Или рвать питание и заново инициализировать
без паяльника вообще нет смысла начинать возиться с батарейными устройствами. Одна Нано жрет больше всех светодиодов, как ты ее в сон не отправляй. Чтобы батарейку растянуть подольше - надо с Наны часть деталей убрать. Паяльником.
Даже в такой связке, на 1000 мА акке приблуда живет во сне 7-8 часов. Хотел растянуть на часов 30. больше не надо. Это запроектированный максимум.
С паяльником дружу, но это крайний вариант. Как минимум думал светики с переферии (Модем и экран) как то погасить программно.
Одного отключения питания мало.
Даже в такой связке, на 1000 мА акке приблуда живет во сне 7-8 часов.
ахренеть... потребление 140мА*ч ????
Даже без применения паяльника должна жить раз в 5 дольше. А при минимальном применении паяльника 500 часов можно получить запросто.
ахренеть... потребление 140мА*ч ????
Даже без применения паяльника должна жить раз в 5 дольше. А при минимальном применении паяльника 500 часов можно получить запросто.
Ну тут опыта маловасто..
1.На борту 2 шт 18b20, во сне я так понимаю тоже кушают. Пины в 0 опускаь? Как потом заново запускаться?
2. LCD получается тоже продолжает кушать
3.Модем хоть и рвется питание, но по RX-TX питание уходит.
такс..
пока тайм аут. потестирую.
модем 590 не щупал, а вот sim800l+MK до 2мА потребление доводил.
но тут такая бяка получается: хоть устройство и предополагалось батарейное, но модем все равно просыпался от разного чиха (СМС, звонок и прочее), пришлось сделать логику - каждые 30 минут просыпаться, проверять СМС и опять засыпать. Примерно прикинул - от аккумулятора 2500 мА 18650 максимум неделя работы.
я к тому - хочеться посмотреть на реализацию решения батарейного устройства на 500 часов.
Ну тут опыта маловасто..
1.На борту 2 шт 18b20, во сне я так понимаю тоже кушают.
почти ничего - доли микроампер. На фоне остального можно забить, я в мобильном термометре ds18b20 не отключаю - батарейки хватает на год
гасите питание
попробовать рвать GND ?
я к тому - хочеться посмотреть на реализацию решения батарейного устройства на 500 часов.
ТС пишет не про часы работы, а часы сна. Разорвать питание LCD и модема совсем - в чем проблема проспать 500 часов?
я к тому - хочеться посмотреть на реализацию решения батарейного устройства на 500 часов.
ТС пишет не про часы работы, а часы сна. Разорвать питание LCD и модема совсем - в чем проблема проспать 500 часов?
это да, согласен, только если понадобиться срочно связаться с устройством - не получиться, впрочем все зависит от задачи.
Разорвать питание модема совсем - в чем проблема проспать 500 часов?
Рву плюс модема. Продолжает гореть светик. По RX-TX питание получает? Softserial (8,9).
Как там перекрыть кислород? тьфу ты..питание?
хм..
тогда будет питание постоянно подаваться. Запитано то не с МК. А отдельно.
тогда будет питание постоянно подаваться. Запитано то не с МК. А отдельно.
у вас должно быть общая земля у модема и ардуины. Вот от этой общей земли модем и отключайте
у вас должно быть общая земля у модема и ардуины. Вот от этой общей земли модем и отключайте
Земля естественно общая.
Спасибо. Буду эксперементировать.
Разорвать питание модема совсем - в чем проблема проспать 500 часов?
Рву плюс модема. Продолжает гореть светик. По RX-TX питание получает? Softserial (8,9).
Как там перекрыть кислород? тьфу ты..питание?
перед сном добрые люди все порты в Z-state переключают.
перед сном добрые люди все порты в Z-state переключают.
мм..что это и как?
перед сном добрые люди все порты в Z-state переключают.
мм..что это и как?
режим входа пина без подтягивающего резистора
digitalWrite(pin,LOW);pinMode(pin,INPUT);
Даже те, которые output?
конечно, а потом после сна опять все пины конфигурировать заново.
ЗЫ. ну конечно надо еще смотреть вдруг по вашей задачи на каком то пине обязательно должна быть 1 или 0.
Это вам не это... (с)
Конечно нужна 1. Релейный модуль стоит, он когда 1-выключен. Или...или питание на него тоже рвать..хм..
Как думаете, прокатит?
Сейчас еще еду в метро, посему только теория.
я бы не использовал реле, которое по логике/схеме должно быть обязательно запитано(управлялось) логическим уровнем от МК. Т.е. менять всю логику работы устройства, МК должен "рулить" всем, а во время сна должно все работать без команд.
Так перед уходом в сон реле выключаются, МК и так рулит процессом. Пока МК спит все должно быть выключено. Мк просыпается когда подается внешнее питание и перевоодит контакты релюх в соответствии с поставленной задачей до отключения. Модули релюх такие просто, что управляются нулем.
А ниче что в 19 сообщении реле управляется 1
Вы уж определитесь как надо, да и схему бы нарисовали - было бы понятнее.
Не...может не так выразился.
Когда на пине 1 реле выключено.
Если я на сон на всех пинах сделаю 0, то реле включится.
Мне надо чтоб во сне там оставалась 1.
меняй (или добавь еще один) транзистор в релейном модуле и инвертируй сигнал управления
Ноль и z состояние - это немного разные вещи, поэтому если вы переведёте пин в режим входа, не факт что реле включится. Почитайте уже литературу.
модем и лсд в итоге релюшкой рву gnd.
во время сна модуль стал кушать около 13 мА. по моему показометру.
модем и лсд в итоге релюшкой рву gnd.
во время сна модуль стал кушать около 13 мА. по моему показометру.
Много
Перевел половину пинов в input-low. При спячке стал кушать 18-19 mA.
Т.е. Увеличилось.
Половину-это те, которые сам инициализирую.
Остались по два пина на softserial, lcd i2c, и один на Dallas по wire.
Ну и несколько пустых не задействованных.
Вопрос, есть функция для опроса состояния портов?
В цикле по всем пройтись считать состояние. А после пробуждения вернуть как было?
Или проще можно?
вопрошу, АЦП отключаешь при уходе вспячку?
1. как уже советовали выше - откусить все светодиоды на плате. В идеале еще бы стабилизатор и переходник/конвертер usb.
2. как в сон уходите? АЦП отключен (выше уже спрашивали) ? мы так и не видели скетч
3. вот типичный скетч для ухода в сон
#include <avr/sleep.h> #include <avr/interrupt.h> #define KEYPIN 2 // wakeup pin to GND INT0 void wakeUp() { sleep_disable(); detachInterrupt(0); } void setup() { // put your setup code here, to run once: pinMode(KEYPIN, INPUT); // wakeup pin to GND digitalWrite(KEYPIN, HIGH); // up resistor to on // OFF unused pins for (byte i = 0; i <= 19; i++) { if (i == KEYPIN) { continue; } pinMode (i, UNPUT); // changed as per below digitalWrite (i, LOW); // ditto } // Flash quick sequence so we know setup has started for (int k = 0; k < 10; k = k + 1) { if (k % 2 == 0) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } delay(250); } // for } void sleep() { // disable ADC ADCSRA = 0; // sleep set_sleep_mode (SLEEP_MODE_PWR_DOWN); sleep_enable(); // turn off brown-out enable in software MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); // interrupt attachInterrupt(0, wakeUp, LOW); sleep_mode(); //Спим (Прерывания продолжают работать.) Программа останавливается. } // sleep void loop() { // put your main code here, to run repeatedly: sleep(); digitalWrite(LED_BUILTIN, HIGH); delay(2000); digitalWrite(LED_BUILTIN, LOW); }4. я конечно не уверен что правильно, но обычно отключаю все без исключения пины.
вот кстати откопал код температурного автономного датчика (на attiny85), там все не используемые пины наоборот переводяться в выходное состояние и ноль - тоже допускается, кроме пина DS18B20 - он в INPUT и LOW. И если я правильно помню сделал это как раз для минимального потребления - пол года от одной китайской CR2032 на улице.
#include <avr/sleep.h> #include <avr/wdt.h> #include <avr/io.h> #include <util/delay.h> /* for _delay_us() */ #define periodusec 400 // mcs #define DS_BIT 4 // pin 3 #define RC_BIT 3 // pin 2 #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif // PB0 pin 5 #define PB0_OUT sbi(DDRB,PB0) #define PB0_LOW cbi(PORTB,PB0) // PB1 pin 6 - EN pin RFunit WL118 #define PB1_OUT sbi(DDRB,PB1) #define PB1_HIGH sbi(PORTB,PB1) #define PB1_LOW cbi(PORTB,PB1) // PB2 pin 7 #define PB2_OUT sbi(DDRB,PB2) #define PB2_LOW cbi(PORTB,PB2) // PB3 pin 2 #define PB3_OUT sbi(DDRB,PB3); #define PB3_LOW cbi(PORTB,PB3); // PB4 pin 3 #define PB4_OUT sbi(DDRB,PB4) #define PB4_IN cbi(DDRB,PB4) #define PB4_HIGH sbi(PORTB,PB4) #define PB4_LOW cbi(PORTB,PB4) #define TimerCountSec 1027 // ~17min delay start by sec word CurrentTime = 0; void ExecFunc() { unsigned long delp = millis(); while ((millis() - delp) <= 300); // установка режима для ds DDRB |= _BV(DS_BIT); PORTB &= ~_BV(DS_BIT); DDRB &= ~_BV(DS_BIT); // get temp and send PB1_OUT; PB1_HIGH; // ON RF unit word TReading = GetThreeTemp(); if (TReading > (word)0) sendRC((unsigned long)(TReading + (word)11500)); // отправляем данные // OFF pins OneWireReset(); PB0_OUT; PB0_LOW; PB1_OUT; PB1_LOW; PB2_OUT; PB2_LOW; PB3_OUT; PB3_LOW; PB4_IN; PB4_LOW; } word GetThreeTemp() { word result = 0; unsigned long delp = millis(); while ((millis() - delp) <= 300); result = GetTemp(); if (result == (word)0) { delp = millis(); while ((millis() - delp) <= 600); result = GetTemp(); if (result == (word)0) { delp = millis(); while ((millis() - delp) <= 900); result = GetTemp(); } } return result; } void CalcTimer() { ++CurrentTime; if (((CurrentTime + 1UL) * 8UL) >= TimerCountSec) { CurrentTime = 0; ExecFunc(); } } ISR (WDT_vect) { wdt_disable(); // disable watchdog } void setup () { // OFF pins PB0_OUT; PB0_LOW; PB1_OUT; PB1_LOW; PB2_OUT; PB2_LOW; PB3_OUT; PB3_LOW; PB4_IN; PB4_LOW; unsigned long delp = millis(); while ((millis() - delp) <= 1000); // pause for enable all device and get temp to clock // first run ExecFunc(); delp = millis(); while ((millis() - delp) <= 4000); // pause for enable all device and get temp to clock // second run ExecFunc(); // for exactly get temp } void loop () { CalcTimer(); cbi(ADCSRA, ADEN); // switch Analog to Digitalconverter OFF setup_watchdog(9); wdt_reset(); // pat the dog set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // timed sequence follows sleep_enable(); sleep_bod_disable(); interrupts (); // guarantees next instruction executed sleep_cpu (); // cancel sleep as a precaution sleep_disable(); } // 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms // 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec void setup_watchdog(int ii) { byte bb; int ww; if (ii > 9 ) ii = 9; bb = ii & 7; if (ii > 7) bb |= (1 << 5); bb |= (1 << WDCE); ww = bb; MCUSR &= ~(1 << WDRF); // start timed sequence WDTCR |= (1 << WDCE) | (1 << WDE); // set new watchdog timeout value WDTCR = bb; WDTCR |= _BV(WDIE); } void sendRC(unsigned long data) { // Отправка данных по радиоканалу RCswitch. Двоичный протокол DDRB |= _BV(RC_BIT); data |= 3L << 20; // ? unsigned short repeats = 1 << (((unsigned long)data >> 20) & 7); data = data & 0xfffff; unsigned long dataBase4 = 0; uint8_t i; for (i = 0; i < 20; i++) { dataBase4 <<= 1; dataBase4 |= (data % 2); data /= 2; } unsigned short int j; for (j = 0; j < repeats; j++) { data = dataBase4; uint8_t i; for (i = 0; i < 20; i++) { switch (data & 1) { case 0: PORTB |= _BV(RC_BIT); _delay_us(periodusec); PORTB &= ~_BV(RC_BIT); _delay_us(periodusec * 3); break; case 1: PORTB |= _BV(RC_BIT); _delay_us(periodusec * 3); PORTB &= ~_BV(RC_BIT); _delay_us(periodusec); break; } data >>= 1; } PORTB |= _BV(RC_BIT); _delay_us(periodusec); PORTB &= ~_BV(RC_BIT); _delay_us(periodusec * 31); } } // OneWire функции: void OneWireReset() { PORTB &= ~_BV(DS_BIT); DDRB |= _BV(DS_BIT); _delay_us(500); DDRB &= ~_BV(DS_BIT); _delay_us(500); } void OneWireOutByte(uint8_t d) { uint8_t n; for (n = 8; n != 0; n--) { if ((d & 0x01) == 1) { PORTB &= ~_BV(DS_BIT); DDRB |= _BV(DS_BIT); _delay_us(5); DDRB &= ~_BV(DS_BIT); _delay_us(60); } else { PORTB &= ~_BV(DS_BIT); DDRB |= _BV(DS_BIT); _delay_us(60); DDRB &= ~_BV(DS_BIT); } d = d >> 1; } } uint8_t OneWireInByte() { uint8_t d, n, b; for (n = 0; n < 8; n++) { PORTB &= ~_BV(DS_BIT); DDRB |= _BV(DS_BIT); _delay_us(5); DDRB &= ~_BV(DS_BIT); _delay_us(5); b = ((PINB & _BV(DS_BIT)) != 0); _delay_us(50); d = (d >> 1) | (b << 7); } return (d); } word GetTemp() { uint8_t DSdata[2]; OneWireReset(); OneWireOutByte(0xcc); OneWireOutByte(0x44); PORTB |= _BV(DS_BIT); DDRB |= _BV(DS_BIT); unsigned long delp = millis(); while ((millis() - delp) <= 1000); //_delay_ms(1000); // если хотим ждать когда датчик посчитает температуру. DDRB &= ~_BV(DS_BIT); PORTB &= ~_BV(DS_BIT); OneWireReset(); OneWireOutByte(0xcc); OneWireOutByte(0xbe); DSdata[0] = OneWireInByte(); DSdata[1] = OneWireInByte(); word TReading = (word)(DSdata[1] << 8) + DSdata[0]; if ((word)(TReading & 0x8000) == (word)(0x8000)) { TReading = (~TReading) + (word)1; TReading = (((word)6 * TReading) + TReading / (word)4) / (word)10; } else { TReading = (((word)6 * TReading) + TReading / (word)4) / (word)10 + (word)2000; } return TReading; }вопрошу, АЦП отключаешь при уходе вспячку?
при потреблении 18мА - совершенно бессмысленное действие.
Отключение ADC на Атмеге328 дает экономию 100мкА, отключение BOD - 20мкА, из чего явно следует, что отключать их имеет смысл, когда ТС понизит потребление своего девайса еще как минимум раз в 100
при потреблении 18мА - совершенно бессмысленное действие.
Отключение ADC на Атмеге328 дает экономию 100мкА, отключение BOD - 20мкА, из чего явно следует, что отключать их имеет смысл, когда ТС понизит потребление своего девайса еще как минимум раз в 100
Да, я согласно.
wdt_enable(WDTO_8S); WDTCSR |= (1 << WDIE); set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_mode();Ухожу спать так.
wdt_enable(WDTO_8S); WDTCSR |= (1 << WDIE); set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_mode();Ухожу спать так.
18мА потребления - это никакой не сон. Или у вас куча периферии остается включенной. Сама Атмега во сне жрет максимум 1мА. Ищите, куда уходят еще 17