Nano+neoway590+lcd1602: вопрос по снижению электропотребления.

Emer
Offline
Зарегистрирован: 02.11.2016

Приветствую!
Делаю проект, питается от сети, при пропадании переключается на аккумулятор и уходит в сон.
По сторожу просыпается, проверяет напряжение, если не появилось-спит дальше.
Можно было бы и без сна, вырубилось и все. Но надо сохранять настройки. Можно писать их в eeprom, но опять же, надо чтоб в режиме когда нет питания, все же иногда чтото выполняла.
Но вопрос не в этом. Это все работает и отлажено.
Вопрос в питании.
Все рабочие пины перед уходом в сон выключаю. Кроме...
Модем сидит на софтсериале(8,9), лсд через i2c.
На них продолжают гореть светодиоды.
При том, что модем вообще питается через релюшку, которая прерывает питание. А лсд если рубить питание, то заново не инициализируется.
Что делать? Как вырубить эти два светика?
Паяльник не предлагать

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Без паяльника - никак. Или рвать питание и заново инициализировать

b707
Offline
Зарегистрирован: 26.05.2017

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

Emer
Offline
Зарегистрирован: 02.11.2016

Даже в такой связке, на 1000 мА акке приблуда живет во сне 7-8 часов. Хотел растянуть на часов 30. больше не надо. Это запроектированный максимум.

С паяльником дружу, но это крайний вариант. Как минимум думал светики с переферии (Модем и экран) как то погасить программно.

Одного отключения питания мало.

 

b707
Offline
Зарегистрирован: 26.05.2017

Emer пишет:

Даже в такой связке, на 1000 мА акке приблуда живет во сне 7-8 часов.

ахренеть... потребление 140мА*ч ????

Даже без применения паяльника должна жить раз в 5 дольше. А при минимальном применении паяльника 500 часов можно получить запросто.

Emer
Offline
Зарегистрирован: 02.11.2016

b707 пишет:

ахренеть... потребление 140мА*ч ????

Даже без применения паяльника должна жить раз в 5 дольше. А при минимальном применении паяльника 500 часов можно получить запросто.

Ну тут опыта маловасто..

1.На борту 2 шт 18b20, во сне я так понимаю тоже кушают. Пины  в 0 опускаь? Как потом заново запускаться?

2. LCD  получается тоже продолжает кушать

3.Модем  хоть и рвется питание, но по RX-TX питание уходит.

 

такс..

пока тайм аут. потестирую.

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

модем 590 не щупал, а вот sim800l+MK до 2мА потребление доводил.

но тут такая бяка получается: хоть устройство и предополагалось батарейное, но модем все равно просыпался от разного чиха (СМС, звонок и прочее), пришлось сделать логику - каждые 30 минут просыпаться, проверять СМС и опять засыпать. Примерно прикинул - от аккумулятора 2500 мА 18650 максимум неделя работы.

я к тому - хочеться посмотреть на реализацию решения батарейного устройства на 500 часов.

b707
Offline
Зарегистрирован: 26.05.2017

Emer пишет:

Ну тут опыта маловасто..

1.На борту 2 шт 18b20, во сне я так понимаю тоже кушают.

почти ничего - доли микроампер. На фоне остального можно забить, я в мобильном термометре ds18b20 не отключаю - батарейки хватает на год

Цитата:
2. LCD  получается тоже продолжает кушать

гасите питание

Цитата:
3.Модем  хоть и рвется питание, но по RX-TX питание уходит.

попробовать рвать GND ?

 

b707
Offline
Зарегистрирован: 26.05.2017

andycat пишет:

я к тому - хочеться посмотреть на реализацию решения батарейного устройства на 500 часов.

ТС пишет не про часы работы, а часы сна. Разорвать питание LCD и модема совсем - в чем проблема проспать 500 часов?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

b707 пишет:

andycat пишет:

я к тому - хочеться посмотреть на реализацию решения батарейного устройства на 500 часов.

ТС пишет не про часы работы, а часы сна. Разорвать питание LCD и модема совсем - в чем проблема проспать 500 часов?

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

Emer
Offline
Зарегистрирован: 02.11.2016

b707 пишет:

Разорвать питание  модема совсем - в чем проблема проспать 500 часов?

Рву плюс модема. Продолжает гореть светик. По RX-TX питание получает? Softserial (8,9).

Как там перекрыть кислород? тьфу ты..питание?

Emer
Offline
Зарегистрирован: 02.11.2016

b707 пишет:
попробовать рвать GND ?

хм..

тогда будет питание постоянно подаваться. Запитано то не с МК. А отдельно.

b707
Offline
Зарегистрирован: 26.05.2017

Emer пишет:

тогда будет питание постоянно подаваться. Запитано то не с МК. А отдельно.

у вас должно быть общая земля у модема и ардуины. Вот от этой общей земли модем и отключайте

Emer
Offline
Зарегистрирован: 02.11.2016

b707 пишет:

у вас должно быть общая земля у модема и ардуины. Вот от этой общей земли модем и отключайте

Земля естественно общая.

Спасибо. Буду эксперементировать.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Emer пишет:

b707 пишет:

Разорвать питание  модема совсем - в чем проблема проспать 500 часов?

Рву плюс модема. Продолжает гореть светик. По RX-TX питание получает? Softserial (8,9).

Как там перекрыть кислород? тьфу ты..питание?

перед сном добрые люди все порты в Z-state переключают.  

Emer
Offline
Зарегистрирован: 02.11.2016

DetSimen пишет:

перед сном добрые люди все порты в Z-state переключают.  

мм..что это и как?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Emer пишет:

DetSimen пишет:

перед сном добрые люди все порты в Z-state переключают.  

мм..что это и как?

режим входа пина без подтягивающего резистора

digitalWrite(pin,LOW);pinMode(pin,INPUT);

Emer
Offline
Зарегистрирован: 02.11.2016

Даже те, которые output?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Emer пишет:
Даже те, которые output?

конечно, а потом после сна опять все пины конфигурировать заново.

ЗЫ. ну конечно надо еще смотреть вдруг по вашей задачи на каком то пине обязательно должна быть 1 или 0.

Это вам не это... (с)

Emer
Offline
Зарегистрирован: 02.11.2016

Конечно нужна 1. Релейный модуль стоит, он когда 1-выключен. Или...или питание на него тоже рвать..хм..
Как думаете, прокатит?
Сейчас еще еду в метро, посему только теория.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Emer пишет:
Как думаете, прокатит?

я бы не использовал реле, которое по логике/схеме должно быть обязательно запитано(управлялось) логическим уровнем от МК. Т.е. менять всю логику работы устройства, МК должен "рулить" всем, а во время сна должно все работать без команд.

Emer
Offline
Зарегистрирован: 02.11.2016

Так перед уходом в сон реле выключаются, МК и так рулит процессом. Пока МК спит все должно быть выключено. Мк просыпается когда подается внешнее питание и перевоодит контакты релюх в соответствии с поставленной задачей до отключения. Модули релюх такие просто, что управляются нулем.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

А ниче что в 19 сообщении реле управляется 1

Вы уж определитесь как надо, да и схему бы нарисовали - было бы понятнее.

Emer
Offline
Зарегистрирован: 02.11.2016

Не...может не так выразился.
Когда на пине 1 реле выключено.
Если я на сон на всех пинах сделаю 0, то реле включится.
Мне надо чтоб во сне там оставалась 1.

gfx125
Offline
Зарегистрирован: 27.05.2017

Emer пишет:
Не...может не так выразился. Когда на пине 1 реле выключено. Если я на сон на всех пинах сделаю 0, то реле включится. Мне надо чтоб во сне там оставалась 1.

меняй (или добавь еще один) транзистор в релейном модуле и инвертируй сигнал управления

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

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

Emer
Offline
Зарегистрирован: 02.11.2016

модем и лсд в итоге релюшкой рву gnd.

во время сна модуль стал кушать около 13 мА. по моему показометру.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Emer пишет:

модем и лсд в итоге релюшкой рву gnd.

во время сна модуль стал кушать около 13 мА. по моему показометру.


Много

Emer
Offline
Зарегистрирован: 02.11.2016

Перевел половину пинов в input-low. При спячке стал кушать 18-19 mA.
Т.е. Увеличилось.
Половину-это те, которые сам инициализирую.
Остались по два пина на softserial, lcd i2c, и один на Dallas по wire.

Ну и несколько пустых не задействованных.
Вопрос, есть функция для опроса состояния портов?
В цикле по всем пройтись считать состояние. А после пробуждения вернуть как было?
Или проще можно?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

вопрошу, АЦП отключаешь при уходе вспячку? 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

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. я конечно не уверен что правильно, но обычно отключаю все без исключения пины.

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

вот кстати откопал код температурного автономного датчика (на 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;
}

 

b707
Offline
Зарегистрирован: 26.05.2017

DetSimen пишет:

вопрошу, АЦП отключаешь при уходе вспячку? 

при потреблении 18мА - совершенно бессмысленное действие.

Отключение ADC на Атмеге328 дает экономию 100мкА, отключение BOD - 20мкА, из чего явно следует, что отключать их имеет смысл, когда ТС понизит потребление своего девайса еще как минимум раз в 100

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

b707 пишет:

при потреблении 18мА - совершенно бессмысленное действие.

Отключение ADC на Атмеге328 дает экономию 100мкА, отключение BOD - 20мкА, из чего явно следует, что отключать их имеет смысл, когда ТС понизит потребление своего девайса еще как минимум раз в 100

Да, я согласно. 

Emer
Offline
Зарегистрирован: 02.11.2016
      wdt_enable(WDTO_8S); 
      WDTCSR |= (1 << WDIE);
      set_sleep_mode(SLEEP_MODE_PWR_DOWN); 
      sleep_mode();

Ухожу спать так.

b707
Offline
Зарегистрирован: 26.05.2017

Emer пишет:

      wdt_enable(WDTO_8S); 
      WDTCSR |= (1 << WDIE);
      set_sleep_mode(SLEEP_MODE_PWR_DOWN); 
      sleep_mode();

Ухожу спать так.

18мА потребления - это никакой не сон. Или у вас куча периферии остается включенной. Сама Атмега во сне жрет максимум 1мА. Ищите, куда уходят еще 17