Снижение потребления питания Arduino через спящий режим

Рассмотрим методы снижения энергопотребления Arduino с использованием библиотеки LowPower.h и создадим маломощную систему отслеживания влажности и температуры в качестве примера.

Мы также поговорим об аппаратных модификациях и программных ресурсах, доступных для резкого энергопотребления в UNO, NANO и Pro-Mini. Мы уделим особое внимание Arduino UNO и сделаем выводы по энергопотреблению каждой платы. И, конечно, обсудим использование спящего режима для снижения энергопотребления.

Модификации оборудования

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

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

Если вы запускаете свой проект от источника питания 12 В, то он потребляет более 50 мА тока. Понизив напряжение до 9-вольтовой батареи, вы можете уменьшить потребляемый ток примерно до 33 мА. При этом вы будете часто менять батарейки, что не очень удобно, если вы делаете автономный проект.

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

Например, учитывая, что светодиод может потреблять до 2 мА, вы можете полностью удалить все светодиоды.

Кроме того, питание подключенных устройств через порт ввода-вывода (I/O, Input/Output) позволяет выключать устройство, когда оно не используется.

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

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

Кроме того, некоторые устройства, такие как часы реального времени (RTC), должны оставаться включенными, и вы должны знать о текущих ограничениях порта ввода-вывода (примерно 40 мА).

В Arduino используется линейный регулятор напряжения, который необходим, но не очень эффективен. Поскольку встроенный регулятор мощности неэффективен, его легче обойти. Линейный регулятор принимает любое дополнительное напряжение и рассеивает его в виде тепла.

Таким образом, при работе вашего Ардуино Уно от батареи 9 В регулятор превращает лишние 4 В в тепло. При этом около 44% энергии расходуется на тепло, и даже больше, если вы используете источник питания 12 В.

Показанное ниже устройство представляет собой понижающий преобразователь DROK DC 4.5-24, который значительно более эффективен, чем линейный регулятор, используемый на UNO.

Схема должна работать с любым понижающим преобразователем, который имеет выход 5 В или 3,3 В, что дает дополнительное преимущество, поскольку вы можете отключить выходную мощность, просто заземлив желтый EN (включить) вывод.

На схеме черный провод - это масса (общее заземление), а красный - входное напряжение. Этот конкретный блок работает до 24 В (в зависимости от вашего понижающего преобразователя), зеленый - выходное напряжение.

Еще одна приятная особенность - он также поддерживает 3,3 В. В обход встроенного регулятора напряжения ток снижается с 52 мА до примерно 23 мА при 5 В.

Обратите внимание, что выход идет на штекер 5 В от понижающего преобразователя. Если вы решите запустить Arduino на 3,3 В, используйте также подключение 5 В. Когда вы обходите разъем питания, вы также обходите диод обратной полярности, поэтому убедитесь, что вы правильно сориентировали провода.

Библиотека низкого энергопотребления Ардуино

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

Процессоры, используемые в Arduino, предназначены для использования многих технологий энергосбережения. Но здесь мы будем говорить о библиотеке Ардуино под названием "Low Power" от Rocket Scream Electronics:

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

Ниже приведены результаты добавления библиотеки Low Power Arduino в программу Blink. Они получены от идентичных Arduino Uno, работающих от 12 В с помощью встроенного регулятора и от 12 В с понижающим преобразователем.

Без Low-PowerС Low-Power
12В с бортовым стабилизатором напряжения = 50 мА12В с бортовым стабилизатором напряжения = 45 мА
Понижающий преобразователь 5 В = 27 мАПонижающий преобразователь 5 В = 25 мА
Понижающий преобразователь 3,3 В = 10 мАПонижающий преобразователь 3,3 В = 8 мА

Чтобы продемонстрировать возможности энергосбережения, программа blink была изменена, - мы заменили две функции delay() функциями библиотеки LowPower.

Ниже показана функция LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF);. Заменив функцию delay() получаем отличный результат:

#include <LowPower.h>
void setup() {
   pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  
  LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF);                    
  digitalWrite(LED_BUILTIN, LOW);    
  LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF);               
}

Первый аргумент, SLEEP_2S, переводит процессор в спящий режим на две секунды. Чтобы освободить процессор, сигнал ШИМ создается на внешнем тактовом сигнале, который отключается, отключая функцию АЦП, экономя дополнительную мощность. Таймер отключения питания (BOT, Brown Out Timer), используемый для обеспечения правильного напряжения, также временно отключен.

Продолжительность сна может быть установлена на 15 мс, 30 мс, 60 мс, 120 мс, 250 мс, 500 мс, 1 секунду, 2 секунды, 4 секунды или 8 секунд. Как показано далее, существуют методы увеличения продолжительности сна намного дольше 8 секунд.

Существует множество других методов управления энергопотреблением ATmega328P. Для простоты воспользуемся методом LowPower.powerDown().

Устройство отслеживания температуры и влажности с низким энергопотреблением

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

Компоненты

Для реализации нашего демо-проекта нам понадобятся следующие компоненты:

  1. Arduino Uno (или Nano, или Pro Mini)
  2. Датчик температуры и влажности DHT11 или DHT22
  3. Память AT24C256 EEPROM 32K
  4. Модуль часов реального времени DS3231
  5. Понижающий преобразователь на 5 В
  6. Резистор 10 кОм
  7. Макетная плата
  8. Соединительные провода

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

AT24C256 поставляется с предварительно запрограммированным на заводе шестнадцатеричным адресом 0x50.

Схема соединения

EEPROM

Мы будем использовать EEPROM (electrically erasable programmable read-only memory или электрически стираемую программируемую постоянную память) для хранения наших данных.

В качестве альтернативы мы могли бы использовать устройство для чтения SD-карт. Однако для устройства чтения SD-карт требуется около 30 мА, и оно будет потреблять больше энергии, чем весь проект.

EEPROM лучше всего подходит для хранения данных в удаленных местах. Они маленькие, надежные, потребляют меньше 3 мА при записи в них, недорогие, а главное энергонезависимые. Схема адресации позволяет подключать до 8 устройств к шине I2C.

Распиновка EEPROM:

  • Pin1 = Address0
  • Pin2 = Address1
  • Pin3 = Address2
  • Pin4 = Gnd
  • Pin5 = SDA
  • Pin6 = SCL
  • Pin7 = Write Protect
  • Pin8 = VCC power

AT24C256 поставляется с предварительно запрограммированным на заводе шестнадцатеричным адресом I2C 0x5 с тремя дополнительными контактами адресации, которые можно изменить, A0, A1 и A2.

С тремя дополнительными двоичными входами (A0, A1, A2) вы можете создать адреса для 8 дополнительных EEPROMS в сети I2C.

Поскольку мы будем использовать только один чип для хранения, мы установим последние 3 бита адреса (A0, A1, A2) на низкий уровень.

Группируя биты в две шестнадцатеричные части, мы получаем адрес 0x50. Обратите внимание, что бит младшего разряда - это бит чтения и записи R/W. Поскольку мы хотим записать в устройство, бит чтения/записи будет установлен в низкий уровень.

Контакты SCL и SDA будут подключаться к A4-SDA и A5-SDA на Arduino Uno, Arduino Nano и Arduino Pro Mini.

На Arduino Pro Mini должны быть добавлены контакты A4 SDA и A5 SCL, а RTC и EEPROM подключаются к шине I2C.

Программа для устройства

Программа для отслеживания влажности и температуры на самом деле состоит из трех отдельных программ. Одна используется для отслеживания и записи данных, вторая - для чтения данных, последняя - для очистки данных из EEPROM.

Первая основана на части программы, найденной в Arduino IDE: Files -> Examples -> EEPROM -> eeprom_update. К этому очень простому примеру мы добавляем код, необходимый для часов реального времени, монитора влажности и температуры, процедур выборки и функций LowPower.

Код для записи данных

#include <DHT.h>
#include <LowPower.h>
#include <Wire.h>
#include <EEPROM.h>
#include <RTClib.h>
RTC_DS1307 rtc;
#define Led 13
#define DHTPIN 5    
// #define DHTTYPE DHT11   
#define DHTTYPE DHT22   
DHT dht(DHTPIN, DHTTYPE);
int address = 0;
void setup() {
  Serial.begin(9600);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  } 
  // раскомментируйте следующую строку, чтобы установить дату, затем закомментируйте ее и перекомпилируйте программу
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

  if (!rtc.isrunning()) {
    Serial.println("RTC Not running!");
  }
  dht.begin();
  Wire.begin();
} // End setup()

void loop() {
  delay(500);
  DateTime now = rtc.now();
  float h = dht.readHumidity();
  delay(500);
  float t = dht.readTemperature();
  delay(500);
  float f = dht.readTemperature(true); 
  delay(500);   
  EEPROM.update(address, (now.month())); 
  address++; 
  delay(500);
  EEPROM.update(address,(now.day()));   
  address++; 
  delay(500);
  EEPROM.update(address,(now.hour()));  
  address++; 
  delay(500);
  EEPROM.update(address,(now.minute())); 
  address++; 
  delay(500);
  EEPROM.update(address,h); 
  address++;
  delay(500);
  EEPROM.update(address,f);             
  address++;   
  delay(500);
//Included to allow you to view your output
  Serial.print("Humidity:" );
  Serial.println(h);
  Serial.print("Temperature:");
  Serial.println(f);
  Serial.print("Time ");
  Serial.print(now.hour());  
  Serial.print(":");
  Serial.println(now.minute());
  delay(1000);
  // Timer delays about 15 minutes between readings
  for (int i = 0; i < 100; i++) {   
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 
  }
}

Операторы #include загружают необходимые библиотеки датчиков DHT, библиотеку LowPower, Wire.h для шины I2C, модуль EEPROM и библиотеку часов реального времени.

DHTPIN подключен к выводу 5; вам нужно раскомментировать строку, которая определяет, какое устройство вы используете (DHT 22) в этом примере.

В функции setup() включен последовательный порт и подтверждена функция часов реального времени. Обратите внимание на строку //rtc.adjust(DateTime(F(DATE), F(TIME))); так как она используется для установки RTC по отношению к часам, которые использует ваш компьютер.

Её нужно один раз раскомментировать, а затем загрузить, чтобы установить часы. После того, как вы сбросили часы, снова вставьте комментарий и перекомпилируйте код. Последние две строки в настройке включают датчик DHT и включают шину I2C.

В функции loop() после delay() первая инструкция должна получить время от RTC с помощью вызова rtc.how(). Следующие два чтения выполняются из библиотеки DHT с использованием функций dht.readHumidity() и dht.readTemperature(), которые сохраняют вывод в переменных «h» и «t» соответственно.

Задержки после функций чтения добавляются, потому что они имеют небольшую задержку при чтении. Функция dht.readTemperature(true) сохраняет температуру в градусах Фаренгейта и сохраняет ее в «f». Если вы предпочитаете использовать градусы Цельсия, измените значение переменной на «t», т.е. заменить «f» в EEPROM.update(address, f);.

Адрес переменной, объявленный изначально как int «0» (целое число), используется для адресации первого места хранения в адресе EEPROM 0. Синтаксис для записи в EEPROM - EEPROM.update(address,(value)).

Использование EEPROM.update сначала делает проверку и записывает, только если данные отличаются от тех, которые, возможно, уже были записаны по этому адресу ранее. Это предотвращает запись одних и тех же данных, т.е. если данные не изменились, то не надо их перезаписывать. Поскольку вы можете писать только ограниченное количество раз, то это способствует долговечности устройства. В ячейки памяти можно записывать примерно 100 000 раз.

После записи в первый адрес «0» адрес увеличивается, и следующая ячейка может быть записана в «1». Обратите внимание, что мы записываем ровно 6 блоков данных для каждой выборки.

Функция LowPower имеет максимальное ограничение в восемь секунд. Мы настроили цикл for для 100-кратного прохождения этапа LowPower, что дало нам задержку чуть более 13 минут. Время можно увеличивать или уменьшать, чтобы учесть любое время выборки, которое вы хотите использовать.

Код для чтения данных

#include <EEPROM.h>
int i = 0;
int address = 0;
byte value;

void setup() {
  Serial.begin(9600);
  while (!Serial) {
  }
}
void loop() {
  value = EEPROM.read(address);
  while (value > 1) {
    for (i = 0; i < 6; i++) {                 
      Serial.print("Date-");
      Serial.print(value);                     
      Serial.print("/");
      address++;
      value = EEPROM.read(address);
      delay(50);
      Serial.println(value);                   
      address++;
      value = EEPROM.read(address);
      delay(50);
      Serial.print("Hours:");
      Serial.print(value);                
      address++;
      value = EEPROM.read(address);
      delay(50);
      Serial.print(" Minutes:");
      Serial.println(value);
      address++;
      value = EEPROM.read(address);
      delay(50);
      Serial.print("Humidity:");
      Serial.print(value);
      Serial.println("%");
      address++;
      value = EEPROM.read(address);
      delay(50);
      Serial.print("Temperature:");
      Serial.print(value);
      Serial.println(" Degrees Fahrenheit");
      address++;
      Serial.println("\n");
      break;
    }
    break;
  }
}

Для ввода данных использовалась функция EEPROM.update(). Теперь воспользуемся функцией EEPROM.read(). В void loop() мы устанавливаем цикл while на основе содержимого по адресу 0 EEPROM.

Первая часть вводимых данных - это месяц, который должен быть от 1 до 12. Убедитесь, что ваш RTC работает; если это не так, цикл while никогда не запустится. Цикл while будет выполняться до тех пор, пока не достигнет последней записанной ячейки.

Цикл for был настроен на чтение шести записей. Именно столько записей делается при каждом запуске программы сбора данных. Если вы хотите увеличить объем собираемых данных, вы должны сначала изменить программу сбора данных, добавив что-нибудь еще, что вы хотите записать. Затем увеличьте число в операторе if, чтобы учесть всё дополнительное.

Код для стирания EEPROM

#include <EEPROM.h>

void setup() {
  // initialize the LED pin as an output.
  pinMode(13, OUTPUT);
  
  for (int i = 0 ; i < EEPROM.length() ; i++) {
    EEPROM.write(i, 0);
  }

  // turn the LED on when we're done
  digitalWrite(13, HIGH);
}

void loop() {
   
}

Последняя часть проекта - программа стирания. Она находится в:

File -> Example -> EEPROM -> eeprom_clear

Что касается светодиода digitalWrite(13, HIGH);, то светодиод включается, чтобы указать, что EEPROM полностью стерта. Запустите эту программу перед началом любого нового сбора данных.

Результаты проекта

Arduino Uno: 3,3 В постоянного тока, 5 В = 17,1 мА в спящем режиме, 26,9 мА в рабочем режиме.

Arduino Nano: 3,3 В, 11,1 мА в спящем режиме, 16,9 мА в режиме работы.

Arduino Pro Mini: 3,3 В постоянного тока, тактовая частота 8 МГц, в спящем режиме 6,5 мА, и 12,2 мА в рабочем состоянии.

Любой из этих примеров может питаться от литиевой батареи и заряжаться от небольшой солнечной панели.

15 ноября 2020 в 16:40
Опубликовано: | Оригинал
Статьи, ,

1 комментарий

  1. Андрей
    14 марта 2021 в 18:50

    В реальности есть наработка этого проекта?

    Ответить

Добавить комментарий

Ваш E-mail не будет никому виден. Обязательные поля отмечены *