Пауза между срабатыванием фотодатчика
- Войдите на сайт для отправки комментариев
Доброго времени, всем коллегам и разработчикам.
Коллега я ваш отдаленно, т.к. являюсь веб-разрабочиком, но тем не менее, по совместительству еще и пчеловод. Решил собрать весы с GSM модулем на базе тензодатчиков, ардуино, модуля связи IOT-GA-6.
Т.к. опыт работы с ардуино имел нулевой уровень, то изучал варианты из Сети и остановился на статье одного из со-пчеловодов, который поделился своими наработками.
Изучив, поковыряв и собрав все по схеме удалось запустить систему и даже поставить в рабочую среду под улья. Суть системы в следующем: по фотодатчику происходит считывание данных с тензодатчиков, формирование смс, проверка батареи, сети и отправка этого всего на определенный номер.
Запустив систему в рабочих условиях столкнулся с тем, что фотодатчик реагирует на то ли фонари то ли еще на что-то, но за ночь пришло 94 смс - многократное срабатывание. Я понимаю, что нужно добавлять паузу между считыванием данных с фотодатчика.
Сама функция SendStat запускается по прерыванию, а в режиме прерывания, как я понял, функция delay() не работает, а delayMicroseconds() имеет, насколько я понял, ограничение по значению (читал, что в районе 16000 , не больше можно туда передавать)
Вопрос: подскажите, пожалуйста, возможно ли по этому скетчу сделать, чтобы в ночное время (после заката и до восхода) функция SendStat срабатывала только 1 раз и все, и как это мне правильно описать?
Спасибо за помощь!
Код скетча:
char phone_no[]="+123456789012"; // Your phone number that receive SMS with counry code byte pin2sleep=5; // Set powerON/OFF pin // NeverSleep (only gsm in power-off mode) #include <SoftwareSerial.h> // Sofrware serial library #include "HX711.h" // HX711 lib. https://github.com/bogde/HX711 or beefree.xyz/wp-content/uploads/2019/07/HX711-master.zip #include <EEPROM.h> // EEPROM lib. HX711 scale0(7, 14); HX711 scale1(8, 14); HX711 scale2(9, 14); #define SENSORCNT 3 HX711 *scale[SENSORCNT]; SoftwareSerial mySerial(4, 3); // 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; float swarm0w; //weight data for swarm warning float swarm1w; float swarm2w; float w0; //weight data for swarm warning float w1; float w2; float DeltaW=0; unsigned long swarm0t; //time for swarm warning unsigned long swarm1t; unsigned long swarm2t; unsigned long TimeNow; word calibrate0=20880; //calibration factor for each sensor word calibrate1=20880; word calibrate2=20880; word daynum=0; //numbers of day after start word i; int notsunset=0; int Hwarning=0; int Halarm=0; boolean setZero=false; char ch = 0; char ch1 = 0; char ch2 = 0; char ch3 = 0; char ch4 = 0; char csq = 0; char csq1 = 0; char csq2 = 0; char csq3 = 0; char csq4 = 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 // delay(200); for ( i = 0; i <= 20 ; i++) { delayMicroseconds(10000);} 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 SignalQ() // read signal strenght { csq = mySerial.read(); while (mySerial.available() > 0) { csq = mySerial.read(); } // empty input buffer from modem mySerial.println("AT+CSQ"); //ask gprs for battery status // delay(200); for ( i = 0; i <= 20 ; i++) { delayMicroseconds(10000);} while (mySerial.available() > 0) { //read input string between coma and CR csq = mySerial.read(); if (csq ==':'){ csq1 = mySerial.read(); csq2 = mySerial.read(); csq3 = mySerial.read(); csq4 = mySerial.read(); } } } void Walert() //send swarm/intrusion alert { digitalWrite(pin2sleep, LOW); // Turn ON modem delay(21000); // Wait for modem booting 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); if (Hwarning != 0) // warning about hive invasion { mySerial.println("WARNING!!!"); mySerial.print("Hive "); mySerial.print(Hwarning); mySerial.println(" is opened! "); } if (Halarm != 0) { mySerial.println("ALARM!!!"); // alarm about swarm mySerial.print("Bees in hive "); mySerial.print(Halarm); mySerial.println(" is SWARMING!!! "); } mySerial.println (char(26));//the ASCII code of the ctrl+z is 26 delay(7000); digitalWrite(pin2sleep, HIGH); // Turn OFF GSM-shield delay(2200); digitalWrite(pin2sleep, LOW); // Turn OFF GSM-shield delay(2200); digitalWrite(pin2sleep, HIGH); Hwarning=0; Halarm=0; DeltaW=0; for (int i = 0; i <= 24; i++) { //blinking LED13 on reset/first boot digitalWrite(13, HIGH); delay(250); digitalWrite(13, LOW); delay(250); } } void nolighting() // disable false statistic when night lighting flash { detachInterrupt(digitalPinToInterrupt(0)); for ( i=0; i <= 250; i++){ delayMicroseconds(10000); } // attachInterrupt(0, nolighting , FALLING); // Interrupt by LOW level attachInterrupt(0, SendStat , RISING); // Interrupt by HIGH level } // ********************************************************************** void SendStat() //send weight { detachInterrupt(digitalPinToInterrupt(0)); notsunset=0; // for ( i=0; i <= 250; i++){ // if ( !digitalRead(2) ){ notsunset++; } //is a really sunset now? you shure? // delayMicroseconds(1000); // } if ( notsunset==0 ) { scale0.power_up(); //power up all scales scale1.power_up(); scale2.power_up(); digitalWrite(13, HIGH); digitalWrite(pin2sleep, LOW); // Turn ON modem for ( i = 0; i <= 2100 ; i++) { delayMicroseconds(10000);} raw01=raw02; raw11=raw12; raw21=raw22; raw02=scale0.get_units(240); //warm-up Wheatstone bridges and hx711-s raw02=scale0.get_units(20); //read data from scales raw12=scale1.get_units(20); raw22=scale2.get_units(20); 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(); SignalQ(); // delay(200); for ( i = 0; i <= 20 ; i++) { delayMicroseconds(10000);} mySerial.println("AT+CMGF=1"); // Part of SMS sending //delay(2000); for ( i = 0; i <= 200 ; i++) { delayMicroseconds(10000);} 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); for ( i = 0; i <= 200 ; i++) { delayMicroseconds(10000);} 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(" %"); mySerial.print("GSM signal strenght: "); mySerial.print(csq1); mySerial.print(csq2); mySerial.print(csq3); if (csq4 != ',') {mySerial.print(csq4);} mySerial.println(" of 31"); mySerial.println (char(26));//the ASCII code of the ctrl+z is 26 for ( i = 0; i <= 700 ; i++) { delayMicroseconds(10000);} } digitalWrite(pin2sleep, HIGH); // Turn OFF GSM-shield for ( i = 0; i <= 220 ; i++) { delayMicroseconds(10000);} digitalWrite(pin2sleep, LOW); // Turn OFF GSM-shield for ( i = 0; i <= 220 ; i++) { delayMicroseconds(10000);} digitalWrite(pin2sleep, HIGH); scale0.power_down(); //power down all scales scale1.power_down(); scale2.power_down(); attachInterrupt(0, SendStat , RISING); // Interrupt by HIGH level // attachInterrupt(0, nolighting , FALLING); // Interrupt by LOW 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 scale[0] = &scale0; //init scale scale[1] = &scale1; scale[2] = &scale2; scale0.set_scale(); scale1.set_scale(); scale2.set_scale(); pinMode(13, OUTPUT); // Led pin init pinMode(pin2sleep, OUTPUT);// Init ON/OFF pin for GSM pinMode(2, INPUT_PULLUP); // Set pullup voltage Serial.begin(9600); digitalWrite(pin2sleep, LOW); // Turn ON modem delay(21000); // Wait for modem booting // ------------------------------------------------------------------------------- switchto9600(); //for AiThinker GSM A6 // ------------------------------------------------------------------------------- mySerial.begin(9600); delay(200); setZero=digitalRead(2); //if (EEPROM.read(500)==EEPROM.read(501) || setZero) // first boot/reset with hiding photoresistor if (setZero) { raw02=scale0.get_units(240); //warm-up Wheatstone bridges and hx711-s raw00=scale0.get_units(20); //read data from scales raw10=scale1.get_units(20); raw20=scale2.get_units(20); 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(); SignalQ(); 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.print("GSM signal strenght: "); mySerial.print(csq1); mySerial.print(csq2); mySerial.print(csq3); if (csq4 != ',') {mySerial.print(csq4);} mySerial.println(" of 31"); mySerial.println (char(26));//the ASCII code of the ctrl+z is 26 delay(7000); raw02=raw00; raw12=raw10; raw22=raw20; digitalWrite(pin2sleep, HIGH); // Turn OFF GSM-shield delay(2200); digitalWrite(pin2sleep, LOW); // Turn OFF GSM-shield delay(2200); digitalWrite(pin2sleep, HIGH); //////////////////////////// swarm0w=scale0.get_units(3); swarm0w=scale0.get_units(3); swarm0w=scale0.get_units(8); //set initial data for swarm warning swarm0t=millis(); // set initial time for swarm warning swarm1w=scale1.get_units(8); swarm1t=millis(); swarm2w=scale2.get_units(8); swarm2t=millis(); /////////////////////////// scale0.power_down(); //power down all scales scale1.power_down(); scale2.power_down(); attachInterrupt(0, SendStat , RISING); // Interrupt by HIGH level // attachInterrupt(0, nolighting , FALLING); // Interrupt by LOW level } void loop() { delay(30000); delay(30000); scale0.power_up(); //power up all scales scale1.power_up(); scale2.power_up(); w0=scale0.get_units(3); w0=scale0.get_units(3); w0=scale0.get_units(8); //read data from scales w1=scale1.get_units(8); w2=scale2.get_units(8); scale0.power_down(); //power down all scales scale1.power_down(); scale2.power_down(); TimeNow=millis(); // check Hive 1 swarming or intrusion DeltaW=((swarm0w-w0)/calibrate0); if (TimeNow-swarm0t > 600000 ) { swarm0t=TimeNow; swarm0w=w0; } else { if (DeltaW > 5 ) { Hwarning=1; Walert(); swarm0t=TimeNow; swarm0w=w0; } else {if (DeltaW > 1 ) { Halarm=1; Walert(); swarm0t=TimeNow; swarm0w=w0; } } } // check Hive 2 swarming or intrusion DeltaW=((swarm1w-w1)/calibrate1); if (TimeNow-swarm1t > 600000 ) { swarm1t=TimeNow; swarm1w=w1; } else { if (DeltaW > 5 ) { Hwarning=2; Walert(); swarm1t=TimeNow; swarm1w=w1; } else {if (DeltaW > 1 ) { Halarm=2; Walert(); swarm1t=TimeNow; swarm1w=w1 ; } } } // check Hive 3 swarming or intrusion DeltaW=((swarm2w-w2)/calibrate2); if (TimeNow-swarm2t > 600000 ) { swarm2t=TimeNow; swarm2w=w2; } else { if (DeltaW > 5 ) { Hwarning=3; Walert(); swarm2t=TimeNow; swarm2w=w2; } else {if (DeltaW > 1 ) { Halarm=3; Walert(); swarm2t=TimeNow; swarm2w=w2; } } } }
может достаточно поместить фотодатчик в тубус и направить туда, где нет фонарей и прочей посторонней засветки.
Спасибо за ваш ответ. Это одно из первых, что мне пришло в голову сегодня утром.
Но в моем профиле работы (фронт-разработка) - это называется "костыль", и я знаю что лучше делать продукт без "костылей". Вот потому и задаюсь поиском вариантов, как сделать все правильно в самом коде
В разработке разных девайсов физического мира это не костыль, а "инженерное решение" ;)
Я читал давеча про то, как инженеры в 30-х годах искали материал для клапана какого-то там. Они присобачивали туда всё - резину, пропитаный хлопок, телячью кожу... Наверное веб-программисты бы упали от такого подхода.
Все-таки костыль... Если в тубус нападает снег/капля дождя/муха какая-то умрет и закроют собой фотодатчик вообще...
Разве что сделать его "пошире" в диаметре. Нужно попробовать, но хотелось-бы варианты по коду. Неужели, без подключения модуля реального времени никак?
В "Проектах" есть какие-то темы про улья. Спросите в них - наверное гораздо выше там шанс встретить брата-пчеловода, понимающего как сделать правильно в вашей типовой пчеловодческой ситуации.
А что вообще у Вас делает фотодатчик? Вы толком не написали зачем он. Он что, должен рассвет определять и всё должно строго раз в сутки срабатывать? Или что?
Вопрос: подскажите, пожалуйста, возможно ли по этому скетчу сделать, чтобы в ночное время (после заката и до восхода) функция SendStat срабатывала только 1 раз и все, и как это мне правильно описать?
очевидно, что для этого нужно знать, что сейчас - закат или восход. Если вы это знаете (например у вас в системе есть часы) - то проще СМС посылать по часам, например ежедневно в 11 утра, а не по датчику света.
Реальное время можно, например, запрашивать у сотовой сети или через инет.
даже интересно, а сейчас фотодатчик от всего этого защищен?
А что вообще у Вас делает фотодатчик? Вы толком не написали зачем он. Он что, должен рассвет определять и всё должно строго раз в сутки срабатывать? Или что?
Может залетающих пчёл на лету считать, а когда они приземлятся- взвешивать?
Может залетающих пчёл на лету считать
Тогда проще поставить КПП и посадить туда трутня - пусть, заодно, у всех влетающих паспорта проверяет.
Все трутни с КПП в России уже пристроены, придётся завозить заграничных.
Фотодатчик для определения заката. Т.к. пчелы перестают работать по закату солнца, автором была решено привязаться именно к этому параметру - закат (срабатывание прерывания по изменению значения LOW--->HIGH -- attachInterrupt(0, SendStat , RISING)) , а не по времени, т.к. в разную пору года будет разное время, когда зашло солнце и пчелы собрались все в улей.
Когда происходит изменение значения с "светло" на "темно" - срабатывает ф-ция SendStat, которая считывает все данные и отправляет смс.
Вот эти прыжки светло-темно-светло-темно фотодачик ловит постоянно, и я так понял, судя по многократному срабатыванию, из-за колебаний света на улице от фонарей, наверное. Почему "наверное" - да потому что, если фотодатчик накрыть полотенцем дома - то такого поведения не наблюдалось.
В данный момент времени надел "тубус" на фотодатчик, посмотрим вечером, какая будет ситуация и правильно ли я предположил причину срабатываний ложных.
даже интересно, а сейчас фотодатчик от всего этого защищен?
Тубус предполагает стенки вокруг датчика. Сейчас датчик вынесен сверху распределительной коробки, в которой находиться GSM-модуль, антенна, батарея и солнечная панель.
Реальное время можно, например, запрашивать у сотовой сети или через инет.
Спасибо за эту наводку, я об этом не знал. Пойду копать как это делать
мне кажется, что идея ловить закат по прерыванию - обречена изначально. Усредняйте значение с датчика за большой период - например за час. Когда средняя за час освещенность упадет ниже определенного порога - считайте что наступила ночь.
Для начала, наверно, нужно указать модель фотодатчика
Для начала, наверно, нужно указать модель фотодатчика
Фоторезистор GL5528
Тогда нужна еще и схема, как так аналоговый датчик был присобачен к прерыванию.
Тогда нужна еще и схема, как так аналоговый датчик был присобачен к прерыванию.
Эта схема неработоспособна в принципе.
Фотодатчик для определения заката. Т.к. пчелы перестают работать по закату солнца, автором была решено привязаться именно к этому параметру - закат (срабатывание прерывания по изменению значения LOW--->HIGH -- attachInterrupt(0, SendStat , RISING)) , а не по времени, т.к. в разную пору года будет разное время, когда зашло солнце и пчелы собрались все в улей.
Когда происходит изменение значения с "светло" на "темно" - срабатывает ф-ция SendStat, которая считывает все данные и отправляет смс.
Вот эти прыжки светло-темно-светло-темно фотодачик ловит постоянно, и я так понял, судя по многократному срабатыванию, из-за колебаний света на улице от фонарей, наверное. Почему "наверное" - да потому что, если фотодатчик накрыть полотенцем дома - то такого поведения не наблюдалось.
В данный момент времени надел "тубус" на фотодатчик, посмотрим вечером, какая будет ситуация и правильно ли я предположил причину срабатываний ложных.
Пчёл нужно измерять именно на закате?
То есть ежедневно в полночь этого делать нельзя?
Пчёл нужно измерять именно на закате?
То есть ежедневно в полночь этого делать нельзя?
Да можно, в принципе. Я пытаюсь понять, возможно ли "исправить" проблему с меньшими "изменениями" того, что есть уже сейчас, чтобы не перепаивать то, что спаял.
Мне, в принципе, без разницы когда получать данные, главное чтобы они были объективными. Я в электронике полный 0. Нашел пример, схему, скетч и описание как все делать. Сделал, столкнулся с проблемой.
Теперь дилема - или убирать фотодатчик (несомненно, более опытный пользователь выше пишет, что схема не рабочая, в принципе, не совсем пойму что он имеет ввиду, т.к. в закрытом помещении схема отработала 1 неделю нормально) или можно как-то исправить положение. Если не удастся сделать второе, то буду подключать модуль времени наверное.
Ну да. В помещении. При стабильной температуре. Может тогда повезло, и отработало более-менее похоже на правду. А если собираете серьезный прибор для практического применения, то нужно делать нормальную настраиваемую цепь смещения и выделенный триггер шмитта. Если хочется оцифровать внешне. Хотя еще проще сделать с ацп, конечно же.
Ну и если совсем не выпендриваться, то нужно просто взять таблицу продолжительности дня, и выкинуть фоторезистор нафиг. Время есть в сотовой сети.
Теперь дилема - или убирать фотодатчик (несомненно, более опытный пользователь выше пишет, что схема не рабочая в принципе, не совсем пойму что он имеет ввиду
он имеет в виду, что датчик подключен абсолютно неверно. Убирать датчик не надо, проблема не в нем, а в том, что вы не удосужились прочитать как его нужно подключать, прежде чем собирать схему.
Этот датчик подключают к аналоговому пину по схеме резистивного делителя. И, конечно, работать с ним надо не через прерывание, а как я выше написал - чтением и усреднением аналоговых значений
а так, как подключили вы - просто удивительно что он хоть что-то показывает.
Благодарю за ваши подсказки, повторюсь, я 0 в этих делах (схемы, токи, пайки), поэтому понадеялся на "правильность" схемы.
Получается, фоторезистор мне нужно подключить к GND, вторую ногу к любому пину A0-A5, а также ко второй ноге подвести питание от VCC (??) через резистор?
Спасибо!
Получается, фоторезистор мне нужно подключить к GND, вторую ногу к любому пину A0-A5, а также ко второй ноге подвести питание от VCC (??) через резистор?
да
Благодарю за ваши подсказки, повторюсь, я 0 в этих делах (схемы, токи, пайки), поэтому понадеялся на "правильность" схемы.
Получается, фоторезистор мне нужно подключить к GND, вторую ногу к любому пину A0-A5, а также ко второй ноге подвести питание от VCC (??) через резистор?
Спасибо!
А для совсем нулевых, в "Песочнице" есть краткое описание "простейших" и там сказано как включают фоторезистор.))))
1. IMHO тубус - это никак не костыль, костыль - это попытка компенсации аппаратных дефектов программными средствами.
2. Если у Вас возникла потребность в прерывании использовать delay или delayMicroseconds, вы явно что-то неправильно делаете.
3. Собственно, для устройства, которое должно срабатывать единожды в сутки использование прерываний выглядит странным.
4. Прерывание от аналогового датчика - еще более странно.
IMHO задачу следует решать периодическим чтением аналоговым входом напряжения с датчика, а переключение день/ночь реализовать с гистерезисом во избежание "дребезга" в период сумерек. От кратковременной помехи можно отстраниться с помощью ФНЧ (программного), если возникнет такая потребность.
А потом так внезапно гроза набежит, облака небо закроют, и девайс начнёт лихорадочно слать СМС "Хозяин, ночь наступила!".
Единственно правильный вариант, на мой взгляд - это использовать астрономические расчёты, формулы общедоступны, время - можно получить у сотового оператора или поюзать DS3231, широту и долготу - тупо прописать в скетче, если по-босяцки.
И... всё. И будет пофиг на показания датчика освещённости, на тубусы-хренубусы и прочую ненужную дребедень. Ибо для того, чтобы понять, где сейчас Солнце - надо совсем немного вводных и чуть-чуть расчётов.
Совет: можно взять кусок кода из любого проекта солнечного трекера, который ипользует астрономические расчёты. Вот тут, например - код на JS: https://github.com/udivankin/sunrise-sunset (сам код тут: https://github.com/udivankin/sunrise-sunset/blob/master/src/index.js)- он крайне понятен алгоритмически, и можно это перенести на С++. Там, правда, отсутствует одна тонкость, а именно - расчёт угла зенита Солнца для переданного времени, но для ваших целей - это не сильно существенно.
Ночь наступает, по команде "Отбой". День наступает по команде "Подъем". Обучить пчел и нечего им шарится по ночам. :))
Вот, вдогонку: беглое гугление по фразе "arduino sunrise sunset" выдало даже библиотеку: https://github.com/dmkishi/Dusk2Dawn
Код бегло просмотрел - используются обычные расчёты.
DIYMan - посмотри тему, ТС не нужно время заката, вот ВООБЩЕ!
все что ему нужно - чтобы СМС посылалаось один раз в сутки, где-то _после_ заката. Выставить раз навсегда отсылку СМС в 23 часа, или в полночь - и никакие расчеты не нужны.
DIYMan - посмотри тему, ТС не нужно время заката, вот ВООБЩЕ!
все что ему нужно - чтобы СМС посылалаось один раз в сутки, где-то _после_ заката. Выставить раз навсегда отсылку СМС в 23 часа, или в полночь - и никакие расчеты не нужны.
Ну если так, то всё ещё проще :)
Благодарю, коллеги, за такую активную помощь и подсказки!
Тубус не дал необходимого эффекта. СМС пришло первое в 17.05, потом 2 часа тишины и в 19.10+ начался опять карнавал. Видать кто-то в это время включает из соседей фонарь какой-то, что-ли.
На будущее, в целях обучения захотелось поиграться и с фоторезистором (как вы пишите, усредненное значение за длительный промежуток времени с флагом для обозначения дня/ночи) и с отсылкой смс по звонку на номер, уже даже слегка доку начал читать в этом направлении. Но это все на будущее, неизвестно как будут дела в этом случае с потреблением и на сколько хватит батареи и солнечной панели в 1w.
Но самым, наверное, простым решением на этот сезон будет отправка смс в определенное время (20.00-21.00), а время буду пинговать с GSM Сети. Будем двигаться от просто к сложному, на "активный" сезон этого будет достаточно. А вот уже к осени-зиме ежедневные данные не так уж и нужны и там уже необходима статистика раз в 3-7 дней, а зимой раз в 2-4 недели - тут уже можно будет и по звонку, если питание будет позволять.
Ерунда это все. Какая Вам разница когда когда получать СМС - с заходом солнца или в 20.00 - суточный привес или убыль одинаковы . Подчеркиваю - суточный.
Но проблема тут совсем не в этом. Весы на тензодатчике под постоянной нагрузкой дают показания "день рождения прабабки снохи". Ставил эксперимент - тензодатчик торговых весов, наша любимая hx711, вес 40 кг. Через 12 часов - вес 40,5 кг. 12 часов - +500 граммов!!!. Со временем врать стали медленнее - 48 часов - 40,7 кг. На этом эксперимент прекратил. При этом - если добавить гирьку 100 гр. - добавляется ровно 100, убрать -уменьшается на 100. Т,е линейность остается в пределах погрешности. Но мы меряем не мгановенное приращение, а длительное - а оно фигня. Кроме того в ДШ hx711
поют про термостабильность -это бред. При повышении темп. микросхемы на 5 град. и нагрузке в 100 кг. показания "уплывают" в + на 40 граммов, а потом падают до -10 гр. Эксперименты проводил с двумя дешевыми зелеными платами и одной красной экранированной -результат один.
Тубус не дал необходимого эффекта. СМС пришло первое в 17.05, потом 2 часа тишины и в 19.10+ начался опять карнавал. Видать кто-то в это время включает из соседей фонарь какой-то, что-ли.
А то что вам сказали. что у вас датчик неверно подключен - вы в это не верите? переставлять его аналоговый вход не собираетесь?
Поймите, опрос по прерыванию тут не подходит категорически.Сснижение освещения в сумерки происходит очень медленно и в момент перехода через порог малейший всплеск цифрового шума с датчика вызывает срабатывание прерывания. То, что у вас в сумерки приходят десятки СМС - в этой ситуации не только нормально - это неизбежно. От этого никакой тубус не поможет. И даже если вы выживете из округи всех соседей с их фонарями - ситуация вряд ли изменится,
DIYMan, время заката/рассвета есть в системной службе времени, ничего не надо ниоткуда брать. http://arduino.ru/forum/programmirovanie/nedokumentirovannaya-i-nestandartnaya-sluzhba-vremeni-avr-libc#comment-511080
Ерунда это все. Какая Вам разница когда когда получать СМС - с заходом солнца или в 20.00 - суточный привес или убыль одинаковы . Подчеркиваю - суточный.
Но проблема тут совсем не в этом. Весы на тензодатчике под постоянной нагрузкой дают показания "день рождения прабабки снохи". Ставил эксперимент - тензодатчик торговых весов, наша любимая hx711, вес 40 кг. Через 12 часов - вес 40,5 кг. 12 часов - +500 граммов!!!. Со временем врать стали медленнее - 48 часов - 40,7 кг. На этом эксперимент прекратил. При этом - если добавить гирьку 100 гр. - добавляется ровно 100, убрать -уменьшается на 100. Т,е линейность остается в пределах погрешности. Но мы меряем не мгановенное приращение, а длительное - а оно фигня. Кроме того в ДШ hx711
поют про термостабильность -это бред. При повышении темп. микросхемы на 5 град. и нагрузке в 100 кг. показания "уплывают" в + на 40 граммов, а потом падают до -10 гр. Эксперименты проводил с двумя дешевыми зелеными платами и одной красной экранированной -результат один.
Суть для чего это делается - не в том, чтобы знать точный вес "до грамма", а видеть динамику в пределах 1-2 суток. Т.е. понимать, идет промышленный взяток/поддерживающий/голодание и в соответствии с этим правильно реагировать или вообще не рыпаться. Погрешность в пределах суток врядли будет громадная и постоянно изменяющаяся от дня на день. А вы сами написали, что линейность остается в приделах погрешности, что мне и нужно.
В любом случае, система собрана, почти работающая)). Проверить как оно будет себя вести в полевых условиях под длительной нагрузкой можно только опытным путем, что я и сделаю в этом сезоне, раз уж ввязался в это дело и потратил 2 недели времени уже.
А то что вам сказали. что у вас датчик неверно подключен - вы в это не верите? переставлять его аналоговый вход не собираетесь?
Поймите, опрос по прерыванию тут не подходит категорически.Сснижение освещения в сумерки происходит очень медленно и в момент перехода через порог малейший всплеск цифрового шума с датчика вызывает срабатывание прерывания. То, что у вас в сумерки приходят десятки СМС - в этой ситуации не только нормально - это неизбежно. От этого никакой тубус не поможет. И даже если вы выживете из округи всех соседей с их фонарями - ситуация вряд ли изменится,
Я шел по пути найменшего сопротивления. И не просто верю в то, что датчик неверно подключен, а уже и снял систему и буду ее переделывать, благодаря вашему участию и участию всех отписавшихся в этой теме, за что большая благодарность
DIYMan, время заката/рассвета есть в системной службе времени, ничего не надо ниоткуда брать. http://arduino.ru/forum/programmirovanie/nedokumentirovannaya-i-nestandartnaya-sluzhba-vremeni-avr-libc#comment-511080
Всё даже ишшо проще :) Вот только немного смущает, что оно "недокументировано и нестандартно".
Ну, не знаю, насколько там всё нестандартно, но вполне себе уже документировано: https://www.nongnu.org/avr-libc/user-manual/group__avr__time.html
Ну, не знаю, насколько там всё нестандартно, но вполне себе уже документировано: https://www.nongnu.org/avr-libc/user-manual/group__avr__time.html
Ну тогда ваще лафа :) В следующих проектах, где потребуется - буду юзать. В текущих - оставлю, как есть, ибо - работает, не трожь (это я про закат/восход).
В общем, закончил я колупание кода и определился с логикой работы.
Значит, пытался получить от оператора время, но оператор попался не очень ответственным в этом направлении, и отдавал время 3х летней давности.
Второй мыслью было обновить время через интернет сеть, но оказалось, что мой модуль связи IOT GA6 не поддерживает передачу каких-то там пакетов, которые нужно отправить на сервер, чтобы синхронизировать время. Прям наплыв совпадений не в мою пользу...
По итогу, оставалось пару вариантов - модуль времени (нужно искать 3231 ибо 1307 имеет не очень отзывы) и отправка смс по времени установленному или чето придумывать по звонку или по смс.
Выбрал вариант по звонку, т.к. это очень удобно и подкупает своей гибкостью (хочешь смс каждый час, хочешь только вечером, хочешь раз в 5 дней.. в общем, то что нужно). Но тут другая проблема, наваяв ф-нал смс по звонку увидел, что модуль связи съедает по 1% в час, что как бы не очень классно - нужно отправлять его в сон однозначно.
Так как же найти этот баланс, между гибкостью функционала (смс НЕ в определенный момент времени, а когда нужно) и в то же время быть автономным? Первое, что пришло в голову - пробуждать модуль каждый час и ждать 5 минут звонка, а потом опять отправлять на 55 минут в сон. В теории это даст экономию заряда на уровне 1/12, а это в районе 2% в сутки. Но как указать арудинке время? чтобы модуль будился ровно в начале каждого часа? Паять модуль времени?
Решив закончить освоение работы с модулем связи принято решение ничего уже не паять, а просто при включении модуля первый раз ожидать смс с цифрой. Цифра - количество минут до "назначенного времени", от которого Ардуино будет отчитывать период сна в 55 минут. Например, если мы запустили систему и хотим, чтобы "окно" для звонка было в первые 5 минут каждого часа, а сейчас 15.28 на часах, то отправляем смс с цифрой 31 - именно на столько заснет модуль связи первый раз, в 15:59 проснется, загрузится и будет ждать звонка с whiteList списка номеров, если звонка нет - засыпает, но в этот раз, уже на 55 минут. Т.е. следующее окно будет опять в 16:59-17:04.
Было сложно для первого раза)). Нужно продумать наличие смс от оператора или залетных смс, что бы их не обрабатывать. Сделано - при первом включении удаляются все смс с симки. Далее мучался с переводом цифры из смс в int-данные. Но и тут все удалось))
Конечно, немного замудренно, и я уверен, что более опытные коллеги с этого могут улыбнуться и предложить гораздо более простой способ решения проблемы, но для меня - это победа и определенного рода достижение, т.к. работает! Теперь стоит проверить потребление заряда батареи в таком режиме и немного оптимизировать изначальный скетч-пример, по которому все делалось в самом начале.
Всем привет!
Я тот самый электропчеловод, конструкция которого по словам некоторых из Вас "Неработоспособна в принципе"
Прежде, чем делать такие заявления, потрудитесь разобраться в самом принципе работы схемы.
Если нет, предложите свою, рабочую систему!
Специфику своих весов описал в статье:
https://habr.com/ru/post/487088/
С уважением, Андрей.
Слушайте, честно, почитал вас на Хабре и офигел. Вам люди дело выше говорят, а вы неймете. Во вторых pull_up использую регулярно, для подключения тактовых кнопок к земле (КЗ, как вы это назвали), и ещё ни разу замыкание ВХОДА с pull_up не приводило к тем последствиям, которые вы на Хабре описали.
В третьих почитайте вот эту статью https://elementztechblog.wordpress.com/2016/12/28/getting-time-and-date-... и таки задумайтесь над отправкой СМС в определенное время, а не по фоторезистору. Ну ведь бред же.
Прежде, чем делать такие заявления, потрудитесь разобраться в самом принципе работы схемы.
Прежде чем советовать людям такие схемы, потрудитесь прочитать даташит atmega328 на предмет допусков параметров входов.
Будь arduino платформой матерых разработчиков - да, можно было-бы внимать.
Но
1. Весьма скоро ИИ будет создавать "каноничную" электронику лучше людей.
2. Книга Массимо Банци - Ардуино для начинающих волшебников - автор прямо рекомендует смело экспериментировать.
И он прав - Arduino - это такая игра для детей и взрослых.
3. У меня и без того настолько серьезная работа, что в своем хобби хочется пошалить - и получается - собранные мной системы без проблем работают у знакомых. Кто-то успешно повторяет эти конструкции, кто-то не очень.
4. Я никого не принуждаю повторять мои конструкции, но видел десятки тем, где "правильные" системы так и не заработали, за год я сделал 12 конструктивно разных рабочих вариантов на десятке разных ардуин и уж не счесть действительно глухих ответвлений.
5. Процентов десять кристаллов Atmega 328P скажем так "раненые" - бывает и такое.
Так что если такие умные и не нравится мое королевство "кривых" зеркал, помогите товарищу сделать "каноничную" систему.
Я-же дал советы как исправить мою систему в случае фэйлов(п.5 тоже никто не отменял ).
С уважением, Андрей
5. Процентов десять кристаллов Atmega 328P скажем так "раненые" - бывает и такое.
Где Вы их такие берёте? Я вот ни одного не встречал. Ситуации, когда мозги у разработчиков раненые - этого добра хоть отбавляй. А вот кристаллы что-то ни разу не попадались. Наверное, что-то не так делаю.
5. Процентов десять кристаллов Atmega 328P скажем так "раненые" - бывает и такое.
Где Вы их такие берёте? Я вот ни одного не встречал. Ситуации, когда мозги у разработчиков раненые - этого добра хоть отбавляй. А вот кристаллы что-то ни разу не попадались. Наверное, что-то не так делаю.
Я понял по контексту написанного, что он их сам ранеными делает.
А так похоже очередной гивер.