может кто подскажет ка еще можно снизить энергопотребление

kayot
kayot аватар
Offline
Зарегистрирован: 11.04.2014

собрал часы

атмега на 8мгц без кварца DS1339 часы OLED 0.96

на данный момент в спячке потребляет 55 мампер

конроллер в с пячке и в олед отключаю преобразователь 12в

чем мжно еще сбросить может подскажите


#include <Sleep_n0m1.h>
#include <Wire.h>
#include "RTClib.h"
#include <OLED_I2C.h>         // Подключение библиотеки для дисплея

OLED  myOLED(SDA, SCL);    

Sleep sleep;
int count = 0;
unsigned long sleepTime;

extern uint8_t MediumNumbers[]; // Подключение больших шрифтов
extern uint8_t MegaNumbers[];
extern uint8_t RusFont[];       // Подключение русских шрифтов
extern uint8_t BigNumbers[];
extern uint8_t SmallFont[];
extern uint8_t TinyFont[];// Подключение маленьких шрифтов

RTC_DS1307 rtc;
int Vcc ;




void setup () {
 
  Wire.begin();
  myOLED.begin();
  rtc.begin();
 
 //время спячки
  sleepTime = 5000000000;
  myOLED.clrScr();
   
  }
  

void print_time () {
  //вывод символов на дисплей//

 DateTime now = rtc.now();

// Установка большого шрифта
      myOLED.setFont(BigNumbers);
// отображение часов
    if (now.hour() < 10) {                      // если число меньше 10
      myOLED.print("0", 0, 22);           // первый знак будет 0 (01)
      myOLED.printNumI(now.hour(), 16, 22);
    }
    else {
      myOLED.printNumI(now.hour(), 0, 22);
    }
      myOLED.print(".", 30, 20);    // Выводим ":"
    
// Отображение минут
    if (now.minute() < 10) {                      // если число меньше 10
      myOLED.print("0", 45, 22);           // первый знак будет 0 (01)
      myOLED.printNumI(now.minute(), 60, 22);
    }
    else {
      myOLED.printNumI(now.minute(), 45, 22);
    }

// Отображение секунд
// Установка маленького шрифта
      myOLED.setFont(SmallFont);
      myOLED.print(":", 76, 40);            // Выводим ":"
      myOLED.setFont(MediumNumbers);
    if (now.second() < 10) {                       // если число меньше 10
      myOLED.print("0", 84, 30);          // первый знак будет 0 (01)
      myOLED.printNumI(now.second(), 95, 30);
    }else {
      myOLED.printNumI(now.second(), 84, 30);
    }
 

// Отображение дня
      myOLED.setFont(MediumNumbers);
    if (now.day() < 10) {                       // если число меньше 10
      myOLED.print("0", 0, 0);          // первый знак будет 0 (01)
      myOLED.printNumI(now.day(), 11, 0);
    }else {
      myOLED.setFont(MediumNumbers);
      myOLED.printNumI(now.day(), 0, 0);
    }

// Отображение месяца
      myOLED.setFont(RusFont);
    switch (now.month())
    {
      case 1:     myOLED.print("ZYDFHM", 30, 0);    break;   //Январь
      case 2:     myOLED.print("ATDHFKM", 30, 0);    break;   //Февраль
      case 3:     myOLED.print("VFHN", 30, 0);    break;   //Март
      case 4:     myOLED.print("FGHTKM", 30, 0);    break;   //Апрель
      case 5:     myOLED.print("VFQ", 30, 0);    break;   //Май
      case 6:     myOLED.print("B>YM", 30, 0);    break;   //Июнь
      case 7:     myOLED.print("B>KM", 30, 0);    break;   //Июль
      case 8:     myOLED.print("FDUECN", 30, 0);    break;   //Август
      case 9:     myOLED.print("CTYNZ<HM", 30, 0);    break;   //Сентябрь
      case 10:    myOLED.print("JRNZ<HM", 30, 0);    break;   //Октябрь
      case 11:    myOLED.print("YJZ<HM", 30, 0);    break;   //Ноябрь
      case 12:    myOLED.print("LTRF<HM", 30, 0);    break;   //Декабрь
      }   
    
      myOLED.setFont(RusFont);
      myOLED.print("UJL", LEFT, 57);              // Выводим "Год"
// Отображение года
      myOLED.setFont(MediumNumbers);
      myOLED.printNumI(now.year(), 25, 48);

// Отображение дня недели
      myOLED.setFont(RusFont);
    switch (now.dayOfWeek())
    {
      case 1:     myOLED.print("GJYTLTKMYBR", 30, 10);    break;   //Понедельник
      case 2:     myOLED.print("DNJHYBR", 30, 10);    break;   //Вторник
      case 3:     myOLED.print("CHTLF", 30, 10);    break;   //Среда
      case 4:     myOLED.print("XTNDTHU", 30, 10);    break;   //Четверг
      case 5:     myOLED.print("GZNYBWF", 30, 10);    break;   //Пятница
      case 6:     myOLED.print("CE<<JNF", 30, 10);    break;   //Суббота
      case 7:     myOLED.print("DJCRHTCTYMT", 30, 10);    break;   //Воскресенье
    }

   //Температура
      myOLED.setFont(SmallFont); 
      myOLED.print("C", 117, 2);
      myOLED.setFont(TinyFont);
      myOLED.print("o", 124, 0);
      myOLED.setFont(SmallFont);
      myOLED.printNumI(GetTemp()-5, 105, 2);
      myOLED.update();   
    
// Обновление дисплея
      myOLED.update();
  
 //установка времени с порта сом
}
void set_times_data()
  {
      rtc.adjust(DateTime(__DATE__, __TIME__)); 
  }
//отбражение напряжения батареи
void bat(){
   
    float Vcc = 0.0;
uint16_t adx;

delay(10);

adx=0;
for (byte i = 0; i< 10; i++)
 {
  ADMUX = 0b01011110; //ref ext, adr, 1.1V src
  delay(1);
  ADCSRA |= (1<<ADSC);
  while (ADCSRA & (1<<ADSC));

  adx += ADC;
 }
Vcc = 11400.0/adx;
   
      myOLED.setFont(RusFont); 
      myOLED.print("<FN", 83, 57);
      myOLED.setFont(SmallFont);
      myOLED.printNumF(Vcc, 2, RIGHT, 57);
      myOLED.update();
  }
//замер тепературы
double GetTemp(void)
{
  unsigned int wADC;
  double t;

  // The internal temperature has to be used
  // with the internal reference of 1.1V.
  // Channel 8 can not be selected with
  // the analogRead function yet.
  // Set the internal reference and mux.
  ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
  ADCSRA |= _BV(ADEN);  // enable the ADC

  delay(20);            // wait for voltages to become stable.

  ADCSRA |= _BV(ADSC);  // Start the ADC

  // Detect end-of-conversion
  while (bit_is_set(ADCSRA,ADSC));

  // Reading register "ADCW" takes care of how to read ADCL and ADCH.
  wADC = ADCW;

  // The offset of 324.31 could be wrong. It is just an indication.
  t = (wADC - 324.31 ) / 1.22;

  // The returned temperature is in degrees Celsius.
  return (t);
}
//уладка в спящий режим экрана
void offscreen() {  
  
    Wire.beginTransmission(0x3c);
    Wire.write(0xAE);
    Wire.write(0x8D);
    Wire.write(0x10);
    Wire.endTransmission();
  
}

void loop()
{
 
 print_time ();
 //  set_times_data();
 bat();

//укладка в сапящий режим контроллера
 count++;
  delay(1000);                           // waits for a second
  
  if(count >= 10)
  {
    count = 0;
 
   offscreen();
  
   
      myOLED.clrScr();
      myOLED.update();
   delay(100); //delay to allow serial to fully print before sleep  
     sleep.pwrDownMode(); //set sleep mode
     sleep.sleepDelay(sleepTime); //sleep for: sleepTime
}

}

 

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

55мА?! Я б не удивился, если это был бы рабочий ток, но для спячки ОЧЕНЬ много!

Как организовано питание?

kayot
kayot аватар
Offline
Зарегистрирован: 11.04.2014

напрямую от аккумы

я точно не смог замерить аккума на 150 ма час  часы седают за 18 часов 1 вольт

остальное программно отключается

я вот думаю может от пинов запитать дисплей?

и часы?

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

Yarik.Yar пишет:

55мА?! Я б не удивился, если это был бы рабочий ток, но для спячки ОЧЕНЬ много!

Как организовано питание?

Думаю, что начинать надо с программы. Скетч. похоже, написан методом копи-пасте. Что вижу с ходу - в строке 224 мы отправляем дисплей в спячку и следующей строкой шлем на него команды.

Да и sleepTime = 5000000000; меня как-то смущает. Это в каких единицах? Похоже, что переход в спящий режим вообще не отрабатывается.

kayot
kayot аватар
Offline
Зарегистрирован: 11.04.2014

спать почти год 315 дней

 выход по сбросу из спячки

забыл ремки поставить )))

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

kayot пишет:

спать почти год 315 дней

 

sleepTime = 5000000000; - превышает максимальный размер unsigned long

Кроме того, аппаратные таймеры ардуино обнуляются через примерно 50 дней, не знаю, правда, относится ли это к библиотеке Sleep_n0m1.h

 

kayot
kayot аватар
Offline
Зарегистрирован: 11.04.2014

это не сильно важно склько он спит сутки- год.

важно чтобы  батарейку на 150 ма-час как можно дольше юзал.

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

kayot пишет:

это не сильно важно склько он спит сутки- год.

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

kayot
kayot аватар
Offline
Зарегистрирован: 11.04.2014

так мне не нужно чтоб он просыпался сам

мне как раз и нужно чтобы по кнопке ресет просыпался

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

Есть несложная схема на двух транзисторах, позволяющая МК самому чебе отключать питание и включать его по кнопке, даже у нас на форуме было...я впервые тут увидел http://avrproject.ru/publ/poleznaja_informacija/upravlenie_pitaniem_ustrojstva_odnoj_knopkoj/4-1-0-177 .

kayot
kayot аватар
Offline
Зарегистрирован: 11.04.2014

я уже тут подумал может поставить на питание кнопку

нажал посмотрел

а внутренние часики от бекапной батарейки тикают

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

kayot пишет:

так мне не нужно чтоб он просыпался сам

Дело то не в том, как ему просыпаться - а в том. что он у тебя вообще не засыпает. И для начала надо очевидные ошибки исправить - неправильный формат таймаута., то что ты дисплей дергаешь после перехода в сон - и тд

kayot
kayot аватар
Offline
Зарегистрирован: 11.04.2014

контроллер дисплея не во сне у него только помпа выключена а сам он работает

я прикинул потребление примерно 8-9 ма в спячке если он за 18 часов 150 мачас батарейку съедает

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

Если я не ошибаюсь, это можно (при текущих компонентах) свести до нескольких десятков (максимум сотен) наноампер. МК - в PowerDown, дисплей выключить, с часов снять основное питание (чтобы от батарейки питались).

kayot
kayot аватар
Offline
Зарегистрирован: 11.04.2014

кнопка по питанию помогла ))))