Совершенствуя свой комнатный термостат, о котором писал раньше, я задался целью дополнить его беспроводным датчиком температуры для измерения температуры воздуха на улице, собрать термостат с питанием от батареек и заменить модули приемник-передатчик RF 433MHz другой парой радиомодулей с большей дальностью связи при напряжении питания не более 3В. По ходу решения этих задач вырисовалась автономная метеостанция, речь о которой пойдет ниже.






Метеостанция состоит из двух узлов, назовем их для простоты анализатором и термометром. Связь между узлами — беспроводная, по радиоэфиру.



Анализатор, построен на контроллере ATMEGA328P, измеряет температуру и влажность в помещении (датчик температуры и влажности DHT22) и напряжение питания анализатора, которое обеспечивают две батарейки АА 1,5В. На контроллер поступает сигнал с приемника LoRa, который по эфиру принимает информацию с термометра (выносного датчика). Информация с контроллера выводится на ЖК-дисплей NOKIA 5110.



В термометре, собранном тоже на контроллере ATMEGA328P, измеряется температура воздуха на улице (датчик температуры DS18B20) и напряжение питания выносного узла, организованного на двух батарейках АА 1,5 В. Передатчик LoRa этого узла передает температуру и напряжение питания на анализатор.



Контроллер ATMEGA328P и передатчик LoRa термометра для экономного расходования заряда батареек после измерений и отправки информации переводятся в режим сна. Напряжение питания на датчик DS18B20 программно подается только на время измерения температуры. Измерения и отправка данных с термометра выполняется с периодом около одной минуты.



В таком же режиме работа-сон работает и анализатор. Продолжительность работы контроллера и приемника анализатора несколько больше одной минуты (около 65 сек). Это сделано для уверенного приема сигнала с термометра — ведь работа термометра и анализатора не синхронизированы. Затем ATMEGA328P и приемник LoRa переводятся на 14 мин в режим сна до пробуждения и старта очередного цикла. Питание на DHT22 подается только во время измерений.



Для программирования режима сна контроллеров ATMEGA328P используется библиотека LowPower.h.



С разрядом батареек на них понижается величина напряжения.





Нижний предел рабочего напряжения питания контроллера ATMEGA328P — 1,8В. При этом, заводская установка фьюз ATMEGA328P выполнена на мониторинг порога напряжения питания 2,7В, поэтому необходимо изменить заводские установки фьюз на мониторинг порога 1,8В, чтобы гарантировать работу контролера при напряжении питания ниже 2,7В при питании от батареек.



Внутренний генератор контроллера может не запускаться на частоте 16 МГц при напряжении питания 3В или несколько ниже. У меня оба контроллера работают с кварцем 16 МГц при пониженном напряжении питания 2,7…2,8В, поэтому я не стал менять кварц 16 МГц на 8 МГц.





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



Компонент Цена, $
анализатор
Контроллер ATMEGA328P-PU 1,59
Датчик температуры и влажности DHT22 2,34
Приемник-передатчик LoRa Rа-01 3,95
ЖК-дисплей NOKIA 5110 1,91
Макетная (монтажная) плата, монтажные провода, батарейки АА, кварцевый резонатор 16 МГц (8 МГц), резисторы и др. 4,00
термометр
Контроллер ATMEGA328P-PU 1,59
Датчик температуры DS18B20 0,63
Приемник-передатчик LoRa Rа-01 3,95
Макетная плата (стеклотекстолит), монтажные провода, батарейки АА, кварцевый резонатор 16 МГц (8 МГц), резисторы и др. 4,00
Всего (примерно): 24


Анализатор





Мозг анализатора – контроллер ATMEGA328P. Он принимает сигналы с датчика DHT22 и формирует сигналы управления приемником LoRa и дисплеем NOKIA 5110.





В Интернете много нареканий на низкую точность измерения влажности датчика DHT22. На сегодня есть альтернатива: более современные датчики температуры и влажности HTU21 (GY21), (Vcc = 3...5 В), Si7021,(Vcc = 1,9… 3,6 В), SHT21, (Vcc = 2.1….3,6 В).



Я использую DHT22, поскольку расхождение между показаниями влажности моего экземпляра этого датчика и серийно выпускаемого термогигрометра LaCrosse WS-9024IT составляют не более 8-ми единиц, что вполне приемлемо для бытовых целей. Расхождение между показаниями влажности сильно увеличиваются, если величина напряжение питания DHT22 ниже 3В. Это и понятно, ведь напряжение питания DHT22 должно находиться в пределах 3…5В. Суммируя – идеально в этих условиях в схему анализатора вписывается датчик Si7021.



На картинке ниже — цоколевка элементов метеостанции.





Фьюзы и многое другое различных контроллеров, в том числе ATMEGA328P, можно читать и редактировать утилитой SinaProg. Если вы впервые сталкиваетесь с этой программой, то несмотря на интуитивно понятный интерфейс, не пытайтесь после инсталляции приложения начинать с ним работать. Сначала почитайте тут, где HWman приводит необходимые дополнения SinaProg при использовании Arduino UNO и подробные инструкции.



Советую вначале прочитать заводские установки фьюз ATMEGA328P и сохранить их значения, чтобы вернуться к ним в случае неудачи. В моих контроллерах заводские установки фьюз бит такие: LOW: 0xFF, HIGH: 0xDE, EXTENDED: 0x05 (Vcc=2.7V, BODLEVEL=101). Фьюзы на мониторинг порога 1,8В: LOW: 0xFF, HIGH: 0xDE, EXTENDED: 0x06 (Vcc=1.8V, BODLEVEL=110).



Скетч анализатора для загрузки в ATMEGA328P находится под спойлером.



скетч анализатора
/*
 * Автономная метеостанция на контроллере ATMEGA328P и питанием от батареек с беспроводным выносным датчиком, анализатор 
 */

#include <SPI.h>
#include <LoRa.h>

#include "DHT.h"
#define DHTPIN 3     // what digital pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);

float  Tin=0;
int Hin=0;
float BatteryInLevel;  // напряжение батареи базы
String LoRaData, Tout_str, BatteryInLevel_str, BatteryOutLevel_str;

//sleep
#include <LowPower.h>
#define PowerDHT (4) //пин питания DHT22
unsigned int sleepCounter;

//Nokia 5110
#include <SPI.h>
#include <Adafruit_GFX.h>  //https://esp8266.ru/forum/threads/esp8266-5110-nokia-lcd.1143/#post-16942
#include <Adafruit_PCD8544.h>  //https://esp8266.ru/forum/threads/esp8266-5110-nokia-lcd.1143/#post-16942

//timer
#include <SimpleTimer.h>
SimpleTimer timer; 

Adafruit_PCD8544 display = Adafruit_PCD8544(5, 7, 6);

void sendSensor(){
    digitalWrite(PowerDHT, 1);
    delay (2000);
    Hin = dht.readHumidity();
    Tin = dht.readTemperature();
  
   /* if (isnan(Hin) || isnan(Tin)) {
    //  Serial.println("Failed to read from DHT sensor!");
      return;
     }*/
     
     digitalWrite(PowerDHT, 0);
  
   // измерение напряжения батареи:  
      analogReference(INTERNAL);       
      int sensorValue = analogRead(A4);
      BatteryInLevel = (sensorValue * 3.2 / 1024);     
} 

void draw(){
   display.clearDisplay(); 
//Tin
 { 
   display.setTextSize(2);
   display.setCursor(8,0);
   display.println (Tin, 1); // один знак после запятой
   display.setCursor(68,0);
   display.println("C");
   }
//Hin
 {  
 //  Hin = 58;   // ТЕСТ, удалить!
   display.setTextSize(2);
   display.setCursor(8,16);
   display.println(String(Hin)+ "%"); 
   }
//Tout   
 { 
   char chr_Tout [12];
   
   Tout_str.toCharArray(chr_Tout, 5); 
   display.setTextSize(1);
   display.setCursor(50,16);
   display.println(String(chr_Tout)+"C"); 
   }
// Battery Out Level 
 { 
   char chr_BatteryOutLevel [12];

   BatteryOutLevel_str.toCharArray(chr_BatteryOutLevel, 4); 
   display.setTextSize(1); 
   display.setCursor(2,32);
   display.println("BAT Out: " + String(chr_BatteryOutLevel)+"V");
   }
// Battery In Level 
 { 
   display.setTextSize(1);
   display.setCursor(2,40);
   display.println("BAT In:  ");
   display.setCursor(56,40);
   display.println(BatteryInLevel, 1);  //один знак после запятой
   display.setCursor(74,40);
   display.println("V");
  }
     
    display.display();
    
      /*    Serial.println("Tin: " + String(Tin)+"*C");
          Serial.println("Hin: " + String(Hin)+"%");
          Serial.println("Tout: " + String(Tout_str)+"*C");
          Serial.println("BAT_In: " + String(BatteryInLevel)+"V");
          Serial.println("BAT_Out: " + String(BatteryOutLevel_str)+"V");
          Serial.println("......"); */
        
} 

void sleepDevice(){      
      // sleepCounter = 65 - 10 min
      // sleepCounter = 91 - 14 min
      for (sleepCounter = 91; sleepCounter > 0; sleepCounter--) //91!!!
      { 
        LoRa.sleep ();
        LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);  
      }  
         LoRa.sleep ();
}

void SignalReception (){
  // try to parse packet
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
 // read packet
    while (LoRa.available()) {
    LoRaData = LoRa.readString();
  //  Serial.println("Принято: "+(LoRaData));
    }
    int pos1 = LoRaData.indexOf('#');
    Tout_str = LoRaData.substring(0, pos1);   
    BatteryOutLevel_str = LoRaData.substring(pos1+1, LoRaData.length());   
  }  
}

void setup() {
 // Serial.begin(9600);
  pinMode(PowerDHT, OUTPUT);
    
   // инициализация и очистка дисплея
        display.begin();
        display.clearDisplay();
        display.display();        
        display.setContrast(60); // установка контраста
        
         display.clearDisplay(); 
         display.setTextSize(2);
         display.setCursor(12,16);
         display.println (">>>>>"); //индикация начала работы при включении 
         display.display();
      
         dht.begin();
         sendSensor();
         draw();

      while (!LoRa.begin(433E6)) {
  //  Serial.println(".");
      delay(500);
      }
       // Диапазон для синхрослова – между «0-0xFF».
      LoRa.setSyncWord(0xF3);          
     // Serial.println("LoRa Initializing"); 
       timer.setInterval(20000, sendSensor); 
       timer.setInterval(5000, draw);
       timer.setInterval(62000, sleepDevice);
}

void loop() {
     SignalReception();
     timer.run();
}



Для работы с контроллерами ATMEGA328P в качестве программатора я использую плату Arduino UNO. Процесс установки загрузчика и загрузки скетчей в контроллер ATMEGA328 с помощью платы Arduino UNO подробно описан тут. На Youtube есть хорошее видео на эту тему.



В скетче закомментированы команды вывода в монитор последовательного порта (Serial). В случае необходимости — раскомментируйте команды.



Цикл начинается с прослушивания эфира и приема информации приемником LoRa. Таймером установлено время прослушивания — 62 сек. В это время с периодом 5 сек обновляется информация на дисплее NOKIA и с периодом 20 сек (3 раза) датчиком DHT22 проводятся измерения температуры, влажности, а также уровень напряжения батареек через один из аналоговых входов контроллера. Напряжение питания на DHT22 подается только во время измерений с минимальной задержкой 2 сек, при которой датчик еще работает. Выход АЦП в скетче масштабирован на напряжение новых батареек, которое составляет 3,2В (1,6В х 2). Время прослушивания эфира выбрано несколько больше 1 мин для уверенного приема одной пачки с термометра, который работает на передачу с периодом 1 мин, но об этом ниже. Затем на 62-ой секунде контроллер и приемник переводятся в режим сна, который длится примерно 14 мин, т.е. период цикла «работа/сон» анализатора — около 15 мин. Замечу, что режим сна в анализаторе – это вынуждения мера, призванная существенно уменьшить потребление. С другой стороны – за 15 минут температура и влажность воздуха кардинально не изменятся. Как показал расчет времени работы от батареек, режим сна можно уменьшить до 8-9 мин, но я не стал этого делать, поскольку в будущем узел будет дополнен функциями термостата, что приведет к увеличению потребления.



Для сравнения — в таблице ниже приведены характеристики термогигрометра LaCrosse WS-9024IT и анализатора с этого проекта. Большинство параметров LaCrosse из таблицы не приводятся в ее техническом описании, а были измерены. Хотел дополнить таблицу результатами аналогичных любительских разработок, но, к сожалению, ничего не нашел.



Параметр LaCrosse WS-9024IT Сadil_TM
Питание 2хАА, 3В, Durasell 2хАА, 3В, GP Ultra+, 2.72 Wh
Потребление сна 8 мкА 10 мкА
Продолжительность сна   14 мин
Операционное потребление 200 мкА 3 мА
Продолжительность работы   65 сек
Период цикла работа/сон 30 сек 15 мин
Время эксплуатации более 2 лет около 1 года


Расчет времени работы.
Средний ток потребления: 3 мА / 15 + 0,01 мА = 0,21 мА, где 15 – скважность. Емкость батарейки GP Ultra+ в мА*час: 2.72 Вт*час / 1,5 В = 1,81 А*час = 1800 мА*час. Время эксплуатации: 1800 мА*час / 0,21 мА = 8600 час (11,9 мес).
Уточню:
— Расчет очень приблизительный, поскольку в основу расчета положено максимальное (пиковое) потребление анализатора.
— Время работы LaCrosse приведено, исходя из собственного опыта. Этот девайс у меня давно.



Термометр





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





Фьюзы для ATMEGA328P термометра такие же, как и для анализатора.



Узел термометра тоже построен на контроллере ATMEGA328P. Он принимает сигнал с датчика DS18B20, измеряет напряжение питания и управляет передатчиком LoRa.





Скетч термометра – под спойлером.



скетч термометра

/*
 * Автономная метеостанция на контроллере ATMEGA328P и питанием от батареек с беспроводным выносным датчиком, термометр  
 */
 
#include <OneWire.h>
OneWire ds(7); //pin 13, Atmega328P

#include <SPI.h>
#include <LoRa.h>

#include <LowPower.h>

#define PowerDS18B20 (6) //pin 12 (Atmega328P), питаниe DS18B20
unsigned int sleepCounter; // счетчик, задающий время сна
float Tout;  //температура
int i;  // отсчет числа циклов при включении устройства интенсивного режима(20 циклов за 1 мин)

String messageTout;  // LoRa-сообщение
float batteryLevel;  // напряжение батареи
const int batteryPin = A0; // pin 23 (Atmega328P), к которому подключена батарея для измерения напряжения

 void Measurement (){
//измерение температуры
  byte data[2]; 
  
  digitalWrite(PowerDS18B20, 1);

  ds.reset();
  ds.write(0xCC); // пропуск поиска по адресу (1 датчик) 
  ds.write(0x44); // команда на измерение
  
  delay(700);   
  
  ds.reset(); 
  ds.write(0xCC); 
  ds.write(0xBE); // передача регистров со значением температуры
  
  data[0] = ds.read(); 
  data[1] = ds.read(); 
  Tout =  ((data[1] << 8) | data[0]) * 0.0625;
 // Serial.println("Tout= "+ String(Tout));
  digitalWrite(PowerDS18B20, 0);
    // измерение напряжения батареи:
  analogReference(INTERNAL);    
  int sensorValue = analogRead(A0);
   batteryLevel = (sensorValue * 3.2 / 1024);
  // Serial.println("BAT= "+ String(batteryLevel));
   }

void SetSynchLoRa () {
int counter = 0;  
  while (!LoRa.begin(433E6) && counter < 10) {
  //  Serial.print(".");
    counter++;
    delay(500);
  }
  
 /* if (counter == 10) {
  //  Serial.println("Failed to initialize ...");
  }*/
  LoRa.setSyncWord(0xF3);  
}

void SendMessage (){
// отправка данных (температура, напряжение батареи)
  messageTout = String(Tout) + "#" + String(batteryLevel); 
//  Serial.println(messageTout);
  delay(250);
  LoRa.beginPacket();
  LoRa.print(messageTout);
  LoRa.endPacket();
}

void setup() {
 // Serial.begin(9600);
 // Serial.println("Initializing ...");
  pinMode(PowerDS18B20, OUTPUT);
  SetSynchLoRa ();
}

void loop() {
 // Serial.println("");
 // Serial.println("i = " + String(i));
  
 if (i >= 30){// i >= 30 (1 мин) - обычный режим (измерение, отправка - 1 раз/1 мин)
   for (sleepCounter = 5; sleepCounter > 0; sleepCounter--)
    {
      LoRa.sleep ();
      LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);  
    }
   Measurement (); 
   SendMessage ();
   LoRa.sleep ();   
 } else 
 { //интенсивный режим продолжительностью 1 мин, отправка - 1 раз/2 сек
  Measurement ();
  SendMessage ();
  delay (1000);
 }
 i++;
  if (i >= 30) i = 30; //уменьшение разрядности заполнения счетчика
}



Вначале при подключении питания термометр на протяжении одной минуты работает в интенсивном режиме. Он измеряет температуру, напряжение батареек и посылает их значения в эфир через каждые 2 сек. Это сделано для удобства. Допустим, при замене батареек или отладке не придется ждать минуту. Информация с датчика появится на дисплее анализатора в первые секунды после подключения батареек термометра и анализатора. Естественно, стоит поторопиться и не делать разрыва во времени больше минуты между подключением батареек на обоих узлах.



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



Расчет времени работы.
Средний ток потребления: 8 мА / 60 + 0,01 мА = 0,14 мА, где 60 – скважность. Емкость батарейки GP Ultra+, (мА*час): 2.72 Вт*час / 1,5 В = 1,813 А*час = 1800 мА*час. Время эксплуатации: 1800 мА*час / 0,14 мА = 12800 час (18 мес).
Предыдущие уточнения относительно точности рассчитанного значения времени работы от одного набора батареек остаются в силе.



И сравнительная таблица. В ней есть результаты пары похожих проектов из Интернета.



Параметр LaCrosse WS-9024IT maniacbug avs24rus Сadil_TM
Питание 2хААА, 3В, Durasell 3В, CR2450 Renata, 540 мА*ч 3В, CR2450, 550-610 мА*ч 2хАА, 3В, GP Ultra+, 2.72 Wh
Потребление сна 10 мкА 0,14 мА (?) 14 мкА 10 мкА
Продолжительность сна       1 мин
Операционное потребление 90 мкА 13,57 мА 16 — 18 мА 8 мА
Продолжительность работы   0,027 сек   1 сек
Период цикла работа/сон 5 сек 1 мин 10 мин 1 мин
Время эксплуатации более 2 лет   более 0,5 года около 1,5 года


Если узлы собраны без ошибок, то на дисплее увидим такую картинку:





Из сравнительных таблиц видно, что операционное потребление любительских устройств на два порядка выше (более 100 раз!) выше, чем в аналогичной за функциями промышленной LaCrosse. Например, 8 мА против 90 мкА для выносного датчика и 3 мА: 200 мкА для анализатора. Потребление сна примерно одинаково – около 10 мкА. Такое разительное отличие в операционном потреблении объясняется, на мой взгляд, тем, что контроллеры в любительских схемах запрограммированы на языке Arduino IDE, а в промышленных продуктах скорее всего на одном из языков низкого уровня или C#/C. Если же использовать регистры микроконтроллера, язык программирования C, то, уверен, можно выйти на потребление, сравнимое с промышленными образцами. Впрочем, это очень убедительно экспериментально показал HWman в своей публикации «Почему многие не любят Arduino». Выполнение простейшего скетча до десятка строк (Blink), выполненного на языке в одном случае Arduino и в другом — C приводит к проигрышу в производительности в 26 раз. Короче, повышенное потребление ресурсов – это плата за комфорт и небольшие усилия со стороны программиста – остальное за него в Arduino сделают «прожорливые» функции среды разработки. Предчувствую — придется напрячься и освоить C#/C…



Выводы


• Собранные анализатор и термометр имеют слишком большое операционное потребление тока по сравнению с промышленными образцами. Для уменьшения энергопотребления в оба узла введен режим сна. Существенно уменьшить операционное потребление можно, переписав скетч на языке C#/C.

• К двум батарейкам питания в схемах напрашивается третья, тогда автоматически решаются следующие проблемы — отпадает необходимость в переустановке фьюз, устойчивая работа контроллера на частоте 16 МГц, работа датчиков DHT22, DS18B20 вдали от нижнего порога напряжения питания. Последнее немаловажно, поскольку напряжение питания подается на датчики не прямо, а программно через ключ с пина контроллера, на котором падает порядка 1В.

• Применение радиомодулей LoRa, с дальностью связи при прямой видимости до 1,5 км, позволило установить устойчивую связь в пределах квартиры с питанием модулей на уровне 3В.

Ссылки по теме


Узел беспроводного датчика с низким энергопотреблением
Беспроводный Lighting-Sensor с питанием от CR2450
Термометр с беспроводной передачей данных
Превращаем Arduino в полноценный AVRISP программатор
LoRa и сон
Узнайте о битах конфигурации ATmega328P и о том, как использовать их с внешним кварцевым резонатором
Калькулятор фьюзов AVR
Почему многие не любят Arduino
Грандиозное тестирование батареек
Батарейки на морозе

Комментарии (47)


  1. ittakir
    08.10.2019 07:25

    1. C# != C.
    2. Если сделаете синхронизацию устройств, то не нужно будет ждать 65 секунд во время приема. Достаточно сделать период отправки сигнала датчиком более-менее фиксированный, а на базе запоминать время приема предыдущего пакета и включать приемник как раз к моменту следущего пакета. Это здорово сэкономит энергию.


    1. Cadil_TM Автор
      08.10.2019 08:31

      Спасибо!
      Но для синхронизации надо ввести в оба узла часы, которые будут потреблять постоянно. Еще не факт, что общее потребление уменьшится. Надо считать.


      1. AlexanderS
        08.10.2019 10:23
        +1

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

        В своё первое включение станция ожидает данных от датчика и держит приёмник включенным. Первый корректный пакет данных синхронизирует обмен и приёмник отключается. Затем станция включает приёмник через 60 секунд на 10 секунд — открывается «окно приёма». Понятное дело, что кварцевые генераторы на станции и датчике тикают по разному и время будет разбегаться, поэтому каждый принятый пакет должен калибровать внутренний счётчик таймаута приёма. Если станция не получила подряд три пакета — нужна полная ресинхронизация (аналог первого включения).

        Однако всё усложняется, если датчиков несколько и они могут быть включены в совершенно произвольное время — станции придётся дожидаться первой посылки от каждого датчика и каждому выделять персональное «окно», за которым и следить. Понятно, что это чисто алгоритмическая нагрузка, которая тем не менее энергопотребление может тоже снизить, но тут уже зависит от количества датчиков и порядка их включения. Хотя, конечно, это не очень красиво, когда время жизни устройства зависит от того в какой последовательности я почесал за ухом и включил тот или иной датчик) Эти проблемы просто решаются введением в систему двунаправленного обмена данными станции с датчиками (введение просто часов не поможет, т.к. всё равно возникнет вопрос их синхронизации), но это повышает сложность и стоимость самих датчиков.


        1. Cadil_TM Автор
          08.10.2019 11:01

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

          Свежий, неожиданный для меня подход! Обязательно займусь им, не откладывая на будущее.
          Возможно, он присутствует в технологии iT+? Описание технологии мне не удалось найти, но производители ее рекламируют.


          1. AlexanderS
            08.10.2019 12:22
            +1

            Я просто предложил решение, которое в голову пришло. Вам же как таковое абсолютное время не нужно — можно и относительным, ни к чему не привязанным обойтись. Решение простое, изменений в аппаратной части не требует — надо только накодить. Вряд ли я изобрёл что-то новое)

            Надо заметить, что синхронизировать моменты приёмо-передачи можно по источнику из вне. Это может быть время GPS (просто опрос модуля GPS), GSM (запрос времени AT+ командами от модуля GSM модема), WiFi (модули на базе ESP, который сам бы подключался к сети, внутри крутился бы опрос по NTP какого-нибудь stratum сервера + ответы на запросы от атмеги) или вообще по радиосигналам точного времени (но не везде они «долетают»). Конечно, всё это будет жрать энергию, но тут зависит от концепции — все эти «обвески» могут включаться, например, только раз в сутки для точной синхронизации. При этом вы получите очень точное время. Окно приемо-передачи можно реально сузить до полсекунды. Однако, с моей точки зрения, если уж заниматься чем-то своими руками и ради хобби, то гораздо интереснее построить именно автономную систему, которая бы минимально зависела от внешних условий. В принципе, сама станция может периодически излучать синхросигнал, по которому будут синхронизироваться датчики. Причём можно его хоть как-то закодировать, чтобы помехоустойчивость поднять.


  1. Javian
    08.10.2019 08:17
    +1

    Попробуйте вот так отключать нагрузку habr.com/ru/post/386735
    image


    1. Cadil_TM Автор
      08.10.2019 08:54

      Попробуйте вот так отключать нагрузку habr.com/ru/post/386735

      Модуль TIDA-00484 TI Design — фантастика! Обязательно посмотрю этот модуль.


      1. Javian
        08.10.2019 11:18

        Там фокус в TPL5111 таймере и выключателе нагрузки TPS22860. Они сами потребляют микроскопический ток и с фиксированной частотой включают прожорливое устройство для передачи данных, а потом отключают.


        1. Cadil_TM Автор
          08.10.2019 12:21

          Там фокус в TPL5111 таймере и выключателе нагрузки TPS22860. Они сами потребляют микроскопический ток и с фиксированной частотой включают прожорливое устройство для передачи данных, а потом отключают.

          Спасибо за уточнения! Но, собственно, неважно что вводит модули в режим сна: таймер контроллера или внешний таймер. К тому же многие модули управляются по нескольким проводам (протокол SPI). Справится с их включением/выключением выключатель нагрузки TPS22860?



  1. smart_alex
    08.10.2019 08:32

    Такое разительное отличие в операционном потреблении объясняется, на мой взгляд, тем, что контроллеры в любительских схемах запрограммированы на языке Arduino IDE


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

    Например, на модифицированной Pro Mini и nRF24L01 прекрасно делаются датчики со временем жизни от 1 года до 10 лет от одного комплекта батареек, в зависимости от типа датчика и режима его работы.

    Анекдот на эту тему из жизни. Во время беседы с представителем «Стрижа», я задал ему вопрос: «Скажите, а как вам удалось добиться времени работы датчика 10 лет?». Ответ: «А наши датчики выходят на связь 1 раз в сутки». :)


    1. Cadil_TM Автор
      08.10.2019 09:20

      В Arduino никто не мешает в критических местах использовать низкоуровневый код, программирование регистров и т. д.

      Это полумеры и шараханье из одной крайности в другую. Хотя, не спорю — вторая крайность требует соответствующей квалификации. Код на языке С — мне кажется оптимальным решением.


    1. Cadil_TM Автор
      08.10.2019 10:00

      … на модифицированной Pro Mini и nRF24L01 прекрасно делаются датчики со временем жизни от 1 года до 10 лет от одного комплекта батареек, в зависимости от типа датчика и режима его работы.

      Сначала надо победить nRF24L01. Посмотрите как мучаются люди с nRF24L01 — 114 страниц форума за несколько лет! Я тоже возился с этим радиомодулем. Возможно, в будущем дополню эту статью.


      1. smart_alex
        08.10.2019 10:28

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

        Это пример работы беспроводного датчика расхода воды на Pro Mini и nRF24L01. Два канала, холодная и горячая вода, период отсылки показаний (актуализации) в системе (AMS) 5 минут.

        Расчётное время работы датчика в динамическом режиме (период 5 минут) — 2 года, в тарификационном режиме (период 1 день) — 6+ лет.

        Всё сделано на Wiring (нативом языке Ардуино) в Arduino IDE.


        1. Cadil_TM Автор
          08.10.2019 11:04

          Где можно посмотреть ваш проект? Дополню хотя бы сравнительные таблицы.


          1. smart_alex
            08.10.2019 11:11
            +1

            Публичные версии системы, включая (работающие) примеры nFR24 датчиков здесь:

            https://hi-lab.ru/arduino-mega-server/details/download

            Частные проекты и разработка здесь:

            https://hi-lab.ru/arduino-mega-server/ams-pro


        1. Polaris99
          08.10.2019 14:04

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


      1. igrushkin
        08.10.2019 13:55

        мучаются птому, что изобретают велосипед. Я использую либу MySensors и получаю удовольствие. Сейчас правда перешел на nrf52


    1. Polaris99
      08.10.2019 14:01
      +1

      Если использовать низкоуровневый код и программирование регистров, то разработчику и Ардуина не нужна, так что не вижу никакого противоречия в словах автора :)


  1. Pafnutyi
    08.10.2019 12:23

    Давно-давно повторял(не моя придумка) проджект температурного датчика на MSP430 в качестве передатчика был контур на 200Кгц ударно возбуждаемый с ножки микроконтролера — никаких радиомодулей ;). Приёмник такой же контур + усилитель и на компаратор встроенный в МК. Дальность была около 20..25 метров на одной не новой солевой батарейке датчик продержался больше года, потом механически был повреждён сосулькой…


  1. gerasimenkoao
    08.10.2019 13:58

    Такое разительное отличие в операционном потреблении объясняется, на мой взгляд, тем, что контроллеры в любительских схемах запрограммированы на языке Arduino IDE

    Вот не нужно валить все с больной головы на здоровую!


    Моя "ардуинка"(голый микроконтроллер) от двух батареек потребляет 0.5 мА в активном режиме(отрабатывая скетч из Arduino IDE), и знаете почему?
    Она работает на 1МГц!


    Удивляет то, что коль уж зацепились с фьюзами, не перешли хотя-бы на 8МГц (внутренний генератор)


    А впрочем, не удивляет — сам столкнулся со следующей вещью — многие библиотеки заточены именно под частоту Атмеги 16МГц!


    Пример — библиотека того-же DHT11/DHT22 — прекрасно работает на быстрой версии Arduino,
    на версии Pro Mini 8Mhz 3.3В приходится править саму библиотеку, и дело не в напряжении — проверял, но даже с правками — работа нестабильна.
    AM2320 — аналогичная картина.


    А вообще автор-молодец!


    1. Polaris99
      08.10.2019 14:05

      многие библиотеки заточены именно под частоту Атмеги 16МГц
      П — платформонезависимость! Ардуино во всей своей красе.


      1. gerasimenkoao
        08.10.2019 14:33

        Вы хотите сказать, что для микроконтроллеров есть библиотеки, одинаково работающие и на Atmega328, и на STM32, и на ESP8266???


        Вот хотя-бы для DHT22


        1. Polaris99
          08.10.2019 14:42
          +1

          То есть, зависимость от частоты кварца — это нормально, Вы это хотите сказать? Да в гробу я видал такие библиотеки, которые даже в рамках одной модели микроконтроллера не способны нормально работать. А судя по Вашим словам, в мире Ардуино это нормально.


          1. iig
            09.10.2019 10:56

            Наверное, есть библиотеки, пихающие данные в регистры напрямую, но не умеющие в F_CPU.


          1. FGV
            09.10.2019 18:49

            рамках одной модели микроконтроллера не способны нормально работать.

            да как бы:


            Atmega328, и на STM32, и на ESP8266

            все разные мк, с абсолютно разной архитектурой и ядрами.


            1. iig
              10.10.2019 12:54

              все разные мк, с абсолютно разной архитектурой и ядрами.

              Как минимум на Atmega328 и на ESP8266 ардуиновский код вполне работает. Так что ардуиновские либы могут работать на разных архитектурах, если под ту архитектуру есть ардуиновское ядро. П — платформонезависимость, ага ;)


              1. FGV
                10.10.2019 16:17

                Как минимум на Atmega328 и на ESP8266 ардуиновский код вполне работает.

                ага. а как реализовано?


                ifdef esp8266

                //шмат кода для есп
                ...


                ifdef atmega

                //шмат кода для атмеги
                ...


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

                Адуриновская обертка единственное что может организовать универсально — программный ногодрыг с уартом. Остальная периферия esp8266/32 фактически не задействуется, собственно понятно почему, иначе универсальности не будет.


                П — платформонезависимость, ага ;)

                Как бы абсолютно не нужная вещь получатся не находите? Уж ногами подрыгать по таймеру / байты по уарту послать это надо страниц 40-20 любого datasheet-а осилить (заодно узнаете архитектуру). Ну или открыть пример из sdk аля gpio / hello world / uart, там и на страницу не наберется.


                1. iig
                  10.10.2019 18:54

                  а как реализовано?
                  ifdef esp8266

                  //шмат кода для есп


                  ifdef atmega

                  //шмат кода для атмеги



                  Если библиотеку писали правильные программисты — то да. Разница в архитектуре будет закодирована на #ifdef'ах, а интерфейсная часть будет одинаковая для любой поддерживаемой платформы.

                  Адуриновская обертка единственное что может организовать универсально — программный ногодрыг с уартом. Остальная периферия esp8266/32 фактически не задействуется, собственно понятно почему, иначе универсальности не будет.


                  Дисплей 1602 по I2C подключается одинаково что к ардуине что к 8266. Никакая периферия вроде не страдает ;)


                  1. FGV
                    11.10.2019 08:36

                    Дисплей 1602 по I2C подключается одинаково что к ардуине что к 8266.

                    Учитывая что у 8266 i2c софтварный то разницы особо нет. Подцепите sd-карточку, или spi-дисплей. Чую на адурине что для 8266 что для avr все через digitalread/write написано.


                    Никакая периферия вроде не страдает ;)

                    А чего ей страдать? Речь о том что она не используется :)


                    1. iig
                      11.10.2019 10:50

                      П — переносимость. О — оптимальность. П != О.

                      Учитывая что у 8266 i2c софтварный то разницы особо нет.


                      В ардуиновском ядре для 8266 своя реализация SPI, софтовая, да. А для тех контроллеров, что умеют поддержку SPI — аппаратная. SPI.h внутри разные, а интерфейсы одинаковые.


  1. igrushkin
    08.10.2019 14:50

    поставил (+) «за старание». но честно говоря, в конце 2019 года хотелось бы видеть какие-то прорывные статьи, а не очередную погодную станцию на античном DHT22


    1. Cadil_TM Автор
      09.10.2019 07:44

      поставил (+) «за старание». но честно говоря, в конце 2019 года хотелось бы видеть какие-то прорывные статьи, а не очередную погодную станцию на античном DHT22

      У каждого свое понимание прорыва. В общем-то, в избитой теме метеостанции я не нашел в Инете решений с питанием базы метеостанции от батареек. Как правило, речь идет о аккумуляторах, солнечных батареях и т.п.
      Осознаю — мое решение не идеальное, но с чего-то надо начинать.
      А что касается DHT22, то это техническая работа — заменить один датчик на другой.
      Успехов!


      1. igrushkin
        09.10.2019 09:35

        те «прорыв» — использование батареек? Разочарую, это не прорыв. Большинство ПС как раз сделано на батарейках, тк у них низкий саморазряд.
        328p далеко не лидер по энергоэффективности, и опять же, странно пользоваться им в 2019 году


        1. Cadil_TM Автор
          09.10.2019 10:25

          Большинство ПС как раз сделано на батарейках, тк у них низкий саморазряд.

          Относительно низкого саморазряда батареек — в этом не надо никого переубеждать. По поводу большинства — хотелось бы хоть один пример, чтобы дополнить сравнительную таблицу приемного узла в статье конкретными результатами из других проектов. Повторюсь, мне таких примеров найти не удалось. Возможно не там искал.
          328p далеко не лидер по энергоэффективности, и опять же, странно пользоваться им в 2019 году

          Учту на будущее.


          1. igrushkin
            09.10.2019 10:28

            откройте для себя сайт mysensors.org и их дочерний сайт openhardware.org, не изобретайте велосипед.
            Вся коммуникация и на lora, и на nrf24 давно реализована в этой библиотеке. С очень эффективным энергосбережением.
            И почитайте про smart sleep


  1. enjoyneering
    08.10.2019 18:54
    +1

    А почему не использовали прерывание — wake on radio, встроенное в чип? Как только SX1278 словил сигнал, он выставляет высокий уровень на DIO4. Atmega328 просыпается делает дела и засыпает до следующего прерывания.

    If a Preamble signal is detected, the Sequencer is switched off. The PreambleDetect signal can be mapped to DIO4, in
    order to request the user's attention. The user can then take appropriate action.


    1. Cadil_TM Автор
      09.10.2019 08:11

      А почему не использовали прерывание — wake on radio, встроенное в чип? Как только SX1278 словил сигнал, он выставляет высокий уровень на DIO4. Atmega328 просыпается делает дела и засыпает до следующего прерывания.

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


      1. enjoyneering
        10.10.2019 04:34

        Приёмник включается по пребыванию таймера встроенного в SX1278 и ест не больше меги. Включился проверил несущую и выключилчился если ничего не нашел. Если нашел, то читаем мой пост выше Иногда полезно заглядывать в datashee. Этим простым спосоьом вы решаете проблему с синхронизацией.


  1. iig
    08.10.2019 21:43

    Если батарейки в комнате, сам датчик снаружи, и между ними провод, непонятно, зачем в этой схеме ещё и радио ?


    1. Cadil_TM Автор
      09.10.2019 08:23

      Уточнил в статье: Метеостанция состоит из двух узлов, назовем их для простоты гигрометром и термометром. Связь между узлами — беспроводная, по радиоэфиру.


      1. iig
        09.10.2019 08:51

        Так то, если под термином "термометр" понимать измеритель температуры, а "гигрометр", соответственно, влажности, то связь между ними особого смысла не имеет. Да и разносить их в конструктивно разные узлы зачем? (Но если хочется, то можно)
        [Зануда офф]


  1. zoldaten
    09.10.2019 15:11

    Вставлю свои 5 копеек, т.к. делал аналогичное решение на esp8266-esp01, которое уже несколько лет работает. Только на улицу у меня «пошел» dht-22.
    Так вот. Зимой датчик замерзает, его едят птицы, он нагревается на солнце, нагревается от стены дома. Чтобы этого не происходило он был погружен в отрезанную горловину пластиковой бутылки, закутанную в фольгу. Кроме того, из-за длины питающих датчик проводов(более метра), он ловит помехи извне, а также на показания влияет сопротивление длины проводов. Немного помогла скрутка проводов в косичку.


  1. VT100
    09.10.2019 20:20

    @Cadil


    1. Неплохо-бы добавить на линии питания конденсатор микрофарад на 100 для облегчения работы батареек.
    2. Контроль питания. С такими сопротивлениями делителя — надо зашунтировать "нижний" конденсатором (10..100 нФ), чтобы данные соответствовали действительности.
      А лучше — измерять напряжение питания полностью встроенными средствами МК. Сконфигурировать опорное напряжение АЦП как напряжение питания и измерять относительно него внутреннее опорное напряжение 1,1 В.

    igrushkin
    "328p далеко не лидер по энергоэффективности, и опять же, странно пользоваться им в 2019 году"
    Правда?


    1. Cadil_TM Автор
      10.10.2019 10:00

      Неплохо-бы добавить на линии питания конденсатор микрофарад на 100 для облегчения работы батареек.

      Для батареек с током короткого замыкания больше 2А (точнее не позволяет измерить шкала моего амперметра) вряд ли нужна помощь при работе с нагрузкой около 10-ти мА.
      Контроль питания. С такими сопротивлениями делителя — надо зашунтировать «нижний» конденсатором (10..100 нФ), чтобы данные соответствовали действительности.

      Я думал над этим и проверял — ставил конденсатор 470 нФ, но изменений в десятых вольта не заметил. Конденсатор, по-моему, важен при подключении к блоку питания — для сглаживания пульсаций напряжения. Для страховки — поставлю.
      А лучше — измерять напряжение питания полностью встроенными средствами МК. Сконфигурировать опорное напряжение АЦП как напряжение питания и измерять относительно него внутреннее опорное напряжение 1,1 В.

      Обязательно реализую этот подход.


      1. VT100
        11.10.2019 08:24

        "Для батареек с током короткого замыкания больше 2А (точнее не позволяет измерить шкала моего амперметра) вряд ли нужна помощь при работе с нагрузкой около 10-ти мА."
        Это для новых. А когда они разрядятся и внутреннее сопротивление вырастет — будет помогать.
        "470 нФ"
        Возможно, эффект маскируется analog_read'ом?


  1. lenz1986
    10.10.2019 17:31

    Nrf52 в любом режиме, выкинуть DS18b20 штука абсолютно бестолковая в батарейных термометрах, поставить хотя бы sht2x — 3x и будет работать от пары АА а лучше от одной LisoCi2 пару лет в режиме шлем инфу каждую минуту. Количество компонентов в разы меньше, стабильность выше.