С чего всё началось

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

В целом это был уже не первый раз, когда я что-то разрабатывал с помощью ИИ. Но предыдущие попытки организовать совместную разработку с коллегой через Git заканчивались на эмоциях: «О, это работает!», «О, круто!», «Ну всё, галочку поставил», «я у мамы программист», «я у мамы дизайнер» и так далее.

А чтобы я этим заболел и думал над функциями, дизайном, SEO, архитектурой, безопасностью и всем вот этим денно и нощно — такое со мной приключилось впервые. Ощущения прикольные: в моменте чувствуешь, как умираешь.

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

У этого вайба есть, конечно, и побочка: засыпал я в три-четыре утра, дописывая или переделывая ранее сделанное, притом что в семь вставать на работу. Семья и близкие начинают думать, что ты сошёл с ума. Попытки объяснить, почему так происходит, особого доверия у родственников не находят, но это же детали))) В моменте тебя от всего этого очень сильно прёт.

Итак, сама идея — автоматизация пасеки — родилась довольно просто: пчеловодством я занимаюсь ровно по тем же методикам, что деды, их деды и, наверное, деды тех дедов… А у нас же XXI век! Роботы где-то не в России уже, наверное, качают мёд на пасеках! Моя пасека — двенадцать ульев на шести сотках в подмосковном СНТ — верх консерватизма.

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

Основная проблема тут, конечно же, весы. Которых у меня не было. Готовые пасечные стоят слишком дорого — в интернете предлагают от 9 до 37 тысяч рублей за один улей. Зато схем для самостоятельной сборки на тензодатчиках хватает с избытком.

Так софтверный проект «просто покодить» привёл меня к паяльнику, флюсу, одному сожжённому стабилизатору и конфликту с ИИ. От идеи до работающего сервиса с железом ушло около двух месяцев — ровно две месячные подписки на ИИ-ассистента, примерно 200 долларов.

Дальше — честный build-log: что купил, как собирал мост из четырёх датчиков, чем тарировал и как всё это работает.

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

Зачем весы под ульем

Классический осмотр — срез в один момент времени. Открыл, посмотрел рамки, прикинул запасы, закрыл. Что было ночью или пока ты на работе — неизвестно.

Что читается по весу:

  • Дневной привес — сила взятка прямо сейчас и конкретно с этого места.

  • Ночная убыль — пчёлы выпаривают воду из нектара, мёд доходит до кондиции.

  • Резкий провал днём — семья отпустила рой. Если приходит уведомление — есть шанс успеть.

  • Плавный минус в безвзяточье — семья проедает корм, пора думать о подкормке.

Полный разбор графика с сезонными данными будет отдельной статьёй. Сейчас — про железо.

Немного о моём опыте: пасека и IT

Пчёлами я занимаюсь пятнадцать лет. Начинал с трёх ульев, потом держал от пяти до десяти, сейчас двенадцать. За этот сезон получилось собрать 270 литров мёда — по весу около 390 килограммов. Пасека — это моё хобби, времени занимает немного, поскольку я пчеловод выходного дня: основные работы — весной (расширение и противороевые методы) и в августе (откачка).

Основная моя работа — в IT: технический руководитель с функциями архитектора на комплексных проектах по автоматизации производств. Проекты крупные, часть предприятий — градообразующие.

Другими словами, автоматизация как класс задач для меня не новость. Новостью оказалось всё, что мельче цеха — паяльник за всю жизнь я держал считаное число раз.

 Я на пасеке: двенадцать семей, многокорпусные ульи — и ни одного грамма данных о том, что внутри происходит.
Я на пасеке: двенадцать семей, многокорпусные ульи — и ни одного грамма данных о том, что внутри происходит.

Принцип: как взвесить улей

Тензодатчик — металлическая балка с наклеенными тензорезисторами. Под нагрузкой балка деформируется на микроны, сопротивление резисторов меняется, и с моста Уитстона снимается разница напряжений — микровольты. Их усиливает и оцифровывает 24-битный АЦП HX711, дальше ESP32 переводит отсчёты в килограммы по калибровочному коэффициенту.

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

Конструкция: сэндвич из двух щитов

Весы — это два щита водостойкой фанеры (ФСФ) толщиной 18 мм, между ними четыре датчика по углам. Улей стоит на верхнем щите, электроника в коробке снизу. Под Дадан на 12 рамок хватает 45×45 см.

Датчик здесь работает опорой: каждый из четырёх тензодатчиков (YZC-161E, корпус 34×34 мм) целиком прикручен к нижнему щиту четырьмя винтами, под каждым я выбрал фрезером 5 мм под прогиб язычка. Язычок свободен с трёх сторон и выступает над корпусом, на его конце — бугорок; верхний щит опирается только на эти четыре бугорка и корпусов датчиков не касается. Язычок прогибается под весом верхнего щита, на котором стоит улей, — это и есть измерение.

Зазор в 5 мм под язычком нужен дважды: как место для прогиба и как защита от перегруза — при перевесе язычок ляжет на нижний щит, а не сломается.

Проверка механики до всякой электроники простая: надавите на верхний щит рукой. Он должен чуть проседать и возвращаться. Стоит колом — нет зазора или пережат крепёж.

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

Снизу по центру — распаячная коробка IP55 85×85×40 мм: в ней HX711, ESP32, плата зарядки TP4056, стабилизатор и аккумулятор. Провода датчиков заводятся через отверстие по центру щита, платы внутри распаячной коробки фиксируются термоклеем. Коробка живёт под ульем. Забегая вперёд: конструкция не слишком удачная, обслуживать её — «одно удовольствие». Лучше размещать коробку ближе к краю, на боковой стенке.

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

Мост Уитстона: главные грабли

Четыре датчика соединяются в мост и дают четыре вывода на HX711: E+, E−, A+, A−. От каждого угла средний (сигнальный) провод идёт на свой контакт платы, а крайние провода соседних углов соединяются кольцом по периметру.

Раскладка цветов у разных производителей разная — паять лучше по картинке из своего комплекта, а не по первой попавшейся из интернета (рекомендация от ИИ, которую получил ещё при пайке))))

Каждый датчик стоит проверить мультиметром до пайки. У живого две пары проводов покажут одинаковое сопротивление (скажем, по 1000 Ом), а третья — их сумму (2000 Ом). Провод, входящий в обе «одинаковые» пары, — средний, сигнальный.

Что видите

Что это значит

~1k / ~1k / ~2k

датчик и провода живые

«1» (обрыв) на любой паре

оторван провод, перелом жилы или лак не зачищен

0 на любой паре

короткое замыкание, датчик под замену

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

Ключевой момент, где я допустил ошибку, — зачем паять, когда можно собрать всё на скрутках, проверить, что работает, а потом уже сделать основательно.

Собрал мост на скрутках — на вид всё было идеально.

Мост не собирался. В мониторе порта Arduino IDE raw стоял ровным нулём — плата не видела датчиков вообще. Мультиметр честно показывал обрыв.

При дебаге агент несколько раз спросил, всё ли я пропаял. Я отвечал: да, да. А потом признался про скрутки — ну тут и началось: я обманщик, время потеряно зря.

Причина — прозрачный лак на проводах тензодатчиков. Выглядит как голый металл, а по факту это изоляция. Скрутка её не пробивает.

Побочный эффект: ещё несколько дней каждый разбор проблемы начинался с вопроса агента «ты точно припаял, а не скрутил снова?». Наверное, я это заслужил))))

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

 Средний провод каждого угла — на свой контакт HX711, крайние — кольцом к соседям.
Средний провод каждого угла — на свой контакт HX711, крайние — кольцом к соседям.

HX711 → ESP32

Четыре провода:

HX711

ESP32 DevKit V1

VCC

3V3

GND

GND

DT (DOUT)

D19 (GPIO19)

SCK

D18 (GPIO18)

Питание HX711 — строго от 3V3, не от 5V/VIN. При пятивольтовом питании линия DT подаёт 5 В на вход ESP32 и может его повредить. Ещё момент: в чужих инструкциях часто фигурируют пины 16/17, которых на гребёнке DevKit V1 просто нет.

VCC на 3V3, GND на GND, DT на GPIO19, SCK на GPIO18.
VCC на 3V3, GND на GND, DT на GPIO19, SCK на GPIO18.

Питание — как по совету ИИ я сжёг стабилизатор

Напрямую от аккумулятора плату питать нельзя: заряженный 18650 даёт 4,2 В, а максимум для ESP32 — 3,6 В. Между ними нужен стабилизатор.

Цепь получилась такая: 18650 → TP4056 (модуль заряда с защитой DW01) → MCP1700-3302E → пин 3V3 ESP32. Зарядка через USB-C разъём TP4056, отпаивать ничего не нужно.

Конденсаторы не опциональны: 1 мкФ между VIN и GND стабилизатора, 1 мкФ между VOUT и GND, и 470 мкФ на 16 В между 3V3 и GND возле ESP32 — последний гасит всплески тока при передаче по WiFi. Без него плата перезагружается ровно в момент отправки данных.

Дымная часть. У MCP1700 средняя ножка — не земля.

У большинства стабилизаторов в корпусе TO-92 средняя ножка как раз GND, и это знание, вероятно, стало общим местом и для ИИ-моделей. У MCP1700 распиновка другая: плоской стороной с надписью к себе, ножками вниз — 1 это GND, 2 это VIN, 3 это VOUT.

Я паял по инструкции, которую сгенерировала модель, и распиновку в ней принял на веру: спросил, какая ножка плюс, какая минус, получил ответ, припаял. Минус ушёл на среднюю. Чип задымился. Стабилизаторы взял с запасом: второй, уже по даташиту, завёлся сразу.

Отдельно — контроль заряда. Два резистора по 470 кОм делителем от BAT+, средняя точка на GPIO34, нижний конец на GND, и конденсатор 0,1 мкФ со средней точки на GND. Без конденсатора высокоомный делитель шумит на АЦП. Прошивка видит половину напряжения батареи и шлёт её в личный кабинет вместе с весом.

Из важного: пока плата питается через пин 3V3, USB в ESP32 втыкать нельзя — два источника столкнутся. Для перепрошивки провод от стабилизатора отключается.

Начинка версии 1 — выглядит так себе, но работает)))) Частично монтаж на dupont-проводах.
Начинка версии 1 — выглядит так себе, но работает)))) Частично монтаж на dupont-проводах.
Питание с делителем контроля заряда и ключом S1.
Питание с делителем контроля заряда и ключом S1.

Логика прошивки: спать, чтобы экономить заряд

Плата просыпается раз в 10 минут, меряет вес, отправляет и засыпает в deep sleep. После пробуждения ESP32 стартует заново, поэтому вся работа живёт в setup(), а loop() пуст.

Три решения, которые стоит подсветить:

WiFi поднимается параллельно с измерением. Соединение запускается первым делом, и пока оно устанавливается, снимаются отсчёты с датчиков. Эфирное время — самое дорогое по батарее, и так его получается срезать на пару секунд.

HX711 усыпляется явно. scale.power_down() перед сном: иначе модуль ест около 1,5 мА круглосуточно, что для одного 18650 существенно.

tare() не вызывается никогда. Это неочевидно, но принципиально: если обнулять весы при каждом пробуждении, вес улья станет нулём после первой же перезагрузки. Ноль зашит константой и снимается один раз.

Вместе с весом плата шлёт телеметрию: разброс отсчётов, RSSI, счётчик перезагрузок, число неудачных отправок и причину последнего сброса. По ней в кабинете сервиса видно, что происходит с железом, — например, BROWNOUT означает просадку питания, а не случайный глюк.

Прошивка целиком

Программировать не нужно: скетч вставляется в Arduino IDE как есть, меняются три строки в самом верху — имя WiFi-сети, пароль и токен из личного кабинета. Плата — DOIT ESP32 DEVKIT V1, библиотека HX711 by Bogdan Necula.

Скрытый текст
/*
 * onlybee.ai — весы улья: ESP32 DevKit v1 + HX711.
 * Плата просыпается раз в 10 минут, меряет вес, шлёт в сервис и засыпает.
 * После deep sleep ESP32 стартует заново, поэтому вся работа в setup(), loop() пуст.
 * Ноль зашит константой (tare() НЕ вызываем — иначе вес улья обнулится при пробуждении).
 * Токен привязан к улью в личном кабинете, номер улья в прошивке не нужен.
 *
 * Железо: DOIT ESP32 DEVKIT V1, HX711 (DT→GPIO19, SCK→GPIO18, VCC→3V3, GND→GND).
 */
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <esp_system.h>
#include <esp_sleep.h>
#include <limits.h>
#include "HX711.h"

// ─────────── ЗАПОЛНИ ЭТИ 3 СТРОКИ ───────────
const char* WIFI_SSID = "МОЯ_СЕТЬ";          // имя WiFi-сети — только 2.4 ГГц!
const char* WIFI_PASS = "ПАРОЛЬ_СЕТИ";
const char* PAT       = "onbee_ВАШ_ТОКЕН";   // токен из мастера «Подключить весы»
// ────────────────────────────────────────────

const char* API_URL = "https://onlybee.ai/api/sensor/readings";

// Калибровка — снимается на шаге 5 гайда, в финальной сборке:
// OFFSET = значение raw при пустой платформе; CAL_FACTOR = units ÷ вес гири (кг).
// До калибровки оставьте как есть — вес будет в «попугаях», это нормально.
const long  OFFSET     = 0;
const float CAL_FACTOR = 1.0;

const uint64_t SLEEP_MINUTES = 10;   // период отправки, минут
const int HX_DT = 19, HX_SCK = 18, LED_PIN = 2;
const int  SAMPLES     = 10;
const long SPREAD_WARN = 5000;
const uint32_t WIFI_TIMEOUT_MS = 20000;   // не ждём сеть вечно — это батарея

// Переменные в RTC-памяти: переживают deep sleep (обычные — нет)
RTC_DATA_ATTR uint32_t bootCount      = 0;
RTC_DATA_ATTR uint32_t sendFails      = 0;
RTC_DATA_ATTR uint32_t totalUptimeSec = 0;   // время с первого включения (сон + работа)

HX711 scale;

const char* resetReasonStr() {
  switch (esp_reset_reason()) {
    case ESP_RST_POWERON:   return "POWERON";
    case ESP_RST_SW:        return "SW";
    case ESP_RST_PANIC:     return "PANIC";
    case ESP_RST_INT_WDT:   return "INT_WDT";
    case ESP_RST_TASK_WDT:  return "TASK_WDT";
    case ESP_RST_DEEPSLEEP: return "DEEPSLEEP";   // норма при пробуждении
    case ESP_RST_BROWNOUT:  return "BROWNOUT";    // просадка питания — тревога
    case ESP_RST_EXT:       return "EXT";
    default:                return "OTHER";
  }
}

// Заснуть. Дальше код НЕ идёт: после таймера плата стартует с setup().
void goSleep() {
  scale.power_down();                    // HX711 в сон: иначе жрёт ~1.5 мА круглосуточно
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
  totalUptimeSec += millis() / 1000 + SLEEP_MINUTES * 60;  // копим «возраст» устройства
  Serial.printf("Сплю %llu мин\n", SLEEP_MINUTES);
  Serial.flush();
  esp_sleep_enable_timer_wakeup(SLEEP_MINUTES * 60ULL * 1000000ULL);
  esp_deep_sleep_start();
}

bool sendReading(float kg, long rawAvg, long spread) {
  WiFiClientSecure client;
  client.setInsecure();
  client.setHandshakeTimeout(15);

  HTTPClient http;
  http.setConnectTimeout(10000);
  http.setTimeout(10000);
  if (!http.begin(client, API_URL)) return false;

  http.addHeader("Content-Type", "application/json");
  http.addHeader("Authorization", String("Bearer ") + PAT);

  char body[256];
  snprintf(body, sizeof(body),
    "{\"weightKg\":%.2f,\"rawAdc\":%ld,\"spreadRaw\":%ld,\"rssiDbm\":%d,"
    "\"freeHeap\":%u,\"uptimeSec\":%lu,\"bootCount\":%lu,\"sendFails\":%lu,"
    "\"resetReason\":\"%s\"}",
    kg, rawAvg, spread, WiFi.RSSI(),
    ESP.getFreeHeap(), totalUptimeSec + millis() / 1000, bootCount, sendFails,
    resetReasonStr());

  int code = http.POST((uint8_t*)body, strlen(body));
  if (code > 0) Serial.printf("POST -> %d  %s\n", code, http.getString().c_str());
  else          Serial.printf("POST ERR %d: %s\n", code, http.errorToString(code).c_str());
  http.end();
  return code == 201;
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
  delay(100);

  bootCount++;
  Serial.printf("\n=== onlybee scale === пробуждение #%lu | reset=%s\n", bootCount, resetReasonStr());

  // WiFi запускаем СРАЗУ и не ждём: пока он поднимается, читаем вес.
  // Так эфирное время (самое дорогое по батарее) короче на пару секунд.
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  scale.begin(HX_DT, HX_SCK);
  scale.set_scale(CAL_FACTOR);
  scale.set_offset(OFFSET);            // ноль зашит — tare() НЕ вызываем!

  if (!scale.wait_ready_timeout(3000)) {
    Serial.println("HX711 не отвечает — проверь DT/SCK/питание");
    sendFails++;
    goSleep();
  }

  long mn = LONG_MAX, mx = LONG_MIN;
  double sum = 0;
  for (int i = 0; i < SAMPLES; i++) {
    long r = scale.read();
    if (r < mn) mn = r;
    if (r > mx) mx = r;
    sum += r;
  }
  long  rawAvg = (long)(sum / SAMPLES);
  long  spread = mx - mn;
  float kg     = (rawAvg - OFFSET) / CAL_FACTOR;

  Serial.printf("вес=%.2f кг | raw=%ld | spread=%ld\n", kg, rawAvg, spread);
  if (rawAvg == 0)                                  Serial.println("  ! raw=0 — DT/SCK/питание HX711");
  else if (rawAvg > 8000000 || rawAvg < -8000000)   Serial.println("  ! рейл — мост открыт, ищи обрыв");
  else if (spread > SPREAD_WARN)                    Serial.println("  ! большой разброс — контакт/качает улей");

  // теперь дожидаемся сеть (она поднималась параллельно)
  uint32_t t0 = millis();
  while (WiFi.status() != WL_CONNECTED && millis() - t0 < WIFI_TIMEOUT_MS) delay(200);

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi FAIL — пропускаю отправку, сплю дальше");
    sendFails++;
    goSleep();
  }
  Serial.printf("WiFi OK  IP=%s  RSSI=%d dBm\n", WiFi.localIP().toString().c_str(), WiFi.RSSI());

  if (sendReading(kg, rawAvg, spread)) {
    sendFails = 0;
    digitalWrite(LED_PIN, HIGH); delay(60); digitalWrite(LED_PIN, LOW);
  } else {
    sendFails++;
  }

  goSleep();
}

void loop() { }   // пусто: между циклами плата спит, работа — в setup()

Калибровка гирей

Два числа превращают «попугаи» в килограммы.

OFFSET — значение raw на пустой платформе. Смотрится в мониторе порта, вписывается в прошивку.

CAL_FACTOR — масштаб. На платформу ставится груз известной массы, значение units делится на вес. Эталон нашёлся дома.

 Метрологический стенд: гиря 16 кг. Точность эталона заводская, повторяемость идеальная.
Метрологический стенд: гиря 16 кг. Точность эталона заводская, повторяемость идеальная.

322608 ÷ 16 = 20163 — вот и весь коэффициент.

Проверка: пустая платформа около нуля, гиря — свой вес. Нажать RST на ESP32 с установленной гирей на платформе: должен снова показать вес гири, а не ноль. Если показывает ноль — где-то остался tare().

Погрешность в граммах для моих задач некритична — интересен не абсолютный вес улья, а его изменение за сутки, и там счёт идёт на сотни граммов и килограммы.

Одно соображение из практики: коэффициент получается тем достовернее, чем ближе эталон к рабочему весу. Гиря 16 кг для улья, который весит десятки килограммов, — пойдёт.

Диагностика: raw расскажет всё

Прошивка пишет в монитор Arduino IDE сырое значение с датчиков. По нему находится почти любая проблема:

Симптом

Причина

Что делать

raw = 0 всегда

линия DT не читается

проверить DT→D19, SCK→D18, питание HX711

raw = 8388607 или −1

мост разорван, обрыв E+ или E−

пары E+/E−/A+/A− должны давать сотни Ом

raw есть, но не реагирует на нажатие

датчики не в мосте, перепутана схема

сверить со схемой из своего комплекта

raw скачет тысячами в покое

холодная пайка

пошевелить провода: где прыгает — там пропаять

плата перезагружается при WiFi

просадка питания

конденсатор 470 мкФ у ESP32

Всё работает, но графики опубликую позже))))

Весы собрал, проверил на пасеке — работают. Но без интернета в СНТ довольно грустно: прошивка умеет ровно одно — проснуться, снять вес, отправить по WiFi и уснуть. Сейчас решаю вопрос интернета на пасеке и надеюсь порадовать весёлыми графиками. Над логикой на ESP ещё поработаю, плюс есть идея передачи через GSM.

Как только WiFi на пасеке появится, опубликую результаты осенней жизни пчелиной семьи с точки зрения веса.

Солнечная панель. Целевая схема — уйти от ручной подзарядки весов совсем. Панель пока выбираю — подойдёт любая стандартная, совместимая с ESP32 по напряжению.

Спецификация и сколько это стоит

 Всё железо версии 1 до сборки: распаячная коробка, четыре тензодатчика, ESP32, модуль HX711, аккумулятор 18650 в держателе, обвязка и провода.
Всё железо версии 1 до сборки: распаячная коробка, четыре тензодатчика, ESP32, модуль HX711, аккумулятор 18650 в держателе, обвязка и провода.

Компонент

Что брать

Кол-во

Цена, ₽

Тензодатчики + HX711

комплект «4 × 50 кг, полумост + модуль HX711»

1 компл.

260

HX711 запасной

модуль АЦП 24 бит

1

115

Контроллер

ESP32-WROOM DEVKIT V1, 30 pin

1

540

Плата заряда

TP4056 + DW01, USB Type-C

1

240

Стабилизатор

MCP1700-3302E, TO-92

1

120

Аккумулятор

18650 Li-ion 3000 мА·ч

1

180

Держатель АКБ

отсек 18650 с проводами

1

80

Конденсаторы

набор керамики + электролит 470 мкФ 16 В

набор

130

Резисторы

470 кОм, набор

2 шт

80

Коробка

распаячная IP55, 85×85×40 (DKC 53785 и аналоги)

1

120

Фанера ФСФ 18 мм

лист 1220×2440

1

1650

Итого

без расходников

≈ 3 515

Расходники

гермоввод, термоусадка, припой, флюс, термоклей

Тензодатчики почти всегда продаются комплектом вместе с HX711, и это дешевле, чем собирать по частям. Отдельный HX711 имеет смысл брать только запасным — что, как показала история со скрутками, не лишнее.

Для сравнения — готовые пасечные весы

Решение

Цена, ₽

Что даёт

Scales4Bee

8 900

Bluetooth и приложение, 0,1–200 кг

ApiMonitor Mobile 1.3

13 000

GSM, данные на сервер каждые 25 минут

ApiMonitor Mobile 1.3 DUO

17 000

то же на два улья

Весы пасечные беспроводные

23 500

беспроводная передача

Bees_V9

36 750

GSM и веб-сервер

Разброс — от 9 до 37 тысяч за один улей. Самоделка выходит ощутимо дешевле.

Куда данные едут дальше

Сырые граммы бесполезны сами по себе — их нужно превратить в выводы: «взяток начался», «пора качать», «возможен рой». Этот слой я делаю в Onlybee.ai. Сервис бесплатный и изначально проектировался под приём телеметрии с весов, но в процессе я увлёкся и добавил функционал, который, по моему мнению, пригодится как начинающим, так и опытным пчеловодам.

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