Watchdog на час

AKOTb
Offline
Зарегистрирован: 24.01.2017

Всем доброго времени суток. Начал работу над датчиком влажности для комнатных растений, и для снижения энергопотребления решил отправлять ардуинку в сон, потому как замерять влажность чаще 5-10 раз в день не нужно. Все здорово, ардуинка уснула, но как уу будить? Первое что подвернулось под руку - watchdog, но максимальное время для работы вотчдога 8с, далее он перезагружает всю программу. Мне хотелось бы увеличить это время раз в 450. Логично подумать что просыпаясь программа должна считывать состояние некой переменной, и если она не достигла 450, то снова спать. Но ведь вотчдог резетит всю программу, переменные стираются, или нет?

#include <avr/wdt.h>                                // здесь организована работа с ватчдогом
#include <avr/sleep.h>                              // здесь описаны режимы сна

int a;

void setup()
{

//инициализация ватчдога
wdt_reset();                                                  // сбрасываем
wdt_enable(WDTO_8S);                                // разрешаем ватчдог 8 сек
        
set_sleep_mode(SLEEP_MODE_PWR_DOWN);                // если спать - то на полную

}

void loop()
{
  
if (a > 5)
{
основная программа  
}

a = a + 1;
sleep_enable(); // разрешаем сон
sleep_cpu(); // спать!

}

Вот так я вижу этот алгоритм в виде кода, но он не работает. При старте программы вотч дог теоретически должен сбросить контролллер 5 раз, затем дать программе выполнить свою работу и снова 5 сбросов. Но каждый раз после резета переменная "a" забывается, и резет идет постоянно.

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

AKOTb
Offline
Зарегистрирован: 24.01.2017

Я вроде бы нигде и не писал что watchdog для засыпания. Watchdog для просыпания. Мне нужно будить контроллер по внутреннему таймеру. 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

AKOTb пишет:

Я вроде бы нигде и не писал что watchdog для засыпания. Watchdog для просыпания. Мне нужно будить контроллер по внутреннему таймеру. 

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

а) включаем контроллер раз в 8 секунд и совершаем один loop

б) включаем контроллер раз в 4 часа и совершаем один loop

 

AKOTb
Offline
Зарегистрирован: 24.01.2017

Длительность цикла loop программы около 5 секунд, в него входит считывание влажности с датчика и вывод его на дисплей. Повторный замер влажности будет необходим только через час, или более, все остальное время контроллер не нужен.

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

вотчдог можно сделать двухступенчатым.  Сначала он может генерить прерывание, а потом перезагружать систему. 

AKOTb
Offline
Зарегистрирован: 24.01.2017

DetSimen пишет:

вотчдог можно сделать двухступенчатым.  Сначала он может генерить прерывание, а потом перезагружать систему. 

Можно подробнее? Не совсем понимаю пока

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

AKOTb пишет:

Можно подробнее? Не совсем понимаю пока

Можно и подробнее.  http://avrprog.blogspot.ru/2013/03/watchdog.html

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

и там же, с примерами http://avrprog.blogspot.ru/2013/03/watchdogc.html

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

AKOTb пишет:

Длительность цикла loop программы около 5 секунд

ты не предположения делай, а замерь и опубликуй реальный результат, потому как, если у тебя loop длится 5 секунд, то остаётся убиться ап стену.

AKOTb
Offline
Зарегистрирован: 24.01.2017

Спасибо DetSimen. Вроде бы разобрался, все получилось. Усыпил мк на пол часа.

Объявил функцию для вотчдога

void myWatchdogEnable(const byte interval) 
  {  
  MCUSR = 0;                                      
  WDTCSR |= 0b00011000;                           
  WDTCSR =  0b01000000 | interval;                
  wdt_reset();
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  sleep_mode();                                  
  }
 
вызываю функцию строкой
 myWatchdogEnable (0b100001);
где значение в скобках 
0b000110 - 1 секунда
0b000111 - 2 секунды
0b100000 - 4 секунды
0b100001 - 8 секунд.

 

gena
Offline
Зарегистрирован: 04.11.2012

  Ещё можно применить RC цепочку с большой постоянной времени и по прерыванию на выводе будить МК.

hemicide
Offline
Зарегистрирован: 05.12.2018

Пытаюсь так-же как и ТС увеличить время ожидания watchdog'a, но так и не понял каким образом удалось усыпить МК на пол часа, если предложенная ТС функция просто перезапускает watchdog и устанавливает ей таймер на 8с. Где эта функция вызываться должна? В основном цикле программы? По подробнее расскажите пожалуйста.

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

Каждые 8 секунд МК просыпается, счётчик /переменная увеличивается, если сумма секунд превысит нужное количество минут, то включается нужный код, если нет - опять засыпать. В теме attiny есть конкретные примеры реальных устройств, если не найдёте - в пн скину ссылку.

hemicide
Offline
Зарегистрирован: 05.12.2018

andycat пишет:
Каждые 8 секунд МК просыпается, счётчик /переменная увеличивается

Я именно так у себя и сделал, (код отсюда) но тут я подумал, МК ведь все равно просыпается каждые 8 сек. Да при этом он не моргет светодиодом, не опрашивает датчики и т.д., но он ведь просыпаеться и проверяет переменную, а значит жрет энергию?

#include <avr/io.h>
#include <avr/wdt.h> // здесь организована работа с ватчдогом
#include <avr/sleep.h> // здесь описаны режимы сна
#include <avr/interrupt.h> // работа с прерываниями


volatile uint8_t i;
ISR (WDT_vect) {
	if ((++i % 4) == 0) 
	{
		PORTB ^= _BV(PB4); // переключаем светодиод
	}
	WDTCR |= _BV(WDTIE); // разрешаем прерывания по ватчдогу. Иначе будет резет.
}

int main() {
	i = 0;
	// инициализация порта светодиода
	DDRB = _BV(PB4); // на этом пине висит светодиод
	PORTB = _BV(PB4); // зажгем его

	//инициализация ватчдога
	wdt_reset(); // сбрасываем
	wdt_enable(WDTO_8S); // разрешаем ватчдог 8 сек
	WDTCR |= _BV(WDTIE); // разрешаем прерывания по ватчдогу. Иначе будет резет.
	sei(); // разрешаем прерывания
	
	set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную
	while(1) {
		sleep_enable(); // разрешаем сон
		sleep_cpu(); // спать!
	}
}

 

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

тоже есть такая задача, только бутлоадер на нано никак не перешью (((

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

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

hemicide
Offline
Зарегистрирован: 05.12.2018

Хорошо, спасибо за подсказки. К сожалению мой мультиметр отказываеться показывать токи меньше 200мА, проверить не могу.

ua6em пишет:

тоже есть такая задача, только бутлоадер на нано никак не перешью (((

У меня Attiny13, если разберетесь, то дайте знать, тоже интересно

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

ua6em пишет:

тоже есть такая задача, только бутлоадер на нано никак не перешью (((

в чем сложность?? На нано прекрасно заливается бут от уно. С догом. Плюс освобождается лишних 1.5 кило памяти.

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

ua6em пишет:

тоже есть такая задача, только бутлоадер на нано никак не перешью (((

Почитайте интернет /форумы, качественно усыпить можно голые МК, для например Nano необходимо отрывать светодиоды, стабилизатор, usb конвертер....нафига это если можно просто взять atmega328p например.

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

andycat пишет:
ua6em пишет:

тоже есть такая задача, только бутлоадер на нано никак не перешью (((

Почитайте интернет /форумы, качественно усыпить можно голые МК, для например Nano необходимо отрывать светодиоды, стабилизатор, usb конвертер....нафига это если можно просто взять atmega328p например.

Получилось!

Теперь жду Ваш пример как усыплять ардуину на час

b707
Онлайн
Зарегистрирован: 26.05.2017

ua6em пишет:

Теперь жду Ваш пример как усыплять ардуину на час

так вроде в #12 andriano все уже рассказал? или что-то не понятно?

у меня таким образом аттини спит минуту - но разницы с часом никакой, любой сон дольше 8сек делается одинаково

ua6em
ua6em аватар
Онлайн
Зарегистрирован: 17.08.2016

b707 пишет:

ua6em пишет:

Теперь жду Ваш пример как усыплять ардуину на час

так вроде в #12 andriano все уже рассказал? или что-то не понятно?

у меня таким образом аттини спит минуту - но разницы с часом никакой, любой сон дольше 8сек делается одинаково

Лично мне лучше пальцем (кодом) показать )))

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

ua6em пишет:

Лично мне лучше пальцем (кодом) показать )))

обленились, щас найду.

b707
Онлайн
Зарегистрирован: 26.05.2017

ua6em пишет:

Лично мне лучше пальцем (кодом) показать )))

играете с огнем %) - новичков за такие пассажи мордой в грязь :)

На работе кода нет, а на паямть не помню

если до того пример не найдете - поздно ночью выложу

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

Отличный исходник, почему я раньше его не находил, спасибо!

P.S. С каким датчик производится работа, DS12B20?

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

hemicide пишет:

P.S. С каким датчик производится работа, DS12B20?

Да.

ЗЫ. Ничего в нем отличного нет, переписать получение температуры надо с использованием библиотеки и с контролем CRC, вместо самодельной отправки воткнуть библиотеку RCswitch. но как обычно некогда....и лень тестировать.

hemicide
Offline
Зарегистрирован: 05.12.2018

Цитата:

Ничего в нем отличного нет

Как минимум то, что он уже готов(код). А я неделю сидел и разбирал разные примеры, переделывал и палил контроллеры xD

P.S. Какую вы ногу в датчике отывали? из той темы. У меня тоже модули по супергетеродинной схеме WL102-341

 

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

hemicide пишет:

P.S. Какую вы ногу в датчике отывали? из той темы. У меня тоже модули по супергетеродинной схеме WL102-341

с трудом :(

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

Upd:

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

#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;
}

 

а вот вариант правильного получения температуры на Attiny85 и DS18B20 с последующей отправкой по Software UART, соотвественно достаточно дорисовать отправку по радиоканалу и протестировать...никак руки не дойдут.

#include <avr/sleep.h>
#include <avr/wdt.h>
#include <OneWire.h>
#include "SoftwareSerial.h"

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

#define ds_pin PB3 // this is physical pin 2
OneWire ds18b20(ds_pin);

#define rx_pin PB3 // this is physical pin 2
#define tx_pin PB4 // this is physical pin 3
SoftwareSerial pcSerial(rx_pin, tx_pin /* out data */);

void setup () {
}

void loop () {
  initPins();
  showTemp();
  offPins();
  toSleep();
}

word getTemp() {
  word errTemp = 1111;
  byte dsData[9];
  ds18b20.reset();
  ds18b20.write(0xCC);
  ds18b20.write(0x44);
  delay(1000);
  ds18b20.reset();
  ds18b20.write(0xCC);
  ds18b20.write(0xBE);
  for (byte i = 0; i < 9; i++) dsData[i] = ds18b20.read();
  if (OneWire::crc8(dsData, 8) != dsData[8]) return errTemp;
  word outTemp = (word)(dsData[1] << 8) + dsData[0];
  if ((word)(outTemp & 0x8000) == (word)(0x8000)) {
    outTemp = (~outTemp) + (word)1;
    outTemp = (((word)6 * outTemp) + outTemp / (word)4) / (word)10;
  } else {
    outTemp = (((word)6 * outTemp) + outTemp / (word)4) / (word)10;
    if (outTemp == 0) return errTemp;
    outTemp  += (word)2000;
  }
  return outTemp;
}

void initPins() {
  digitalWrite(tx_pin, HIGH); pinMode(tx_pin, OUTPUT);
  pcSerial.begin(9600);
}

void offPins() {
  digitalWrite(PB0, LOW); pinMode(PB0, INPUT);
  digitalWrite(PB1, LOW); pinMode(PB1, INPUT);
  digitalWrite(PB2, LOW); pinMode(PB2, INPUT);
  digitalWrite(PB3, LOW); pinMode(PB3, INPUT);
  digitalWrite(PB4, LOW); pinMode(PB4, INPUT);
}

ISR (WDT_vect)
{
  wdt_disable();  // disable watchdog
}

void toSleep() {
  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 showTemp() {
  word currT = getTemp();
  if (currT == 1111) {
    pcSerial.println("Error get temp.");
    return;
  }
  pcSerial.print("Current temp = ");
  if (currT < 2000) pcSerial.print("-"); else currT -= 2000;
  pcSerial.print((currT / 10), DEC);
  pcSerial.print(".");
  pcSerial.print((currT % 10), DEC);
  pcSerial.println(" `C");
}

 

hemicide
Offline
Зарегистрирован: 05.12.2018

Сейчас замерил потребление своего утсройства)

Режим глубокого сна: 0.0056 мА

Режим работы: 0.1254 мА

При срабатывании раз в минуту, и длительностью работы 500мс, устройство проживет 1288.86 дня, или 3.53 года. от батарейки CR2032

Невероятно!

Калькулятор

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

А если морозы учесть ;)?
У меня на совсем китайской cr2032 за 12 рублей отработало на улице 9 месяцев. Поставил в октябре varta батарейки, посмотрим...на сколько хватит.

mable
Offline
Зарегистрирован: 09.10.2019

Я правильно понял, обычная часовая батарейка на 3В?

А как питание организовано? Можно схему посмотреть?

И как организован спящий режим? 

b707
Онлайн
Зарегистрирован: 26.05.2017

mable пишет:

А как питание организовано? Можно схему посмотреть?

плюс батарейки на VCC контроллера, минус  - на GND

Цитата:
И как организован спящий режим? 

А если тему почитать? - там же все ответы есть. Совсем уже обленились