SMS-мониторинг веса трех ульев за 30$ +28


My Logo


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


Немного предыстории:


Некоторое время назад я решил завести пчел, и они таки появились… на целый сезон, но не вышли из зимовки.
И это несмотря на то, что вроде все делал правильно — осенний прикорм, утепление перед холодами.
Улей был классический деревянный системы "Дадан" на 10 рамок из 40-мм доски.
Но в ту зиму из-за температурных "качелей" даже опытные пчеловоды потеряли куда больше, чем обычно.


Так пришла идея системы мониторинга состояния улья.
После публикации нескольких статей на Хабр-е и общения на форуме пчеловодов, решил идти от простого к сложному.
Вес — единственный бесспорный параметр, но как правило, существующие системы мониторят только один "эталонный" улей.
Если с ним что-то идет не так (к примеру вылет роя, болезнь пчел), то показатели становятся неактуальны.


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


Логика работы следующая: при первом запуске/сбросе запоминаются в EEPROM показания датчиков, установленных под ульи.
Дальше, каждый день, после заката система "просыпается", считывает показания и отправляет СМС с изменением веса за сутки и от момента включения.
Кроме того передается значение напряжения батареи, а при снижении до 3.5В выдается предупреждение о необходимости зарядки, ибо ниже 3.4В модуль связи не включается, да и показания веса уже "уплывают".


"Ты помнишь как все начиналось. Все было впервые и вновь."
How its begin
Да, именно такой набор "железа" был изначально, правда до конечного варианта дожили только тензодатчики и провода, но обо всем по порядку.
На самом деле, бухта кабеля не понадобится, просто она оказалась в ту-же цену, что и 30м наотрез.


Если Ваc не страшит демонтаж 3 smd-светодиодов и пол-сотни точек обычной(выводной) пайки — то в путь!


Итак, нам понадобится следующий набор оборудования/материалов:


  1. Arduino Pro Mini 3V
    Следует обратить внимание на микросхему линейного преобразователя — она должна быть именно на 3.3В — на чипе маркировки KB 33/LB 33/DE A10 — у меня китайцы что-то напутали, и вся партия
    плат в магазине оказалась с 5-вольтовыми регуляторами и кварцами на 16MHz.
  2. USB-Ttl на чипе CH340 — можно даже 5-вольтовый, но тогда во время прошивки микроконтроллера, Arduino нужно будет отключать от GSM-модуля, чтобы не сжечь последний.
    Платы на чипе PL2303 не работают под Windows 10.
  3. Модуль связи GSM Goouu Tech IOT GA-6-B или AI-THINKER A-6 Mini.
    Почему остановился на нем? Neoway M590 — конструктор, требующий отдельных танцев с бубнами, GSM SIM800L — не понравился нестандартный 2.8V уровень логики, требующий согласования даже с трехвольтовой ардуинкой.
    К тому-же, у решения от AiThinker минимальное потребление энергии (при отправке СМС не видел тока выше 100мА).
  4. Антенна GSM GPRS 3DBI (на фото выше — прямоугольная платка с "хвостиком", на 9 часов)
  5. Стартовый пакет оператора, имеющего хорошее покрытие в месте расположения Вашей пасеки.
    Да, пакет надо предварительно активировать в обычном телефоне, ОТКЛЮЧИТЬ ЗАПРОС PIN при входе, и пополнить счет.
    Сейчас есть много вариантов с названиями в стиле "Датчик", "IoT" — у них несколько меньше абонплата.
  6. провод dupont 20см мама-мама — 3 шт. (для подключения Arduino к USB-TTL)
  7. 3шт. HX711 — АЦП для весов
  8. 6 тензодатчиков на вес до 50кг
  9. 15метров 4-жильного телефонного кабеля — для соединения модулей веса с ARDUINO.
  10. Фоторезистор GL5528 (важно именно такой, с темновым сопротивлением 1МОм и световым 10-20кОм) и два обычных резистора на 20к
  11. Кусочек двухстороннего "толстого" скотча 18х18мм — для крепления ардуино к модулю связи.
  12. Держатель батарей 18650 и, собственно, сама батарея ~2600мАч.
  13. Немного воска или парафина(свеча-таблетка аромалампы) — для влагозащиты HX711
  14. Отрезок деревянного бруса 25х50х300мм для основания тензодатчиков.
  15. Дюжина саморезов с прессшайбой 4,2х19 мм для крепления датчиков к основанию.

Батарею можно взять с разборки ноутбуков — в разы дешевле новой, а емкость получится куда больше, чем у китайской UltraFire — у меня получилось 1500 против 450 (это у фаера 6800 ;-)


Кроме этого, потребуются некривые руки, паяльник ЭПСН-25, канифоль и припой ПОС-60.


Soldering iron


Еще 5 лет назад я пользовался советским паяльником с медным жалом (вот не зашли мне паяльные станции — брал на тест-драйв, и заканчивал схему ЭПСН-ом).
Но после выхода его из строя и нескольких китайских чудовищных под(д)елок, последняя имела название Sparta — вещь столь-же суровая, как и название, остановился
на изделии с терморегулятором.


Итак поехали!


GSM A6


Для начала, выпаиваем из GSM-модуля два светодиода (место, где они находились обведено оранжевым овалом)
Сим-крту вставляем контактными площадками к печатной плате, скошенный уголок на фото обозначен стрелкой.


Arduino Pro Mini 3v


Дальше аналогичную процедуру проводим со светодиодом на плате Arduino (овал слева от квадратного чипа),
Паяем гребенку на четыре контакта (1),
Берем два резистора на 20k, скручиваем выводы с одной стороны, паяем скрутку в отверстие контакта A5, оставшиеся выводы в RAW и GND ардуинки (2),
Фоторезистору укорачиваем ноги до 10мм и паяем его к выводам GND и D2 платы (3).


Теперь пришло время синей изоленты двухстороннего скотча — клеим его на держатель сим-карты модуля связи, а сверху — ардуино — красная(серебристая) кнопка обращена к нам и находится над симкой.


Паяем питание: плюс с конденсатора модуля связи (4) на контакт RAW arduino.
Дело в том, что сам модуль связи требует для своего питания 3.4-4.2В, а его контакт PWR заведен на понижающий преобразователь step-down, поэтому для работы от li-ion напряжение надо подавать минуя эту часть цепи.


В ардуино-же, напротив мы заводим питание через линейный преобразователь — при малых токах потребления, падение напряжения drop-out составляет 0.1В.
Зато подав стабилизированное напряжение на модули HX711, мы избавляемся от необходимости их доработки под меньший вольтаж (и заодно от повышения шумов в результате данной операции).


Дальше паяем перемычки (5) между контактами PWR-A1, URX-D4 и UTX-D5, "землю" GND-G (6) ну и наконец питание от держателя батарей 18650 (7), подключаем антенну (8).
Теперь берем USB-TTL преобразователь и соединяем проводами Dupont с ARDUINO (гребенка 1) контакты RXD-TXD и TXD-RXD, GND-GND:


Первая версия


На фото выше — еще первая версия (из трех) системы, которая использовалась для отладки.


А вот теперь мы на некоторое время отвлечемся от паяльника, и перейдем к программной части.
Буду описывать последовательность действий для Windows:
Во-первых, необходимо скачать и установить/распаковать программу Arduino IDE — текущая версия — 1.8.9, но я пользуюсь 1.6.4


Для простоты распаковываем архив в папку C:\arduino-"номер_Вашей_версии", внутри у нас будут папки /dist, drivers, examples, hardware, java, lib, libraries, reference, tools, а также исполняемый файл arduino (помимо прочих).


Теперь нам потребуется библиотека для работы с АЦП HX711 — зеленая кнопка "clone or download" — download ZIP.
Содержимое (папка HX711-master) ложится в каталог C:\arduino-"номер_Вашей_версии"\libraries


Ну и конечно-же драйвер для USB-TTL с того-же github — из распакованного архива просто запускается инсталяха файлом SETUP.


Ок, запускаем и настраиваем программу C:\arduino-"номер_Вашей_версии"\arduino


Интерфейс программы


Заходим в пункт "Инструменты"-выбираем плату "Arduino Pro or Pro Mini", процессор Atmega 328 3.3V 8 MHz, порт — номер кроме системного COM1 (он появляется после установки драйвера CH340 при подключенном USB-TTL адаптере)


Ок, копируем нижеследующий скетч (программу), и вставляем ее в окно Arduino IDE


char phone_no[]="+123456789012"; // Your phone number that receive SMS with counry code 
#include <avr/sleep.h>  // ARDUINO sleep mode library
#include <SoftwareSerial.h> // Sofrware serial library
#include "HX711.h" // HX711 lib. https://github.com/bogde/HX711
#include <EEPROM.h> // EEPROM lib.
HX711 scale0(10, 14);
HX711 scale1(11, 14);
HX711 scale2(12, 14);
#define SENSORCNT 3
HX711 *scale[SENSORCNT];

SoftwareSerial mySerial(5, 4); // Set I/O-port TXD, RXD of GSM-shield  
byte pin2sleep=15; //  Set powerON/OFF pin

float delta00; // delta weight from start
float delta10;
float delta20;
float delta01; // delta weight from yesterday
float delta11;
float delta21;

float raw00; //raw data from sensors on first start
float raw10;
float raw20;
float raw01; //raw data from sensors on yesterday
float raw11;
float raw21;
float raw02; //actual raw data from sensors
float raw12;
float raw22;

word calibrate0=20880; //calibration factor for each sensor
word calibrate1=20880;
word calibrate2=20880;

word daynum=0; //numbers of day after start

int notsunset=0;

boolean setZero=false;

float readVcc() { // Read battery voltage function
  long result1000;
  float rvcc;  
  result1000 = analogRead(A5);
  rvcc=result1000;
  rvcc=6.6*rvcc/1023;
  return rvcc;
}

void setup() { // Setup part run once, at start

  pinMode(13, OUTPUT);  // Led pin init
  pinMode(2, INPUT_PULLUP); // Set pullup voltage
  Serial.begin(9600);
  mySerial.begin(115200); // Open Software Serial port to work with GSM-shield
  pinMode(pin2sleep, OUTPUT);// Itit ON/OFF pin for GSM
  digitalWrite(pin2sleep, LOW); // Turn ON modem
  delay(16000); // Wait for its boot 

scale[0] = &scale0; //init scale
scale[1] = &scale1;
scale[2] = &scale2;

scale0.set_scale();
scale1.set_scale();
scale2.set_scale();

delay(200);

setZero=digitalRead(2);

if (EEPROM.read(500)==EEPROM.read(501) || setZero) // first boot/reset with hiding photoresistor
//if (setZero)
{
raw00=scale0.get_units(16); //read data from scales
raw10=scale1.get_units(16);
raw20=scale2.get_units(16);
EEPROM.put(500, raw00); //write data to eeprom
EEPROM.put(504, raw10);
EEPROM.put(508, raw20);
for (int i = 0; i <= 24; i++) { //blinking LED13 on reset/first boot
    digitalWrite(13, HIGH);
    delay(500);
    digitalWrite(13, LOW);
    delay(500);
  }
}
else {
EEPROM.get(500, raw00); // read data from eeprom after battery change
EEPROM.get(504, raw10);
EEPROM.get(508, raw20);
digitalWrite(13, HIGH); // turn on LED 13 on 12sec. 
    delay(12000);
digitalWrite(13, LOW);
}

delay(200); // Test SMS at initial boot

//
  mySerial.println("AT+CMGF=1");    //  Send SMS part
  delay(2000);
  mySerial.print("AT+CMGS=\"");
  mySerial.print(phone_no); 
  mySerial.write(0x22);
  mySerial.write(0x0D);  // hex equivalent of Carraige return    
  mySerial.write(0x0A);  // hex equivalent of newline
  delay(2000);
  mySerial.println("INITIAL BOOT OK");
  mySerial.print("V Bat= ");
  mySerial.println(readVcc());
 if (readVcc()<3.5) {mySerial.print("!!! CHARGE BATTERY !!!");}
  delay(500);
  mySerial.println (char(26));//the ASCII code of the ctrl+z is 26
  delay(3000);

//  

raw02=raw00;
raw12=raw10;
raw22=raw20;

//scale0.power_down(); //power down all scales 
//scale1.power_down();
//scale2.power_down();

}

void loop() {

  attachInterrupt(0, NULL , RISING); // Interrupt on high lewel
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Set ARDUINO sleep mode
  digitalWrite(pin2sleep, HIGH); // Turn OFF GSM-shield
  delay(2200);
  digitalWrite(pin2sleep, LOW); // Turn OFF GSM-shield
  delay(2200);
  digitalWrite(pin2sleep, HIGH);
  digitalWrite(13, LOW);
  scale0.power_down(); //power down all scales 
  scale1.power_down();
  scale2.power_down();
  delay(90000);
  sleep_mode(); // Go to sleep
  detachInterrupt(digitalPinToInterrupt(0)); // turn off external interrupt

  notsunset=0;
 for (int i=0; i <= 250; i++){
      if ( !digitalRead(2) ){ notsunset++; } //is a really sunset now? you shure?
      delay(360);
   }
  if ( notsunset==0 )
  { 
  digitalWrite(13, HIGH);
  digitalWrite(pin2sleep, LOW); // Turn-ON GSM-shield
  scale0.power_up(); //power up all scales 
  scale1.power_up();
  scale2.power_up();
  raw01=raw02;
  raw11=raw12;
  raw21=raw22;
  raw02=scale0.get_units(16); //read data from scales
  raw12=scale1.get_units(16);
  raw22=scale2.get_units(16);

  daynum++; 
  delta00=(raw02-raw00)/calibrate0; // calculate weight changes 
  delta01=(raw02-raw01)/calibrate0;
  delta10=(raw12-raw10)/calibrate1;
  delta11=(raw12-raw11)/calibrate1; 
  delta20=(raw22-raw20)/calibrate2;
  delta21=(raw22-raw21)/calibrate2;

  delay(16000);
  mySerial.println("AT+CMGF=1");    //  Send SMS part
  delay(2000);
  mySerial.print("AT+CMGS=\"");
  mySerial.print(phone_no); 
  mySerial.write(0x22);
  mySerial.write(0x0D);  // hex equivalent of Carraige return    
  mySerial.write(0x0A);  // hex equivalent of newline
  delay(2000);
  mySerial.print("Turn ");
  mySerial.println(daynum);
  mySerial.print("Hive1  ");
  mySerial.print(delta01);
  mySerial.print("   ");
  mySerial.println(delta00);
  mySerial.print("Hive2  ");
  mySerial.print(delta11);
  mySerial.print("   ");
  mySerial.println(delta10);
  mySerial.print("Hive3 ");
  mySerial.print(delta21);
  mySerial.print("   ");
  mySerial.println(delta20);

  mySerial.print("V Bat= ");
  mySerial.println(readVcc());
  if (readVcc()<3.5) {mySerial.print("!!! CHARGE BATTERY !!!");}
  delay(500);
  mySerial.println (char(26));//the ASCII code of the ctrl+z is 26
  delay(3000);

  }

}

В первой строке, в кавычках char phone_no[]="+123456789012"; — вместо 123456789012 ставим свой номер телефона с кодом страны, на который будут приходить СМС.


Теперь жмем кнопку проверить (над цифрой один в скриншоте выше) — если внизу (под тройкой на скрине) "Компиляция завершена" — то можем прошивать микроконтроллер.


Так, USB-TTL подключен к ARDUINO и компьютеру, ставим заряженный аккумулятор в держатель (обычно на новой ардуинке начинает моргать светодиод с частотой раз в секунду).


Теперь прошивка — тренируемся нажимать красную(серебристую) кнопку микроконтроллера — это нужно будет сделать строго в определенный момент!!!
Есть? Жмем кнопку "Вгрузить" (над двоечкой на скриншоте), и внимательно смотрим на строку внизу интерфейса (под тройкой скрина).
Как только надпись "компиляция" сменится "загрузкой" — жмем красную кнопку (ресет) — если все ок — на USB-TTL адаптере радостно заморгают огоньки, а внизу интерфейса надпись "Вгрузили"


Теперь пока мы ждем прихода тестовой СМС на телефон, расскажу как работает программа:


Вторая версия отладочного стенда


На фото — вторая версия отладочного стенда.


При первом включении система сверяет байты номер 500 и 501 EEPROM если они равны, значит калибровочные данные не записаны, и алгоритм переходит к разделу настройки.
То-же самое происходит, если при включении фоторезистор затенен (колпачком от авторучки) — активируется режим сброса параметров.


Тензодатчики должны уже быть установлены под ульи, так как мы просто фиксируем начальный уровень нуля и дальше измеряем изменение веса (сейчас просто придут нули, поскольку мы ничего еще не подключали).
На ардуино при этом начнет моргать встроенный светодиод пина 13.
Если сброс не происходит, светодиод загорается на 12 секунд.
После этого отправляется тестовая СМС с сообщением "INITIAL BOOT OK" и напряжением батареи.
Модуль связи выключается, и через 3 минуты плата Ардуино переводит платы АЦП HX711 в режим сна и засыпает сама.
Такая задержка сделана что-бы не ловить наводки от работающего GSM-модуля(после выключения он некоторое время "фонит").


Дальше, у нас работает прерывание по фотодатчику на втором пине (включена подтяжка плюса функцией pullup).
При этом после срабатывания еще 3 минуты проверяется состояние фоторезистора — для исключения повторных/ложных срабатываний.
Что характерно, безо всякой настройки система срабатывает через 10 минут после астрономического заката в пасмурную погоду и через 20 в ясную.
Да, чтобы при каждом включении система не делала сброс, должен быть подключен по крайней мере первый модуль HX711(пины DT-D10, SCK-А0)


Потом снимаются показания тензодатчиков, вычисляется изменение веса с предыдущего срабатывания(первое число в строке после Hive) и от первого включения, проверяется напряжение батареи и эта информация отправляется в виде СМС:


Образец работы системы


Кстати, получили СМС? Поздравляю! Мы на середине пути! Батарею пока можно извлечь из держателя, компьютер нам далее не понадобится.


К слову, центр управления полетами получился настолько компактным, что его можно уместить в майонезную баночку, в моем случае отлично подошла полупрозрачная коробочка размером 30х60х100мм (от визиток).


Да, спящая система потребляет ~2.3мА — на 90% за счет модуля связи — он не выключается полностью, а переходит в режим ожидания.


Не Хьюстон


Приступаем к изготовлению датчиков, для начала коснемся схемы расположения сенсоров:


Расположение сенсоров


Это план улья — вид сверху.


Классически, устанавливаются 4 сенсора по углам (1,2,3,4)


Мы-же мерить будем по-другому. А точнее даже по-третьему. Поскольку по-другому делают ребята из BroodMinder:


BroodMinder


В данной конструкции датчики установлены на позициях 1 и 2, точки 3,4 опираются на брус.
Тогда на сенсоры приходится только половина веса.
Да, такой метод имеет меньшую точность, но все-же трудно представить, чтобы пчелы застроили все рамки "языками" из сот вдоль одной стенки улья.


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


Варианты датчиков и сенсоров


В общем, было проверено два вида модулей на HX711, два вида датчиков, и два варианта их соединения — с полным мостом Уитстона(2 сенсора) и с половинкой, когда вторая часть дополняется 1к резисторами с допуском 0.1%.
Но последний способ нежелателен и не рекомендован даже производителями сенсоров, поэтому опишу только первый.


Итак, на один улей у нас будет устанавливаться два тензодатчика и один модуль HX711 схема распайки следующая:



От платы АЦП до ардуино идет 5 метров 4-жильного телефонного кабеля — мы-же помним, как пчелы не любят GSM-устройства в улье.


В общем, на датчиках оставляем "хвосты" по 8см, зачищаем витую пару и все распаиваем как на фото выше.


Прежде, чем начать столярную часть, поставьте воск/парафин в подходящей емкости плавиться на водяную баню.


Теперь берем наш брус и делим на три отрезка по 100мм


Дальше размечаем продольный паз шириной 25 мм, глубиной 7-8мм, с помощью ножовки и стамески убираем лишнее — должен выйти п-образный профиль.


Воск разогрелся? — окунаем туда наши платы АЦП — это защитит их от влаги/тумана:


Защита АЦП от влаги


Располагаем это все на деревянном основании(необходимо обработать антисептиком от гниения):


Сборка


Ну и наконец, фиксируем датчики саморезами:


Готовый датчик


Был еще вариант с синей изолентой но из соображений гуманности его не привожу ;-)


Со стороны Ардуино делаем следующее:


Зачищаем наши телефонные кабеля, цветные жилы скручиваем между собой, лудим.


После этого, паяем к контактам платы как на фото:


Финал


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


При этом должен заморгать светодиод на ардуинке и придти тестовая СМС.


Дальше снимаем с фотоэлемента колпачек, и идем набирать воду в 1.5 литровую пластиковую бутылку.
Ставим бутылку на фанеру и если уже прошло несколько минут от включения, одеваем колпачек обратно на фоторезистор (имитируя закат).


Через три минуты светодиод на ардуино загорится, и Вам должна придти СМС со значениями веса около 1кг на всех позициях.


Поздравляю! система успешно собрана!


Если теперь заставить систему сработать повторно, то в первой колонке веса получатся нули.


Да, в реальных условиях фоторезистор желательно ориентировать вертикально вверх.


Теперь приведу кратенький мануал по пользованию:


  1. Установить тензодатчики под задние стенки ульев (под передние подставить брус/доску толщиной ~30мм)
  2. Затенить фоторезистор и поставить аккумулятор — должен заморгать светодиод и придти тестовая СМС c текстом "INITIAL BOOT OK"
  3. Расположить центральный блок на максимальном удалении от ульев и так, чтобы провода не мешали при работе с пчелами.
    Каждый вечер, после заката будет приходить СМС с изменением веса за сутки и с момента запуска.
    При достижении напряжения батареи значения 3.5В, СМС будет оканчиваться строкой "!!! CHARGE BATTERY !!!"
    Время работы от одной батареи емкостью 2600мАч — около месяца.
    В случае замены батареи, суточные изменения веса ульев не запоминаются.

Что дальше?


  1. Придумать как оформить все это в проект для github
  2. Завести 3 пчелиных семьи в ульях системы Паливоды(или рогатых в народе)
  3. Добавить "плюшек" — измерение влажности, температуры, а главное — анализ жужжания пчел.

Засим пока все, искренне Ваш, электропчеловод Андрей





К сожалению, не доступен сервер mySQL