Development for IOT
Developing for Arduino
DIY

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

NewBee


Прошло совсем немного времени с предыдущей публикации о системе за 30$.


Что-же изменилось за прошедший лунный месяц?


  1. Добавлена солнечная батарейка — время работы практически неограниченно.
  2. Добавлена отправка информации по звонку.
  3. Возможность работы со всеми видами модулей связи, попавших в поле моего зрения — AiThinker, Goouu tech, SIM800/900, Neoway M590 *

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


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


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


Предвосхищая критику по поводу неиспользования режимов сна и дополнительных сигнальных линий GSM-модулей скажу следующее:


У каждого модуля связи есть своя специфика — кто засыпает по низкому уровню сигнала, кто по высокому, некоторые — по двойному нажатию.


Специфика "сделай сам" подразумевает некую творческую часть вот как раз в тут ее и стоит проявить.


Я-же делал систему с прицелом на дальнейшее развитие мониторинга других параметров улья, где сон не особо и нужен.


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


Данная-же статья — о весах, а под катом — мое персональное видение и исполнение системы.


Одним словом — WELCOME! ПОЕХАЛИ!


Для начала эта система не спит… совсем, ибо 6-вольтовая двухватная солнечная батарейка даже в пасмурную погоду выдает 5 вольт и до ста миллиампер.


А потребление всей системы составляет 17мА, в режиме ожидания (в стандарте GSM1800) и около тридцати на GSM900.


К тому-же, как уже говорилось, это сделано с прицелом на реализацию дополнительных функций мониторинга в реальном времени (рой к примеру может выйти за 5 минут) — спать некогда ;-)


Хотите абсолютного энергосбережения, так оно будет в следующей публикации, но это будет совсем другая история система.


*Да, еще по поводу сноски о модулях связи — не то чтобы я стал адептом AiThinker, просто Neoway нужно еще самому собирать, а модули SIM800L требуют отдельной статьи с ликбезом по работе с ними.


Одним словом, выбранные GSM-ки — имхо, единственные, способные без дополнительных плясок с бубнами работать по 4 проводам, включая питание.


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


  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.
  4. Антенна GSM GPRS "YG-01"

    Как они добились такого усиления — загадка — может это относительно полного отсутствия таковой ;-).
  5. Стартовый пакет оператора, имеющего хорошее покрытие в месте расположения Вашей пасеки.
    Да, пакет надо предварительно активировать в обычном телефоне, ОТКЛЮЧИТЬ ЗАПРОС PIN при входе, и пополнить счет.
  6. провод dupont 20см мама-мама — 4 шт. (для подключения Arduino к USB-TTL)
  7. 3шт. HX711 — АЦП для весов
  8. 6 тензодатчиков на вес до 50кг
  9. 15метров 4-жильного телефонного кабеля — для соединения модулей веса и GSM с ARDUINO.
  10. Фоторезистор GL5528 (важно именно такой, с темновым сопротивлением 1МОм и световым 10-20кОм).
  11. две пары разьемов и гнезд 6P6C — телефонные, гнезда — с "хвостами"
  12. 50см двухстороннего скотча шириной 10мм — для крепления солнечной батареи к корпусу GSM-модуля.
  13. Плата зарядного устройства на базе TP4056 для LiIon батарей
  14. Держатель батарей 18650 и, собственно, сама батарея.
  15. Немного воска или парафина(свеча-таблетка аромалампы) — для влагозащиты HX711
  16. Отрезок деревянного бруса 25х50х300мм для основания тензодатчиков.
  17. Дюжина саморезов с прессшайбой 4,2х19 мм для крепления датчиков к основанию.
  18. Солнечная батарея 5-6V 2W (в соседнем радиомаге не было — взял две одноватные и пару диодов 1N4148)
    Вид панелей сзади
    Через зарядное устройство обратного тока нет, а вот параллельные солнечные модули по-правильному стоит включать через диоды
  19. Коробочка под модуль связи и солнечную батарею(размер 60x100мм) — можно взять подходящую распределительную из электротоваров, у меня идеально подошла пластиковая от визиток 30х60х100.

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


Для столярных работ достаточно ножовки по дереву/металлу, стамески и дрели со сверлом 3мм.


Компоновка системы у нас следующая:


Компоновка


В любом случае, не стоит располагать GSM-модуль ближе метра от Arduino — при высокой мощности сигнала в стандарте GSM900 это может вызывать перезагрузку микроконтроллера!


Ну а модуль связи с солнечной батареей — следует установить на шесте — и прием будет лучше, и от пчел дальше.


Теперь приступим к сборке:


GSM A6


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


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


Плюс от батареи и провода, идущего к контроллеру паяется к конденсатору напрямую (4).


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


Arduino Pro Mini 3v


Дальше аналогичную процедуру проводим со светодиодом на плате Arduino (овал справа от квадратного чипа).


Паяем гребенку на четыре контакта (1), обязательно горизонтально — вдоль платы.


Фоторезистору укорачиваем ноги до 10мм и паяем его 20-см проводниками к выводам GND и D2 платы (2).


Питание мы заводим через линейный преобразователь — при малых токах потребления, падение напряжения drop-out составляет 0.1В.


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


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


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


А вот теперь мы на некоторое время отвлечемся от паяльника, и перейдем к программной части.
Буду описывать последовательность действий для 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.


Для тех, кому неохота возиться с библиотеками, я запаковал свою сборку программы Arduino IDE — просто качаем и распаковываем ее.


Запускаем и настраиваем программу 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 
// NeverSleep
#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  

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;
boolean forceSend=false;

char ch = 0;
char ch1 = 0;
char ch2 = 0;
char ch3 = 0;
char ch4 = 0;

void readVcc() // read battery capacity 
{
  ch = mySerial.read();
   while (mySerial.available() > 0) {  ch = mySerial.read(); } // empty input buffer from modem

 mySerial.println("AT+CBC?"); //ask gprs for battery status (for sim800 and neoway command must be "AT+CBC" )
 delay(200);
 while (mySerial.available() > 0) { //read input string between coma and CR
 ch = mySerial.read();
     if (ch ==','){ 
       ch1 = mySerial.read();
       ch2 = mySerial.read();
       ch3 = mySerial.read();
       ch4 = mySerial.read();       
     }
   }
}

// **********************************************************************
void SendStat() 
{
  detachInterrupt(digitalPinToInterrupt(0)); // turn off external interrupt
   digitalWrite(13, HIGH);  

  if (!forceSend){
  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 || forceSend )
  { 

  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;

  readVcc(); 
  delay(200);
  mySerial.println("AT+CMGF=1");    //  Part of SMS sending 
  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("Battery capacity is ");
  mySerial.print(ch1);
  mySerial.print(ch2);
  mySerial.print(ch3);
  mySerial.print(ch4);
  mySerial.println(" %");
  if (forceSend) {mySerial.print("Forced SMS");}
  mySerial.println (char(26));//the ASCII code of the ctrl+z is 26
  delay(3000);

  }
  forceSend=false;
digitalWrite(13, LOW);
attachInterrupt(0, SendStat , RISING); // Interrupt by HIGH level 
}
// *************************************************************************************************

void switchto9600()
{
mySerial.begin(115200); // Open software serial port
delay(16000); // wait for boot
mySerial.println("AT");
delay(200);
mySerial.println("AT");
delay(200);
mySerial.println("AT+IPR=9600");    //  Change Serial Speed 
delay(200);
mySerial.begin(9600);
mySerial.println("AT&W0");
delay(200);
mySerial.println("AT&W");
}

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

  pinMode(13, OUTPUT);  // Led pin init
  pinMode(2, INPUT_PULLUP); // Set pullup voltage
  Serial.begin(9600);

// -------------------------------------------------------------------------------

switchto9600(); // switch module port speed

// -------------------------------------------------------------------------------

mySerial.begin(9600);

delay(200);
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

readVcc();
delay(200);
  mySerial.println("AT+CMGF=1");    
  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("Battery capacity is ");
  mySerial.print(ch1);
  mySerial.print(ch2);
  mySerial.print(ch3);
  mySerial.print(ch4);
  mySerial.println(" %");
  mySerial.println (char(26));//the ASCII code of the ctrl+z is 26
  delay(3000);

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

attachInterrupt(0, SendStat , RISING); // Interrupt by HIGH level

}

void loop() {

digitalWrite(13, LOW);
ch=mySerial.read();
if ( ch=='R' ) { //wait first lerrer from "RING" string
forceSend=true;
mySerial.println("ATH");
SendStat();
ch=' ';
}

}

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


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


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


Теперь прошивка — тренируемся нажимать красную(серебристую) кнопку микроконтроллера — это нужно будет сделать строго в определенный момент!!!


Есть? Жмем кнопку "Вгрузить" (над двоечкой на скриншоте), и внимательно смотрим на строку внизу интерфейса (под тройкой скрина).


Как только надпись "компиляция" сменится "загрузкой" — жмем красную кнопку (ресет) — если все ок — на USB-TTL адаптере радостно заморгают огоньки, а внизу интерфейса надпись "Вгрузили"


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


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


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


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


На ардуино при этом начнет моргать встроенный светодиод пина 13.
Если сброс не происходит, светодиод загорается на 12 секунд.
После этого отправляется тестовая СМС с сообщением "INITIAL BOOT OK" и процентом заряда батареи.


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


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


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


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


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


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


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


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


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


BroodMinder


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


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


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



От платы АЦП до ардуино идет 5 метров 4-жильного телефонного кабеля (в случае модулей веса 2 и 3), первый датчик подключен 10-см "хвостом", но об этом далее.


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


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


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


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


Основы


На самом деле, нам нужна одна Н-образная деталь 1 и две — П-шки, все длинной 10 см.


Зачем Н-ка — не поверите, в ней спрячем Arduino:


чудо враждебной техники


Кроме того, здесь-же крепятся гнезда 6P6C для подключения датчиков 2 и 3.


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


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


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


Сборка


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


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


Далее, паяем все оставшиеся компоненты согласно схеме в шапке и здравому смыслу.


В плане расположения компонентов, желательно проявить фантазию, стоит учитывать одно — расстояние между микроконтроллером и GSM-модулем должно составлять не менее одного метра!


У меня-же вышла следующая конструкция:


Финал


Да угол установки панелей я взял 45 градусов — из-за простоты изготовления, но он близок к оптимальным для лета сорока градусам на широте Киева.


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


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


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


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


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


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


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


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


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

До полной красоты системы осталось совсем немного:


  1. Добавить аппарантый авторесет системы по фотодатчику.
  2. Проверить другие типы модулей связи.
  3. Сделать все под ESP-8266 — во-первых, он поддерживает обновление прошивок "по воздуху" — удобно же.

Во-вторых — может отдавать статистику в виде простых веб-страничек.
Ну и наконец, при наличии вайфай можно вообще отказаться от GSM-ки.


Ах да, что-то мне надоело возиться с проводами, да и обещал систему с "абсолютным" энергосбережением.


Одним словом, я решил немного "пошалить" и все это сделать.
Насколько получится — читайте в публикации через месяц!


До встречи на страницах Хабр-а,
Электропчеловод Андрей

Стоит-ли продолжать тематику пчеловодства на страницах Хабр-а?
96.1% Да 101
3.8% Нет 4
0% Свой вариант (в комментариях) 0
Voted 105 users. Passed 10 users.
+29
7.9k 82
Comments 23
Top of the day