- PVSM.RU - https://www.pvsm.ru -
Прошло совсем немного времени с предыдущей публикации о системе за 30$ [1].
Что-же изменилось за прошедший лунный месяц?
Но самое главное, что теперь физически разнесены модуль связи и микроконтроллер, что исключает помехи в его работе с HX711.
И все это благодаря конструктивной критике и пчеловодов, подключившихся к обсуждению системы.
Остальные ТТХ остались прежними — максимальный вес ульев — 200кг, после заката выполняется измерение, и отправка показателей.
Предвосхищая критику по поводу неиспользования режимов сна и дополнительных сигнальных линий GSM-модулей скажу следующее:
У каждого модуля связи есть своя специфика — кто засыпает по низкому уровню сигнала, кто по высокому, некоторые — по двойному нажатию.
Специфика "сделай сам" подразумевает некую творческую часть вот как раз в тут ее и стоит проявить.
Я-же делал систему с прицелом на дальнейшее развитие мониторинга других параметров улья, где сон не особо и нужен.
В общем, на заглавной схеме — чистый андроид базовая система, от которой можно плясать куда угодно с конструкцией и количеством/набором датчиков, модулей ии т.д.
Данная-же статья — о весах, а под катом — мое персональное видение и исполнение системы.
Одним словом — WELCOME! ПОЕХАЛИ!
Для начала эта система не спит… совсем, ибо 6-вольтовая двухватная солнечная батарейка даже в пасмурную погоду выдает 5 вольт и до ста миллиампер.
А потребление всей системы составляет 17мА, в режиме ожидания (в стандарте GSM1800) и около тридцати на GSM900.
К тому-же, как уже говорилось, это сделано с прицелом на реализацию дополнительных функций мониторинга в реальном времени (рой к примеру может выйти за 5 минут) — спать некогда ;-)
Хотите абсолютного энергосбережения, так оно будет в следующей публикации, но это будет совсем другая история система.
Одним словом, выбранные GSM-ки — имхо, единственные, способные без дополнительных плясок с бубнами работать по 4 проводам, включая питание.
Нам понадобится следующий набор оборудования/материалов:
Кроме этого, потребуются некривые руки, паяльник ЭПСН-25, канифоль и припой ПОС-60.
Для столярных работ достаточно ножовки по дереву/металлу, стамески и дрели со сверлом 3мм.
Компоновка системы у нас следующая:
В любом случае, не стоит располагать GSM-модуль ближе метра от Arduino — при высокой мощности сигнала в стандарте GSM900 это может вызывать перезагрузку микроконтроллера!
Ну а модуль связи с солнечной батареей — следует установить на шесте — и прием будет лучше, и от пчел дальше.
Теперь приступим к сборке:
Для начала, выпаиваем из GSM-модуля два светодиода (место, где они находились обведено оранжевым овалом).
Сим-карту вставляем контактными площадками к печатной плате, скошенный уголок на фото обозначен стрелкой.
Плюс от батареи и провода, идущего к контроллеру паяется к конденсатору напрямую (4).
Дело в том, что сам модуль связи требует для своего питания 3.4-4.2В, а его контакт PWR заведен на понижающий преобразователь step-down, поэтому для работы от li-ion напряжение надо подавать минуя эту часть цепи.
Дальше аналогичную процедуру проводим со светодиодом на плате Arduino (овал справа от квадратного чипа).
Паяем гребенку на четыре контакта (1), обязательно горизонтально — вдоль платы.
Фоторезистору укорачиваем ноги до 10мм и паяем его 20-см проводниками к выводам GND и D2 платы (2).
Питание мы заводим через линейный преобразователь — при малых токах потребления, падение напряжения drop-out составляет 0.1В.
Зато подав стабилизированное напряжение на модули HX711, мы избавляемся от необходимости их доработки под меньший вольтаж (и заодно от повышения шумов в результате данной операции).
Теперь необходимо взять 5 метров телефонного четырехжильного кабеля, и распаять между микроконтроллером и модулем связи согласно схеме в начале статьи (цвета проводов соответствуют действительности).
Также паяем держатель батареи, все остальное сделаем немного позже.
А вот теперь мы на некоторое время отвлечемся от паяльника, и перейдем к программной части.
Буду описывать последовательность действий для Windows:
Во-первых, необходимо скачать и установить/распаковать программу Arduino IDE [2] — текущая версия — 1.8.9, но я пользуюсь 1.6.4
Для простоты распаковываем архив в папку C:arduino-"номер_Вашей_версии", внутри у нас будут папки /dist, drivers, examples, hardware, java, lib, libraries, reference, tools, а также исполняемый файл arduino (помимо прочих).
Теперь нам потребуется библиотека для работы с АЦП HX711 [3] — зеленая кнопка "clone or download" — download ZIP.
Содержимое (папка HX711-master) ложится в каталог C:arduino-"номер_Вашей_версии"libraries
Ну и конечно-же драйвер для USB-TTL [4] с того-же github — из распакованного архива просто запускается инсталяха файлом SETUP.
Для тех, кому неохота возиться с библиотеками, я запаковал свою сборку программы Arduino IDE [5] — просто качаем и распаковываем ее.
Запускаем и настраиваем программу 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:
В данной конструкции датчики установлены на позициях 1 и 2, точки 3,4 опираются на брус.
Тогда на сенсоры приходится только половина веса.
Да, такой метод имеет меньшую точность, но все-же трудно представить, чтобы пчелы застроили все рамки "языками" из сот вдоль одной стенки улья.
Так вот, я предлагаю вообще свести датчики в точку 5 — тогда отпадает необходимость в экранировании системы, а при использовании легких ульев и вовсе обходиться одним сенсором.
Итак, на один улей у нас будет устанавливаться два тензодатчика и один модуль HX711 схема распайки следующая:
От платы АЦП до ардуино идет 5 метров 4-жильного телефонного кабеля (в случае модулей веса 2 и 3), первый датчик подключен 10-см "хвостом", но об этом далее.
В общем, на датчиках оставляем "хвосты" по 8см, зачищаем витую пару и все распаиваем как на фото выше.
Прежде, чем начать столярную часть, поставьте воск/парафин в подходящей емкости плавиться на водяную баню.
Теперь берем наш брус и делим на три отрезка по 100мм
Дальше размечаем продольный паз шириной 25 мм, глубиной 7-8мм, с помощью ножовки и стамески убираем лишнее — должен выйти п-образный профиль.
На самом деле, нам нужна одна Н-образная деталь 1 и две — П-шки, все длинной 10 см.
Зачем Н-ка — не поверите, в ней спрячем Arduino:
Кроме того, здесь-же крепятся гнезда 6P6C для подключения датчиков 2 и 3.
Воск разогрелся? — окунаем туда наши платы АЦП — это защитит их от влаги/тумана:
Располагаем это все на деревянном основании(необходимо обработать антисептиком от гниения):
Ну и наконец, фиксируем датчики саморезами:
Далее, паяем все оставшиеся компоненты согласно схеме в шапке и здравому смыслу.
У меня-же вышла следующая конструкция:
Да угол установки панелей я взял 45 градусов — из-за простоты изготовления, но он близок к оптимальным для лета сорока градусам на широте Киева.
Все, теперь для конечной проверки, ставим датчики по секторам круга, сверху — кусок фанеры, обнуляем контроллер (включаем систему с одетым на фотодиод колпачком от авторучки).
При этом должен заморгать светодиод на ардуинке и придти тестовая СМС.
Дальше снимаем с фотоэлемента колпачок, и идем набирать воду в 6 — литровую пластиковую бутылку.
Ставим бутылку на фанеру и если уже прошло несколько минут от включения, одеваем колпачок обратно на фоторезистор (имитируя закат).
При этом светодиод на ардуино загорится, и Вам должна придти СМС со значениями веса около 4кг на всех позициях.
Поздравляю! система успешно собрана!
Если теперь заставить систему сработать повторно, то в первой колонке веса получатся нули.
Да, в реальных условиях фоторезистор желательно ориентировать вертикально вверх.
Теперь приведу кратенький мануал по пользованию:
До полной красоты системы осталось совсем немного:
Во-вторых — может отдавать статистику в виде простых веб-страничек.
Ну и наконец, при наличии вайфай можно вообще отказаться от GSM-ки.
Ах да, что-то мне надоело возиться с проводами, да и обещал систему с "абсолютным" энергосбережением.
Одним словом, я решил немного "пошалить" и все это сделать.
Насколько получится — читайте в публикации через месяц!
До встречи на страницах Хабр-а,
Электропчеловод Андрей
Автор: Андрей Герасименко
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/arduino/314792
Ссылки в тексте:
[1] о системе за 30$: https://habr.com/ru/post/444326/
[2] Arduino IDE: https://www.arduino.cc/en/Main/Software
[3] HX711: https://github.com/bogde/HX711
[4] USB-TTL: https://github.com/HobbyComponents/CH340-Drivers
[5] Arduino IDE: http://zfile.in.ua/download?file=256e2919d32470d78e1c2add52085ec4
[6] Источник: https://habr.com/ru/post/448274/?utm_source=habrahabr&utm_medium=rss&utm_campaign=448274
Нажмите здесь для печати.