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

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



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


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


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


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


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


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


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



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


    Внутренний генератор контроллера может не запускаться на частоте 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 МГц, резисторы и др. 4,00
    термометр
    Контроллер ATMEGA328P-PU 1,59
    Датчик температуры DS18B20 0,63
    Приемник-передатчик LoRa Rа-01 3,95
    Макетная плата (стеклотекстолит), монтажные провода, батарейки АА, кварцевый резонатор 16 МГц, резисторы и др. 4,00
    Всего (примерно): 24

    Анализатор




    Мозг анализатора – контроллер ATMEGA328P. Он принимает сигналы с датчика DHT22 и по протоколу SPI взаимодействует с приемником 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 находится под спойлером.


    скетч анализатора
    ```cpp
    /*
    Автономная метеостанция на контроллере ATMEGA328P и питанием от батареек с беспроводным выносным датчиком, анализатор
    https://habr.com/ru/post/470381/
    */

    #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
    {
    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(65000, sleepDevice);
    }

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


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


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


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


    Для сравнения — в таблице ниже приведены характеристики термогигрометра LaCrosse WS-9024IT и анализатора с этого проекта.


    Параметр LaCrosse WS-9024IT Сadil_TM
    Питание 2хАА, 3В, Durasell 2хАА, 3В, GP Ultra+, 1800 мА*ч
    Потребление сна 350 мкА (10 мкА)
    Продолжительность сна   14 мин
    Операционное потребление < 200 мкА 12-18 мА
    Продолжительность работы   около 1 мин
    Период цикла работа/сон 15 мин
    Время эксплуатации около 2 лет около 2,5 мес

    Ток потребления LaCrosse очень сильно «пляшет». В таблице я привел пиковое измеренное значение, чтобы показать порядок потребления: не более двух сотен микроампер.



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


    Основной вклад в потребление сна анализатора (350 мкА) вносит ЖК-дисплей. Если его отключить, то потребление упадет до 10 мкА. Пиковое потребление 18 мА приходится на время приема приемником LoRa сигнала с передатчика, но прием сигнала длится несколько микросекунд. Это время очень мало по сравнению с минутой работы приемника в режиме прослушивания и потреблением 10 мА, поэтому я не стал учитывать этот кратковременный пик при расчете времени работы на одном комплекте батареек.


    Расчет времени работы.
    Средний ток потребления: 10 мА / 15 + 0,35 мА = 1,0 мА, где 15 – скважность. Время эксплуатации: 1800 мА*час / 1,0 мА = 1800 час (2,5 мес).
    Уточню:
    — Расчет очень приблизительный.
    — Время работы LaCrosse приведено, исходя из собственного опыта. Этот девайс у меня давно.


    Термометр



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



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


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



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


    скетч термометра
    /*
      Автономная метеостанция на контроллере ATMEGA328P и питанием от батареек с беспроводным выносным датчиком, термометр
    https://habr.com/ru/post/470381/
    */
    
    #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);
      }
      LoRa.setTxPower(4); //мощность передатчика 2-20 дБ
    
      /* 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; //уменьшение разрядности заполнения счетчика
    }

    Пара передатчик-приемник LoRa обеспечивает устойчивую связь на расстоянии 1,5 км при прямой видимости и до 300м в условиях городской застройки, естественно, на максимальной или близкой к максимальной мощности передатчика: 17-20 дБ. Для устойчивой связи в пределах квартиры оказалось достаточно 4 дБ.


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


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


    Расчет времени работы.
    Средний ток потребления: 14 мА / 60 + 0,005 мА = 0,24 мА, где 60 – скважность. Время эксплуатации: 1800 мА*час / 0,24 мА = 7500 час (10 мес).
    Предыдущие уточнения относительно точности рассчитанного значения времени работы от одного набора батареек остаются в силе.


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


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

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



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


    Выводы


    • Собранные анализатор и термометр имеют слишком большое потребление тока по сравнению с промышленными образцами.


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


    • Применение радиомодулей LoRa, с программно заданной мощностью передатчика 4 дБ, позволило установить устойчивую связь в пределах квартиры с питанием модулей от двух батареек АА.


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


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

    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 49

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

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

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

            Свежий, неожиданный для меня подход! Обязательно займусь им, не откладывая на будущее.
            Возможно, он присутствует в технологии iT+? Описание технологии мне не удалось найти, но производители ее рекламируют.
              +1
              Я просто предложил решение, которое в голову пришло. Вам же как таковое абсолютное время не нужно — можно и относительным, ни к чему не привязанным обойтись. Решение простое, изменений в аппаратной части не требует — надо только накодить. Вряд ли я изобрёл что-то новое)

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

          Модуль TIDA-00484 TI Design — фантастика! Обязательно посмотрю этот модуль.
        +2
        Такое разительное отличие в операционном потреблении объясняется, на мой взгляд, тем, что контроллеры в любительских схемах запрограммированы на языке Arduino IDE


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

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

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

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

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

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

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

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

                0
                Где можно посмотреть ваш проект? Дополню хотя бы сравнительные таблицы.
                0
                1 раз в 5 минут — это такая скважность, учитывая возможную скорость передачи по BLE, что 2 года от батарейки выглядит издевательством.
                0
                мучаются птому, что изобретают велосипед. Я использую либу MySensors и получаю удовольствие. Сейчас правда перешел на nrf52
                +1
                Если использовать низкоуровневый код и программирование регистров, то разработчику и Ардуина не нужна, так что не вижу никакого противоречия в словах автора :)
                +1
                Давно-давно повторял(не моя придумка) проджект температурного датчика на MSP430 в качестве передатчика был контур на 200Кгц ударно возбуждаемый с ножки микроконтролера — никаких радиомодулей ;). Приёмник такой же контур + усилитель и на компаратор встроенный в МК. Дальность была около 20..25 метров на одной не новой солевой батарейке датчик продержался больше года, потом механически был повреждён сосулькой…
                  +2
                  Такое разительное отличие в операционном потреблении объясняется, на мой взгляд, тем, что контроллеры в любительских схемах запрограммированы на языке Arduino IDE

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


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


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


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


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


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

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

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


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

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

                            да как бы:


                            Atmega328, и на STM32, и на ESP8266

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

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

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

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


                                ifdef esp8266

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


                                ifdef atmega

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


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

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


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

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

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

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


                                  ifdef atmega

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



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

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


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

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


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

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

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

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


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

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


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

                                        У esp8266 есть два аппаратных контроллера spi, а программная реализация spi для адурины — софтовая. Собственно для esp32 где аппаратных контроллеров spi уже три (вобще 4 но юзить можно три) — аналогичная ситуация. Как то это неправильно, особенно если учитывать то что вектор развития современных микроконтроллеров это именно обогачивание периферии (таймеры, шины, дма, итд) и разгрузка программной части от софтварного ногодрыга.

                                          +1

                                          Ардуиновское ядро делает из любого контроллера ардуину :). Если ардуино с ее ногодрыгом (это минус) и низким порогом вхождения (это плюс) достаточно для решения задачи — why not ;) К примеру, зачем в данном проекте можно переживать о 3 аппаратных SPI?

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

                        У каждого свое понимание прорыва. В общем-то, в избитой теме метеостанции я не нашел в Инете решений с питанием базы метеостанции от батареек. Как правило, речь идет о аккумуляторах, солнечных батареях и т.п.
                        Осознаю — мое решение не идеальное, но с чего-то надо начинать.
                        А что касается DHT22, то это техническая работа — заменить один датчик на другой.
                        Успехов!
                          0
                          те «прорыв» — использование батареек? Разочарую, это не прорыв. Большинство ПС как раз сделано на батарейках, тк у них низкий саморазряд.
                          328p далеко не лидер по энергоэффективности, и опять же, странно пользоваться им в 2019 году
                            0
                            Большинство ПС как раз сделано на батарейках, тк у них низкий саморазряд.

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

                            Учту на будущее.
                              0
                              откройте для себя сайт mysensors.org и их дочерний сайт openhardware.org, не изобретайте велосипед.
                              Вся коммуникация и на lora, и на nrf24 давно реализована в этой библиотеке. С очень эффективным энергосбережением.
                              И почитайте про smart sleep
                        +2
                        А почему не использовали прерывание — 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.
                          0
                          А почему не использовали прерывание — wake on radio, встроенное в чип? Как только SX1278 словил сигнал, он выставляет высокий уровень на DIO4. Atmega328 просыпается делает дела и засыпает до следующего прерывания.

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

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

                          +2

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

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

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

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

                              @Cadil


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

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

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

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

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

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

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

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

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

                                Самое читаемое