Авторизация
Регистрация

Напомнить пароль

Безумный дом. Датчик с батарейным питанием на базе ESP8266

Я как-то обещал рассказать, как сделать WiFi датчик для умного дома на базе ESP8266 с батарейным питанием. Тупо подключить батарейку и ничего не предпринять для экономии энергии — не самая лучшая мысль, средний потребляемый ток модуля 70ма, емкость хорошей батарейки АА 1800 — 2700 mAh, хватит ее на 38 часов в лучшем случае. Хотелось бы менять батарейки раз в год или реже.
Вариант с дополнительным к ESP8266 малопрожорливым процессором, например, MSP430, не рассматриваем — батарея все-таки достаточно емкая, постараемся обойтись минимумом дополнительных деталей.

Что пишут в спецификации про потребление тока ESP8266:
  • Deep Sleep mode ~20 uA
  • С выключенным WiFi — 15 mA
  • Полностью все включено — до 150-200 mA в пике

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

Алгоритм следующий — микросхема уходит в глубокий сон, просыпается раз в 10 минут без подключения к сети и измеряет температуру. Не забудьте, для того, чтобы разбудить ESP8266, нужно соединить вход сброса с GPIO16!

Если температура изменилась меньше, чем на пол градуса — засыпаем снова. Раз в час подключаемся к сети и сообщаем — еще живой, напряжение батареи и текущую температуру. Если температура изменилась — подключаемся к сети до истечения часа и передаем новые значения. Не знаю, может я чего-то не понимаю, или задница через два П пишется, но если микроконтроллер заснул с запретом на WiFi, включить WiFi после просыпания мне не удалось. Проще оказалось усыпить его снова на несколько секунд с просыпанием в нормальном режиме, с включенным WiFi.

  if (TimeToUpdate)  
  {
    reset_RTC_counter();
    ESP.deepSleep(FAST_SLEEP_TIME*1000000);  //uS
  }
  else
  {
    if (boot_counter>=5)
    {
      reset_RTC_counter();
      ESP.deepSleep(SLEEP_TIME*1000000);  
    }
    else ESP.deepSleep(SLEEP_TIME*1000000, WAKE_RF_DISABLED);  
  }

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

Здесь спрятан код
void reset_RTC_counter(void)
{
  uint32_t bootcount =0;
  ESP.rtcUserMemoryWrite(0, &bootcount, sizeof(bootcount));  
}

uint16_t RTC_bootcount(void)
{
  uint32_t bootcount;
  uint16_t low_word; 
  uint16_t high_word; 
  uint16_t return_word; 
  ESP.rtcUserMemoryRead(0, &bootcount, sizeof(bootcount)); 
  low_word = bootcount & 0xFFFF;
  high_word = (bootcount>>16) & 0xFFFF;
  if (low_word!=high_word)
  {
    low_word = 0;
    high_word = 0;
  }
  return_word =  low_word;
  low_word++;
  high_word++;
  bootcount = (high_word << 16) + low_word;
  ESP.rtcUserMemoryWrite(0, &bootcount, sizeof(bootcount));
  return (return_word);
}

void SaveFloatRtc(float fnum1, float fnum2)
{
  union
  {
    uint32_t ltemp;  
    float ftemp;
  };
  ftemp = fnum1;
  ESP.rtcUserMemoryWrite(1, & ltemp, sizeof(ltemp));
  ftemp = fnum2;
  ESP.rtcUserMemoryWrite(2, & ltemp, sizeof(ltemp));
}

float GetFloatFromRtc(uint8_t offset)
{
  union
  {
    uint32_t ltemp;  
    float ftemp;
  };  
  ESP.rtcUserMemoryRead(offset+1, & ltemp, sizeof(ltemp)); 
  return ftemp;
}


Схема приведена ниже. Для питания используется преобразователь с повышение напряжения BL8530 с очень маленьким током холостого хода (без подключенных внешних компонентов) — <7uA. Есть преобразователи и более экономичные, но это — аутентичная китайская разработка и продается на Али очень дешево.



Для начала проверим потребление энергии без преобразователя. ESP8266 плюс оба датчика с режиме глубокого сна потребляют около 17мкА и при работе с сетью в среднем около 70мА — как и обещано в описании ESP8266, датчики температуры потребляют пренебрежимо мало.


Поиграемся с преобразователем напряжения.


На выходе рекомендуют ставить конденсатор 100-200 микрофарад. У меня большое изобилие танталовых конденсаторов на 22 микрофарад — их и попытался везде воткнуть. Не пролезло — ток холостого хода оказался почти 80 мкА. Смотрим, что за дела? Видимо, самый короткий генерируемый пульс достаточен, чтобы изрядно перезарядить маленькую емкость, пульсации больше вольта.


Разругавшись с жабой, ставлю на выход 330 мкФ — у меня их мало, а других номиналов в закромах вообще не нашлось. Пульсации ушли, ток холостого хода упал до 16 мкА — с учетом импульсного потребления понятно, что мультиметр будет врать, но и так сойдет.

Почему такая странная конфигурация датчиков, а не просто два одинаковых температурных сенсора? Это долгая история, но я расскажу.
Много лет назад, еще в другой жизни, многие фирмы высылали всем желающим бесплатные образцы микросхем, 3-5 видов, по 2-5 штуки каждого. Все были равны, но в силу служебного положения, я был равнее многих. Мне полагалось от своей фирмы до 50 штук 5 видов в день, желтые штаны и 2 «ку». Не обязательно на свой адрес, мог заказать и в адрес любого потенциального покупателя. Естественно, все это было для работы, но и для личного пользования не возбранялось — без злоупотреблений, конечно. Даже устраивался ежегодный конкурс самоделок среди сотрудников. Условие участия в конкурсе — использование в самоделке микросхем фирмы. Я даже раз в число призеров входил, приз — значок и маечка.


Ну так вот, один раз я заказал какие-то LDO для демо-платы или для тестовой платы, уже не помню. Штук 20 микросхем. Все спаял (вру, конечно — сам не паял) — не работает. Начал разбираться — одна из микросхем имеет непонятные надписи. На пакетике — все правильно, а микросхемы туда затолкали другие, но в таком же корпусе. На работе разбираться, что прислали, было некогда, утащил их домой с надеждой вечером разобраться и заказал новые. До разборок дело дошло лет через 10 :) Эти микросхемы и оказались датчиками температуры и у меня их почти два десятка — надо же их как-то использовать.
Ну а второй сенсор — выносной для измерения температуры на улице или в соседнем помещении. Лучше, чем DS18B20 для этой цели вряд ли что-то найдешь.

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


Корпус проектируется в OpenSCAD. Зачем? Исключительно чтобы позлить некоторых местных специалистов, которые его просто на дух не переносят :)


Для того, чтобы все работало, в Home Assistant, очевидно, нужно установить MQTT сервер и работать уже через него.


Просто натыкать все мышью не получится, нужно ручками редактировать configutation.yaml и кое-чего там дописать, но, когда уже написана программа для ESP8266, это уже совсем несложно.

configutation.yaml
mqtt:
  sensor:
    - name: "Temperature outside"
      state_topic: "garage/sensor/temperature/outside"
      unit_of_measurement: "°C"


    - name: "Temperature inside"
      state_topic: "garage/sensor/temperature/inside"
      unit_of_measurement: "°C"
      

    - name: "Battery Voltage"
      state_topic: "garage/sensor/battery_level"
      unit_of_measurement: "V"      
      
    - name: "Temperature boiler"
      state_topic: "workshop/sensor/temperature/boiler"
      unit_of_measurement: "°C"


    - name: "Temperature workshop"
      state_topic: "workshop/sensor/temperature/inside"
      unit_of_measurement: "°C"
      

    - name: "Workshop Battery Voltage"
      state_topic: "workshop/sensor/battery_level"
      unit_of_measurement: "V"      
      icon: mdi:battery-60 


Теперь нужно добавить свой датчик на панель — тоже ручками, но тут уже просто натыкать мышью.




На всякий случай исходный код — мало ли кому может пригодится.
Исходники
#include <Arduino.h>
#include <Wire.h>
#include <DS18B20.h>
#include <ESP8266WiFi.h>
#include <ArduinoMqttClient.h>

#define DEBUG false
#define Serial if(DEBUG)Serial

#define TMP75_ADDRESS 0x48 

#define TMP75_TEMP_REGISTER 0
#define TMP75_CONF_REGISTER 1
#define TMP75_THYST_REGISTER 2
#define TMP75_TOS_REGISTER 3

#define TMP75_CONF_SHUTDOWN  0
#define TMP75_CONF_OS_COMP_INT 1
#define TMP75_CONF_OS_POL 2
#define TMP75_CONF_OS_F_QUE 3

// time in seconds
//#define SLEEP_TIME 60
#define SLEEP_TIME 600
#define FAST_SLEEP_TIME 10


#define GARAGE 1

// ADC caluibration
#ifdef GARAGE  
  #define CALIB_CODE 0x2AA
  #define CALIB_VOLTAGE 2.78
#else
  #define CALIB_CODE 0x2ee
  #define CALIB_VOLTAGE 3.06
#endif


const char* ssid = "xxxxxx";
const char* password = "xxxxxxxx";
const int channel = 1;
const uint8_t bssid[] = {0xC8, 0x60, 0x00, 0x94, 0x9B, 0x12};
#ifdef GARAGE  
IPAddress ip(192, 168, 0, 150);
#else
IPAddress ip(192, 168, 0, 151);
#endif
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
//IPAddress dns(1,1,1,1);
IPAddress dns(192,168,0,1);

// We make a structure to store connection information 
// The ESP8266 RTC memory is arranged into blocks of 4 bytes. The access methods read and write 4 bytes at a time,
// so the RTC data structure should be padded to a 4-byte multiple.
struct
{
  uint32_t crc32;   // 4 bytes
  uint8_t channel;  // 1 byte,   5 in total
  uint8_t ap_mac[6];// 6 bytes, 11 in total
  uint8_t padding;  // 1 byte,  12 in total
} rtcData;


const char* mqtt_broker = "192.168.0.253";
const int mqtt_port = 1883;
const char* mqtt_username = "homeassistant";
const char* mqtt_password = "quo8gaelai6zah4uthaefaer4theilai0oth0Cai0phoopahShungie5ohs4Chee";  
  

#ifdef GARAGE  
const char *topic[]  = {"garage/sensor/temperature/inside",
                        "garage/sensor/temperature/outside",
                        "garage/sensor/battery_level"};
#else
const char *topic[]  = {"workshop/sensor/temperature/inside",
                        "workshop/sensor/temperature/boiler",
                        "workshop/sensor/battery_level"};

#endif


WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

//uint8_t ds_address[] = {0x28, 0x69, 0xD8, 0x13, 0x00, 0x00, 0x00, 0x9B};
#ifdef GARAGE  
uint8_t ds_address[] = {0x28, 0x13, 0xec, 0x13, 0x00, 0x00, 0x00, 0x57};
#else
uint8_t ds_address[] = {0x28, 0x69, 0xD8, 0x13, 0x00, 0x00, 0x00, 0x9B};
#endif

void TMP75_ctrl(uint8_t ctrl)
{
  Wire.begin();                      // Join the I2C bus as a master 
  Wire.beginTransmission(TMP75_ADDRESS);       // Address the TMP75 sensor
  Wire.write(TMP75_CONF_REGISTER);                       // Address the Configuration register 
  Wire.write(ctrl);                         // Set the temperature resolution 
  Wire.endTransmission();                      // Stop transmitting
}

float readTemp()
{
  uint16_t regdata = 0xFFFF;
  TMP75_ctrl(0xA1); // One-Shot
  Wire.beginTransmission(TMP75_ADDRESS);
  Wire.write(TMP75_TEMP_REGISTER); // pointer reg
  Wire.endTransmission();
  Wire.requestFrom(TMP75_ADDRESS, 2);
  regdata = Wire.read();
  regdata <<= 8;
  regdata |= ((uint16_t)Wire.read());
  return ((float)(int16_t)regdata / 32) / 8;
}




void reset_RTC_counter(void)
{
  uint32_t bootcount =0;
  ESP.rtcUserMemoryWrite(0, &bootcount, sizeof(bootcount));  
}

uint16_t RTC_bootcount(void)
{
  uint32_t bootcount;
  uint16_t low_word; 
  uint16_t high_word; 
  uint16_t return_word; 
  ESP.rtcUserMemoryRead(0, &bootcount, sizeof(bootcount)); 
  low_word = bootcount & 0xFFFF;
  high_word = (bootcount>>16) & 0xFFFF;
  if (low_word!=high_word)
  {
    low_word = 0;
    high_word = 0;
  }
  return_word =  low_word;
  low_word++;
  high_word++;
  bootcount = (high_word << 16) + low_word;
  ESP.rtcUserMemoryWrite(0, &bootcount, sizeof(bootcount));
  return (return_word);
}

void SaveFloatRtc(float fnum1, float fnum2)
{
  union
  {
    uint32_t ltemp;  
    float ftemp;
  };
  ftemp = fnum1;
  ESP.rtcUserMemoryWrite(1, & ltemp, sizeof(ltemp));
  ftemp = fnum2;
  ESP.rtcUserMemoryWrite(2, & ltemp, sizeof(ltemp));
}

float GetFloatFromRtc(uint8_t offset)
{
  union
  {
    uint32_t ltemp;  
    float ftemp;
  };  
  ESP.rtcUserMemoryRead(offset+1, & ltemp, sizeof(ltemp)); 
  return ftemp;
}

uint32_t calculateCRC32( const uint8_t *data, size_t length )
{
  uint32_t crc = 0xffffffff;
  while( length-- ) 
  {
    uint8_t c = *data++;
    for( uint32_t i = 0x80; i > 0; i >>= 1 ) 
    {
      bool bit = crc & 0x80000000;
      if(c & i) bit = !bit;
      crc <<= 1;
      if(bit) crc ^= 0x04c11db7;
    }
  }
  return crc;
}


void setup_wifi() 
{

  // Try to read WiFi settings from RTC memory
  bool rtcValid = false;
  if( ESP.rtcUserMemoryRead( 3, (uint32_t*)&rtcData, sizeof( rtcData ) ) )
  {
    // Calculate the CRC of what we just read from RTC memory, but skip the first 4 bytes as that's the checksum itself.
    uint32_t crc = calculateCRC32( ((uint8_t*)&rtcData) + 4, sizeof( rtcData ) - 4 );
    if(crc == rtcData.crc32) rtcValid = true;
  }

  if (rtcValid) { Serial.print("WiFi settings ok"); }
  else { Serial.print("WiFi settings fail"); }
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.persistent(false);
  WiFi.mode(WIFI_STA);
  WiFi.config(ip, gateway, subnet, dns);

  if(rtcValid)  WiFi.begin( ssid, password, rtcData.channel, rtcData.ap_mac, true );
  else WiFi.begin(ssid, password);

  uint8_t trial_counter=10;
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
    trial_counter--;
    if (trial_counter==0)
    {
      Serial.println();
      Serial.println("WiFi not availale");
      Serial.println("Deep sleep");
      rtcData.crc32++;  // now crc is wrong
      ESP.rtcUserMemoryWrite( 3, (uint32_t*)&rtcData, sizeof( rtcData ) );
      //reset_RTC_counter();
      ESP.deepSleep(SLEEP_TIME*1000000);        
    }
  }

  if (!rtcValid) 
  {
    // Write current connection info back to RTC
    rtcData.channel = WiFi.channel();
    memcpy(rtcData.ap_mac, WiFi.BSSID(), 6); // Copy 6 bytes of BSSID (AP's MAC address)
    rtcData.crc32 = calculateCRC32( ((uint8_t*)&rtcData) + 4, sizeof( rtcData ) - 4 );
    ESP.rtcUserMemoryWrite( 3, (uint32_t*)&rtcData, sizeof(rtcData));
  }

  Serial.println();
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());  
  Serial.print("nWiFi channel: ");
  Serial.println(WiFi.channel());
  Serial.print("WiFi BSSID: ");
  Serial.println(WiFi.BSSIDstr().c_str());
}



#define ONE_WIRE_GPIO 12
//DS18B20 ds(D6);   //	GPI12
DS18B20 ds(ONE_WIRE_GPIO); 


void setup()
{
  float SensValues[3];
  bool TimeToUpdate = false;
  Serial.begin(115200);
  delay(100);
  Serial.println();

  uint16_t boot_counter;
  boot_counter = RTC_bootcount();

  Serial.println();
  Serial.print("Boot count ");
  Serial.println(boot_counter);

  Wire.begin();  
  Wire.setClock(400000);
  //TMP75_ctrl(0x01); // SD mode 0.5C
  TMP75_ctrl(0x21); // SD mode 0.25C

  float prevT0 = GetFloatFromRtc(0);
  float prevT1 = GetFloatFromRtc(1);


  Serial.print("T©=");
  // check TMP75
  SensValues[0] = readTemp();  
  Serial.print(SensValues[0]);
  Serial.print(", ");
  // check DS18B20
  if (ds.select(ds_address)) SensValues[1] = ds.getTempC();
  else Serial.println("DS18B20 not found!");
  Serial.println(SensValues[1]);

  if(abs(prevT0-SensValues[0])>0.5) TimeToUpdate = true;
  if(abs(prevT1-SensValues[1])>0.5) TimeToUpdate = true;  

  if (boot_counter==0)
  {
    setup_wifi() ;
    delay(100);
    //uint16_t batterylevel = ESP.getVcc(); 


    pinMode(14, OUTPUT);
    digitalWrite(14, HIGH);
    uint16_t batterylevel = analogRead(A0);
    Serial.print("ADC=0x");
    Serial.print(batterylevel, HEX);        
    SensValues[2] = (float)batterylevel/CALIB_CODE*CALIB_VOLTAGE;
    Serial.print(", V=");  
    Serial.println(SensValues[2]);
    
    mqttClient.setUsernamePassword(mqtt_username, mqtt_password);
    if (mqttClient.connect(mqtt_broker)) 
    {
      Serial.println("You're connected to the MQTT broker!");
      for(uint8_t i=0; i<3; i++)
      {
        mqttClient.beginMessage(topic[i]);
        mqttClient.print(SensValues[i]);
        mqttClient.endMessage();
        delay(10);
      }
      SaveFloatRtc(SensValues[0], SensValues[1]);
      mqttClient.poll();
      TimeToUpdate = false;
      delay(500);
    }
    else
    {
      Serial.print("MQTT connection failed! Error code = ");
      Serial.println(mqttClient.connectError());
    }
  }

  Serial.println("Deep sleep mode");
  if (TimeToUpdate)  
  {
    reset_RTC_counter();
    ESP.deepSleep(FAST_SLEEP_TIME*1000000);  //uS
  }
  else
  {
    if (boot_counter>=5)
    {
      reset_RTC_counter();
      ESP.deepSleep(SLEEP_TIME*1000000);  
    }
    else ESP.deepSleep(SLEEP_TIME*1000000, WAKE_RF_DISABLED);  // WAKE_RF_DISABLED
  }
}


void loop() {}


Кормить такое устройство от аккумулятора — по-моему, просто расточительство. Срок службы аккумулятора, в зависимости от технологии, от трех лет для NiMH. Проще и дешевле раз в год поставить новые батарейки. А если очень важны габариты — пуговка 2450 спасет отца русской демократии, при небольших размерах она имеет емкость больше 500 мАч при напряжении 3 Вольта.

На этом у меня пока все, но тему можно развить дальше если не надоело и кому-то надо. Меня умный дом не привлекает и вроде как абсолютно не нужен, все делается исключительно для развлечения — нужно же пенсионеру чем-то заняться. Как в «Кавказской пленнице» — имею возможность купить козу сделать умный дом, но не имею желания.

Самое ценное в этой статье (Имею Мнение — Хрен Оспоришь) — это исходный код. Несмотря на кажущуюся простоту, некоторые вещи или нигде не описаны, либо описание найти не так просто. А все остальное — словесная шелуха вокруг.
Добавить в избранное
+129 +205
свернутьразвернуть
Комментарии (92)
RSS
+
avatar
+2
  • dens17
  • 09 апреля 2023, 21:17
У меня большое изобилие танталовых конденсаторов на 22 микрофарад — их и попытался везде воткнуть.
Желательно рассказать или добавить картинки про танталовые конденсаторы. Для понимания как у них маркируется + и — .
Недавно, одна крупная контора, выпустила видеокарты. И там были танталовые конденсаторы. Только они перепутали полярность, при их запайке на плату видеокарты.
+
avatar
+2
Ориентироваться нужно не на общепринятую маркировку, а на техническую документацию производителя компонента.
+
avatar
+1
такие конденсаторы даже простой цешкой можно определить полярность.
утечка если не в ту сторону бешеная.Попробуйте сами и убедитесь.
у меня был случай когда некоторые из одной партии были маркированы наоборот.
При включении перегрев и «волшебный» дым.
С тех пор всегда сначала проверяю тестером.
+
avatar
0
Я то в курсе, но производитель электроники должен ориентироваться на документацию.
+
avatar
0
Видимо перемаркировка прошла у китайцев неудачно — перепутали полярность.
После покупки перемаркированных танталлов на Али — больше их не беру там принципиально.
+
avatar
-3
Явно не указано, исходники то под что? Arduino?
+
avatar
+11
так там же первая же строка
#include <Arduino.h>
:)
+
avatar
-6
+
avatar
-1
  • sav1812
  • 18 апреля 2023, 02:33
"… но я не понял, что конкретно ты имела в виду!.." :)))
+
avatar
0
Корпус проектируется в OpenSCAD. Зачем? Исключительно чтобы позлить некоторых местных специалистов, которые его просто на дух не переносят :)
Почитал что такое, интересно, пользовать вряд ли буду, да и тридэ как-то не получается, чегойто в голове не хватает или чего-то типа лени с избытком, но в некоторых случаях энное число строк с описанием коробки будут быстрее выдавать результат чем в визуальном редакторе.
+
avatar
0
Автор в одном из предыдущих топиков mysku.club/blog/diy/93683.html убедительно показал всем сомневающимся, что от OpenSCAD'а разумные люди должны держаться подальше. Это только для мазопрограммистов. Ну а если без шуток, то программа реально удобна для параметрических моделей, где надо по-быстрому изменить, условно говоря, какую-нибудь коробку под нужные размеры. Но только если эту коробку уже кто-то написал в OpenSCAD'е для тебя.
+
avatar
0
где надо по-быстрому изменить, условно говоря, какую-нибудь коробку под нужные размеры. Но только если эту коробку уже кто-то написал в OpenSCAD'е для тебя
Ну, не сказал бы. Вчера за 5 минут сделал вот такую модель:
Особых трудностей не испытывал.

Да, проектирование сложных деталей в OpenSCAD может быть затруднительным, но простые создаются достаточно быстро.
+
avatar
0
Мой комментарий — в основном юмористический, отражает лишь моё ощущение (ну и многих других людей). Не сомневаюсь, что при необходимости мог бы разобраться в ОпенСкаде, да честно говоря, там на базовом уровне действительно никакой сложной магии, но у меня уже сложился другой пользовательский опыт. Ломать его нет желания, нет сил, нет нужды.
+
avatar
0
  • bazis13
  • 12 апреля 2023, 14:24
этой модели кучи фасок не хватает. Их можно сделать в пару кликов, а в опенскаде проще оставить всё квадратным.
+
avatar
0
В OpenSCAD'е тоже можно фаски делать «автоматом» (например, minkowski). Только затормозит это так, что можно успеть модель напечатать, пока он посчитает.

Вопрос тут в другом — а нужны ли они? Я последнее время печатаю соплом 0.6 мм, оно автоматически дает скругление радиусом 0.3 мм у любого угла. Для большинства задач этого достаточно.

P.S. В модели выше фаски не нужны, т.к. у неё очень специфическое применение.
+
avatar
0
программа реально удобна для параметрических моделей, где надо по-быстрому изменить, условно говоря, какую-нибудь коробку под нужные размеры
Ну как бы во фьюжине тоже можно создавать параметрические модели, а потом быстро править их только меняя одну цифру в параметре.
+
avatar
0
Я тоже делаю параметрические модели в «Компасе», но там нюансы. Во-первых, «интуитивная» работа мышкой может создавать кучу скрытых проблем, вы должны о них знать. Во-вторых, обе программы достаточно громоздкие, а Fusion ещё и интернета требует куда-то. В-третьих, хотя я в ОпенСкаде работал только с готовыми моделями, но показалось, что для новичка он будет в этом плане (подгонка параметров) попроще. Короче, если для нас с вами инструмент чуждый, это не значит, что он негодный. Кому-то он вообще самый лучший.
+
avatar
+1
  • trekker
  • 11 апреля 2023, 06:49
Openscad помогает мозгам не заржаветь. Его вкус надо прочувствовать, для фанатов.
+
avatar
+2
Собирал схожий датчик протечки.
Логика была, что просыпался раз в 1 минуту, проверял состояние и если все сухо, то дальше в глубокий сон.
А на приёме схожий девайс просыпался раз в 5 минут и если получал аларм, то включал реле и перекрывал воду.
Но я не умею работать с регистром и просто в EPROM писал переменную и когда она достигала 10, то подключался к wifi и говорил что жив и принимал, если надо, новые данные о длительности сна и если надо переводилась в режим прошивки по воздуху.
Питал напрямую от аккумулятора LiOn (4.2v). Плата нормально на этом напряжении работала.
Не смог победить, чтобы ещё напряжение аккумулятора мерить и направлять, это уже обвязки требовало. А так во сне 16мкА ело всего.

Прототип собрал, вроде всё ок и на этом успокоился и купил нормальные датчики aquara на зигби, а на клапан батарею большую (на 3 недели хватает заряда).
В итоге получил интересный опыт работы с esp8266, но понял, что Esp32 рулит, а по энергоэффективности всеже зигби удобнее.
+
avatar
0
  • Johnmat
  • 10 апреля 2023, 00:16
Состояние «все сухо» лучше проверять отдельным датчиком, схема простейшая. И потом им уже включать питание esp. Как датчики открытия герконовые. Тогда батарейка вообще вечная будет.
+
avatar
+9
У меня стоит коммерческая система от протечек. Однажды у меня лопнула труба. Система сработала почти мгновенно (время на срабатывание привода крана). Представил, что могло произойти, если она подождала хотя бы минуту!..

Конечно, наличие любого такого датчика в любом случае лучше, чем его отсутствие. И во многих случаях, когда подкапывает, такое время опроса не критично. Но именно по поводу датчиков протечки, особенно, если есть ещё и приводы, я бы крепко подумал о частоте опроса.
+
avatar
-1
  • sav1812
  • 18 апреля 2023, 02:38
Датчик протечки воды должен быть связан с исполнительным устройством напрямую: элементарное соображение надёжности и безопасности.
А уже «куда надо» он может сообщать «для сведения, в части касающейся»…
+
avatar
0
У ESP8266 есть внутренний «измерятель» напряжения питания, так что напряжение питания можно узнать вообще без обвязки. Но встроенным ADC тогда пользоваться не получится.
+
avatar
0
  • Adei
  • 18 апреля 2023, 19:10
Этот датчик работает только тогда, когда питание подключается непосредственно от источника, а если подключать через преобразователь, то пользы будет немного. То есть, если через понижающий преобразователь, который всё, что ниже целевого напряжения, пропускает напрямую, тогда да, можно. Например, если так питать от литиевого аккумулятора: пока напряжение выше, чем 3,3 В, оно понижается до 3,3, а потом, когда напряжение становится ниже, контроллер начинает это видеть. А в случае повышающего преобразователя, как в примере, пользы от внутреннего измерения всё равно не будет.
+
avatar
+5
Не знаю, может я чего-то не понимаю, или задница через два П пишется, но если микроконтроллер заснул с запретом на WiFi, включить WiFi после просыпания мне не удалось. Проще оказалось усыпить его снова на несколько секунд с просыпанием в нормальном режиме, с включенным WiFi.
Так, собственно, это же в доке описано:
If you implement deep sleep with WAKE_RF_DISABLED and require WiFi functionality on wake up, you will need to implement an additional WAKE_RF_DEFAULT before WiFi functionality is available.
+
avatar
+3
  • Ammo1
  • 09 апреля 2023, 23:38
А зачем нужен преобразователь напряжения? ESP8266 отлично работает от двух батареек без всяких преобразователей.
+
avatar
+1
Может быть, чтобы работал дольше и стабильней? BL8530 стартует от 0,8 В, то есть способен высосать батарейки досуха.
+
avatar
0
Даже при 1В входного напряжения микросхема BL8530-331 не способна отдать больше 50 мА в нагрузку (выходное напряжение «проседает» ниже 3,15В)
при работе с сетью в среднем около 70мА
+
avatar
+1
  • Ammo1
  • 10 апреля 2023, 09:40
Мне кажется там будет такая минимальная разница по времени работы, что заморачиваться не стоит, хотя конечно лучше бы сравнить.
+
avatar
0
Конечно, нужно проверять, но я знаю немало устройств, которые работают от батареек, но уже не хотят работать от аккумуляторов. То есть падение напряжения до 1,2 В на элемент оказывается критическим, а энергии при этом остаётся ещё много.
+
avatar
+2
  • Ammo1
  • 10 апреля 2023, 11:29
1.2 В это 50% разряда батареек. Странно, что какие-то устройства в состоянии использовать только половину ёмкости батареек.
Ну и на аккумуляторах конечно не 1.2 В на самом деле, а 1.4 на старте.
+
avatar
0
  • sim31r
  • 16 апреля 2023, 21:45
С учетом потребления стабилизатора, время работы может уменьшится! Можно по кривым разряда проверить.
+
avatar
0
Вот делал, и без преобразователя досуха выходит.
+
avatar
+2
Практика — наше всё. Но у вас там написано остаточное напряжение 2,46 В на пару, окисление учитывать не будем. Это как бы 1,23 вольта на элемент, чуть выше Алексей (Ammo1) написал про ползаряда батарейки.

Собственно, моя первоначальная реплика была просто предположением, я не могу отвечать за автора, но исхожу из того, что он опытный разработчик «железа», работавший в супер крутой корпорации TI, куда не всякого возьмут. И дополнительный чип поставил не просто так, а со смыслом. Помимо «высасывания» энергии, кстати, не забудьте фактор стабилизации напряжения, без которого то или иное устройство может преподнести сюрпризы.
+
avatar
0
0.5 Ом внутреннего сопротивления батарей не смогут работать даже с преобразователем.
+
avatar
0
  • Adei
  • 18 апреля 2023, 21:02
Если я правильно понял, что получается сделать с этой повышайкой, то использовать две батарейки имеет смысл, но тоже с преобразователем: тогда она будет работать даже при 0,4В на элемент. Но тут ещё всплывает вопрос, какой ток такой преобразователь на самом деле сможет дать при входном напряжении 0,8В.
+
avatar
+1
Ваши цифры:
1. 8912*5/60/60=12,36 часов в активном режиме работы.
2. 473*24-12,36=11339,64 часов во сне.
3. 11339,64*0,016=181мА*ч было потрачено во сне, и я это исправлю в следующей версии датчика.
В данном обзоре написано:
средний потребляемый ток модуля 70ма
Итого, 12.36*70 + 181 = 1046 мАч. Примерно столько вы получили от элементов питания. А это половина или даже меньше. То, что у вас один элемент «потек» и внутреннее сопротивление увеличилось до 0.5 Ом — вопрос отдельный, причины которого надо изучать. Но по цифрам вы потратили меньше половины емкости батареек, что примерно соответствует финальному напряжению.

Оптимальным решением будет, скорее всего, таймер + преобразователь, т.к. это позволит снизить ток сна и иметь стабильное питание. Но сильно ли таймер нужен? Допустим, преобразователь потребляет те самые 16 мкА. Это 140 мАч в год. Или 5-7% емкости батарей. Если ESP во сне потребляет еще столько же, это 10-15% емкости в сумме.

Есть ли смысл в оптимизации? Боюсь, что нет, т.к. срок службы батарей определяется не только емкостью, сделать устройство, которое отработает от одного комплекта 10 лет всё равно не выйдет (и ваш опыт с потекшей батарейкой это только доказывает).
+
avatar
0
Я не писал в обзоре но напишу здесь. Обе батареи были по 0.25Ом. Т.е. они обе ушли в мир иной однинаково. То что одна протекла сильнее — этому лишь причина перегрев её при пайке мною. И её защитная рубашка от протекания нарушилась сильнее.
А это значит, что питая от 3В вплоть до 0.5Ом внутреннего сопротивления преобразователь был не нужен.
В моем случае таймер решал не только ток сна но и проблему бесконечного сброса.
Если очень хочется таки преобразователь, то его можно управлять именно таким таймером как у меня.
Подсчёт вами емкости в активном режиме оптимистично занижен, т.к. в течении 5 секунд активности esp имеет пики до 140мА.
Смысл оптимизации есть. Если не уходить в зигби или блэ а цепко держаться за старый esp то стоит посмотреть esp now, где активность радио будет не 5 сек а единицы миллисекунд, и о чудо, двух АА хватит существенно на дольше. Моё ИМХО
+
avatar
0
А это значит, что питая от 3В вплоть до 0.5Ом внутреннего сопротивления преобразователь был не нужен.
Интересно, почему так вышло и сколько на самом деле осталось энергии в батарейках. Т.к. напряжение 1.25 В говорит, что осталось примерно половина, но вот сопротивление 0.25 Ом — как-то многовато для половины. И с чем связана такая странная кривая разряда.
+
avatar
0
Я замерял напряжение на открытой цепи, и любая нагрузка в 10 мА это напряжение бы уводила в полное «нет». Думаю разряд был полным, просто мелкие остатки активной массы в батарейке делали видимость неполного разряда без нагрузки.
Помню, когда сделал и повесил, то делал ставки: ну на 2 недели. Ну месяц, ну 2 месяца, ну ок, три. Ну полгода продержится и хорошо:) Когда прошёл год, то уже стало интересно как долго :)
+
avatar
+1
  • Johnmat
  • 10 апреля 2023, 00:11
Если работать с ХА, то все реализуется штатными средствами esphome, не так забубенно конечно :) а просто каждые 15 минут отсылка всех данных. На батарейке lifepo4 в 250 mah работает два-три месяца (на балконе). На 750 mah до полугода (уличный). Шлет напряжение батареи, так что снимаем и заряжаем когда надо, и снова в работу. Конечно, никаких преобразователей, да и холод держит неплохо.
+
avatar
0
Покажите, пожалуйста, как. Я имею ввиду код.
+
avatar
+1
возможно, где-то так:
esphome:
  name: t01c3_02
  platformio_options:
    board_build.variant: esp32c3
    board_build.flash_mode: dio
    # run with 80 MHz
    board_build.f_cpu: 80000000L

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: arduino
    version: dev
    platform_version: https://github.com/platformio/platform-espressif32.git#feature/arduino-upstream

deep_sleep:
  run_duration: 1min
  sleep_duration: 1min
сам не проверял, но попробую когда-нибудь.
+
avatar
+2
  • Nuts_
  • 10 апреля 2023, 00:55
хотелось бы про энергофээективные режимы в esp32 читать
там же отдельное ядро под это дело со своим программированием.
хабр это в конце концов или не хабр…
ой сорри ошибся окошком :) :)
+
avatar
+1
  • sim31r
  • 16 апреля 2023, 21:48
У Chat GPT можно спросить, он всё знает
Ниже приведен пример кода, который включает режим Deep Sleep на 30 секунд:

#include <esp_sleep.h>

void setup() {
// Подключаем GPIO16 к RST
pinMode(GPIO_NUM_16, INPUT_PULLUP);
esp_sleep_enable_timer_wakeup(30 * 1000000);
}

void loop() {
// Переводим устройство в режим Deep Sleep
esp_deep_sleep_start();
}

После выполнения этого кода устройство будет находиться в режиме Deep Sleep в течение 30 секунд, после чего оно проснется и начнет выполнять код снова. В режиме Deep Sleep все периферийные устройства отключены, так что устройство потребляет очень мало энергии.
+
avatar
0
  • Phanex
  • 10 апреля 2023, 02:02
О, народ, раз уж все тут говорят на умном, можно и я подъеду на кривой козе?

Есть у меня весы Xiaomi body composition 2. И я, когда меряю, пускаю прогу для пересылки данных в Гармин.

Есть у меня пара модулей WeMos d1 Mini. Один взял для превращения кофемашины в умную, а второй — чтобы не брать один, авось пригодится.

И вот думаю присобачить к этим весам. Все равно гонять Хоум ассистент, так что думаю, почему бу не запустить скрипт, который будет с помощью внешнего есп-модуля получать по блютузу данные.
На гитхабе рассказано как засунуть этот модуль в отдельную коробку, а я чешу репу.
И вот не знаю, насколько идея тупа, встроить модуль прямо в весы, запитав от батареек.
Там 3 или 4 АА, питания должно хватить. Но будет сажать.
Можно ли сделать так, чтобы модуль был в глубокой спячке, а включался только тогда, когда загорается определенный сегмент индикатора весов (ещё не разбирал и не замерял, сколько туда идёт вольт и модно ли сегмент отделить от остальных)?

Я вижу так сценарий: весы спят. Я или кто-то из семьи становится на весы. Когда вес измеряется до самого конца (с измерением всех этих сопротивлений ступней), там бежит строка из сегментов индикатора. И если последний загорается, чтобы модуль просыпался, грузился, подключался к вайфаю, опрашивал по BLE весы (благо те доступны ещё минут десять после взвешивания), отсылал данные, а потом снова уходил в спячку.
Я не программировал пока ардуинки, не знаю, насколько «пробуждение по вольтажу» вообще возможно. Если да, то буду ковырять.
+
avatar
0
  • Phanex
  • 10 апреля 2023, 02:05
github.com/RobertWojtowicz/miscale2garmin

Вот тут сам проект. В принципе, ничего не мешает подключить «как есть», будет сажать изредка батарейку, включаясь раз в 7 минут, но хотелось бы целенаправленно.
+
avatar
0
  • fps
  • 10 апреля 2023, 07:12
Я только главного не понял — сколько в итоге это всё проработало на одном комплекте батареек?
+
avatar
0
Месяца полтора протянет.
+
avatar
0
  • fps
  • 10 апреля 2023, 14:20
Смутило, что автор пишет
Проще и дешевле раз в год поставить новые батарейки.
Откуда взялся год? Почему не пол-года и не 5 лет?
+
avatar
0
Автор не добил до конца режим энергосбережения. По тестеру получаются красивые цифры, по секундомеру нет.
+
avatar
+1
У меня год+
+
avatar
0
  • fps
  • 11 апреля 2023, 06:39
У вас схема работы другая, как я понял. У вас оно не просыпается по таймеру — только по событиям. Может сутками спать.
А тут автор пишет про просыпания раз в 10 минут, и у меня большие сомнения что это у него долго протянет.
У меня в примерно таком же режиме работы, ЕСП запитанной напрямую от одной 18650 на год автономности не хватает.
+
avatar
0
Почитайте внимательнее. Одна перемычка и по таймеру. 8 тыс срабатываний — легко
+
avatar
0
  • fps
  • 11 апреля 2023, 07:51
8 тыс срабатываний — это действительно легко
Но раз в 10 минут, в течение года — это не 8 а 80+ тысяч )
+
avatar
0
Мне кажется, вы упускаете одну вещь — раз в 10 минут устройство включается без wifi — т.е. оно и время работы сильно меньше, и ток потребления тоже. А с wifi оно включается раз в час — вот тогда оно отрывается по полной.
+
avatar
0
  • fps
  • 11 апреля 2023, 09:00
Об этом я помню. У меня аналогичное поведение заложено.
Так сколько у вас реальное время жизни от батареек? Или не было тестов еще?
+
avatar
0
устройство работает только пару недель, напряжение не поменялось. А через год писать уже будет не о чем — во-первых я все забуду, а во-вторых — уже не интересно будет
+
avatar
0
Ага. Потому я обзор выкатил своей поделки существенно позже её создания.
+
avatar
0
  • RW9UAO
  • 10 апреля 2023, 07:16
хе-хе. вход делителя АЦП ключиком оторвал =) наш человек, наш =)
+
avatar
0
Зачеркнуто. Протупил =)
+
avatar
0
  • ufaman
  • 10 апреля 2023, 07:40
Типами диодов-транзисторов можно поинтересоваться?
+
avatar
0
Диоды и транзисторы строго первые попавшиеся, schottky D2 — 1N5819, nMOSFET Q1 — SI2302, pMOSFET Q2 — SI2301. D1 — вообще любой обычный диод. например 1n4148 — дешевле, вроде, сложно найти.
+
avatar
0
В прогамме есть только digitalWrite(14, HIGH);
После сна порт станет на вход?
Или в «0»?
+
avatar
0
там же есть
pinMode(14, OUTPUT);
digitalWrite(14, HIGH);
А после сна и сброса она будет входом.
+
avatar
0
  • fps
  • 10 апреля 2023, 08:13
А после сна и сброса она будет входом.
А где написано, что IO14 после сброса будет входом?
+
avatar
0
А как реагирует HomeAssistant на отсутствие датчиков 10 минут?
Они устанавливаются в недоступные?
+
avatar
0
Если использовать плагин MQTT — то датчик установлен в доступные всегда.
+
avatar
0
Неправда ваша, там можно топик доступности задать.
+
avatar
+1
  • vismyk
  • 10 апреля 2023, 09:39
Для питания используется… BL8530… китайская разработка и продается на Али очень дешево.
Разрешите поворчать? ;)
BL8530 по даташиту выпускаются на фиксированные напряжения (36 вариантов) и для каждого напряжения ещё бывает 6 разновидностей чипа. Итого: 6^3 (216) вариантов. Поэтому выбирать на Али по буквам «BL8530» надо осторожненько… ;)
+
avatar
0
  • Amurzet
  • 10 апреля 2023, 10:17
Не очень в теме. На сколько понимаю, поделки на ESP8266 правильны тем, что поддерживаются «нативно» ESPHOME, позволяют не зависеть от китайских облаков. Но существуют ли готовые изделия на данных чипах (на примере умной розетки wifi)? Обычно это «голые модули» как в обзоре
+
avatar
0
Китайцы эти модули много куда пихают, в «умные» розетки в том числе. Тут недавно был обзор на заводскую метеостанцию например.
+
avatar
0
  • rustamt
  • 10 апреля 2023, 10:56
Они в половине китайских розеток стоят — во всяких sonoff, blitzwolf и прочих. В другой половине — какие-то модули от tuya.
+
avatar
0
  • Phanex
  • 10 апреля 2023, 23:43
От китайских облаков отвязывается почти всё. Для чистого Китая, к примеру, есть OpenBeken, причём во многих случаях можно девайс прошить удалённо через эксплойт с помощью TuyaCloudCutter github.com/tuya-cloudcutter/tuya-cloudcutter
+
avatar
0
  • petrows
  • 15 апреля 2023, 23:47
Конечно, и их очень много. Выберите что-то на свой вкус в каталоге Tasmota supported devices. Там те, что можно прошить на опенсорсную прошивку Tasmota (которая в общем-то уже умеет всё что нужно), либо можно разумеется что-то своё, если надо.

Если вас интересует именно WiFi розетка, то вот раздел с розетками.
+
avatar
0
  • DVANru
  • 10 апреля 2023, 12:20
+
avatar
+1
  • dobs
  • 10 апреля 2023, 12:43
А если к батарее примутить пельтье, не проканает часом ли? Или солнечную с кондером
+
avatar
+2
ночью только данные не получишь. но мысль интересная.
грунтовую батарею забыл на меди и цинке ))
+
avatar
+2
Автор, дайте тогда уж и OpenSCAD-исходник корпуса. Поизучать, как это пишется.
+
avatar
0
Для поизучать я не так давно делал краткое описание здесь mysku.club/blog/diy/93683.html, посмотрите — там моделька простая и полезная.
+
avatar
-3
Начинать сборку датчика на ESP8266 надо с этих статей:
arduinodiy.wordpress.com/2020/01/18/very-deepsleep-and-energy-saving-on-esp8266/
Примеры там присутствуют.
Потом можно узнать, почему датчики температуры ds18b20 не лучший выбор:
community.alexgyver.ru/threads/meteostancija-narodnogo-monitoringa.3529/
Готовый вариант внешнего датчика:
github.com/ghmartin77/ESP8266_BME280
Ну и хороший датчик в метеостанции Андрея Ушакова в Ютубе.
www.youtube.com/watch?v=WZ4iBk451jE
+
avatar
0
  • sav1812
  • 18 апреля 2023, 02:55
Потом можно узнать, почему датчики температуры ds18b20 не лучший выбор:
community.alexgyver.ru/threads/meteostancija-narodnogo-monitoringa.3529/
И там же, если внимательно прочитать, можно узнать, что «Вы просто не умеете их готовить!» :)

Нормальный это выбор, если читать документацию, думать головой и не «задирать» точность измерений этого датчика до максимальной там, где она на фиг не сдалась…
+
avatar
+1
Вот читаю, вас братцы- ничего не понимаю. Но интересно. Хаотично ставлю плюс. Дона люблю, был у меня в корешах в прошлой жизни. Уважаю за оптимизм в весьма непростой жизненной ситуации. Как вспомню чердак, просто «неприличное слово» удивляюсь…
+
avatar
+2
  • miner
  • 15 апреля 2023, 17:44
WiFi.persistent(true) после WiFi.begin() бессмысленно делать, надо до.
Персистентный режим позволяет за 0.6 с. реконнектиться вместо обычных 4.5 с., но у вас он не реализован, плюс в библиотеке ESP8266WiFi.h есть баг.
+
avatar
0
плюс в библиотеке ESP8266WiFi.h есть баг.
А можно детали?
+
avatar
+1
  • miner
  • 15 апреля 2023, 20:54
+
avatar
0
Поправил код — в статье заменил, ускорилось несколько. Пишут, что можно довести подключение до 170 мсек, у меня явно больше. Между полусекундой и секундой. Уже хорошо, а что можно еще сделать?
+
avatar
0
  • miner
  • 16 апреля 2023, 17:45
Больше не могу ничего посоветовать, у меня получились те же 700 мсек, и на этом я остановился. Про 170 мсек читал, но что-то есть сомнения, и вообще информация про persistent коннект в интернете противоречивая.
В теории, время тратится на сканирование каналов, на обмен ключами WiFi и на получение IP по dhcp. Первое и третье решается явной передачей параметров, со вторым непонятно.
+
avatar
0
  • Adei
  • 18 апреля 2023, 21:31
Можно отказаться от использования DHCP и прошивать параметры сети в память контроллера. В код или через конфигурационный сайт — это, думаю, без разницы. Точнее, разница есть, но это уже экономия на спичках, которая теряется из-за «соседа с дрелькой».
+
avatar
0
  • miner
  • 19 апреля 2023, 07:37
Это уже сделано в текущей версии кода в статье
+
avatar
+1
  • Herz
  • 16 апреля 2023, 13:28
Много лет назад, еще в другой жизни, многие фирмы высылали всем желающим бесплатные образцы микросхем, 3-5 видов, по 2-5 штуки каждого.
Эх, помню те славные времена… У меня до сих пор две картонные коробки набиты бесплатными сэмплами, в основном от TI и AD. Казалось, так будет всегда. Ан нет, всё хорошее скоро заканчивается. Знал бы — пять коробок наполнил :)))
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.