Пауза между срабатыванием фотодатчика

vsmityukh
Offline
Зарегистрирован: 30.01.2020

Доброго времени, всем коллегам и разработчикам.

Коллега я ваш отдаленно, т.к. являюсь веб-разрабочиком, но тем не менее, по совместительству еще и пчеловод. Решил собрать весы с 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;
        }
      }
  }

}

 

ВН
Offline
Зарегистрирован: 25.02.2016

может достаточно поместить фотодатчик в тубус и направить туда, где нет фонарей и прочей посторонней засветки.

vsmityukh
Offline
Зарегистрирован: 30.01.2020

Спасибо за ваш ответ. Это одно из первых, что мне пришло в голову сегодня утром. 

Но в моем профиле работы (фронт-разработка) - это называется "костыль", и я знаю что лучше делать продукт без "костылей". Вот потому и задаюсь поиском вариантов, как сделать все правильно в самом коде

sadman41
Offline
Зарегистрирован: 19.10.2016

В разработке разных девайсов физического мира это не костыль, а "инженерное решение" ;)

Я читал давеча про то, как инженеры в 30-х годах искали материал для клапана какого-то там. Они присобачивали туда всё - резину, пропитаный хлопок, телячью кожу... Наверное веб-программисты бы упали от такого подхода.

vsmityukh
Offline
Зарегистрирован: 30.01.2020

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

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

sadman41
Offline
Зарегистрирован: 19.10.2016

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А что вообще у Вас делает фотодатчик? Вы толком не написали зачем он. Он что, должен рассвет определять и всё должно строго раз в сутки срабатывать? Или что?

b707
Offline
Зарегистрирован: 26.05.2017

vsmityukh пишет:

Вопрос: подскажите, пожалуйста,  возможно ли по этому скетчу сделать, чтобы в ночное время (после заката и до восхода) функция SendStat срабатывала только 1 раз и все, и как это мне правильно описать?

очевидно, что для этого нужно знать, что сейчас - закат или восход. Если вы это знаете (например у вас в системе есть часы) - то проще СМС посылать по часам, например ежедневно в 11 утра, а не по датчику света.

Реальное время можно, например, запрашивать у сотовой сети или через инет.

ВН
Offline
Зарегистрирован: 25.02.2016

vsmityukh пишет:
Все-таки костыль... Если в тубус нападает снег/капля дождя/муха какая-то умрет и закроют собой фотодатчик вообще...

даже интересно, а сейчас фотодатчик от всего этого защищен?

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

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

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

ЕвгенийП пишет:

А что вообще у Вас делает фотодатчик? Вы толком не написали зачем он. Он что, должен рассвет определять и всё должно строго раз в сутки срабатывать? Или что?

Может залетающих пчёл на лету считать, а когда они приземлятся- взвешивать?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

trembo пишет:

Может залетающих пчёл на лету считать

Тогда проще поставить КПП и посадить туда трутня - пусть, заодно, у всех влетающих паспорта проверяет.

sadman41
Offline
Зарегистрирован: 19.10.2016

Все трутни с КПП в России уже пристроены, придётся завозить заграничных.

vsmityukh
Offline
Зарегистрирован: 30.01.2020

ЕвгенийП пишет:
А что вообще у Вас делает фотодатчик? Вы толком не написали зачем он. Он что, должен рассвет определять и всё должно строго раз в сутки срабатывать? Или что?

Фотодатчик для определения заката. Т.к. пчелы перестают работать по закату солнца, автором была решено привязаться именно к этому параметру - закат (срабатывание прерывания по изменению значения LOW--->HIGH -- attachInterrupt(0, SendStat , RISING)) , а не по времени, т.к. в разную пору года будет разное время, когда зашло солнце и пчелы собрались все в улей.

Когда происходит изменение значения с "светло" на "темно" - срабатывает ф-ция SendStat, которая считывает все данные и отправляет смс.

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

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

 

vsmityukh
Offline
Зарегистрирован: 30.01.2020

ВН пишет:

vsmityukh пишет:
Все-таки костыль... Если в тубус нападает снег/капля дождя/муха какая-то умрет и закроют собой фотодатчик вообще...

даже интересно, а сейчас фотодатчик от всего этого защищен?

Тубус предполагает стенки вокруг датчика. Сейчас датчик вынесен сверху распределительной коробки, в которой находиться GSM-модуль, антенна, батарея и солнечная панель.

vsmityukh
Offline
Зарегистрирован: 30.01.2020

b707 пишет:

Реальное время можно, например, запрашивать у сотовой сети или через инет.

Спасибо за эту наводку, я об этом не знал. Пойду копать как это делать

b707
Offline
Зарегистрирован: 26.05.2017

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

rkit
Offline
Зарегистрирован: 23.11.2016

Для начала, наверно, нужно указать модель фотодатчика

vsmityukh
Offline
Зарегистрирован: 30.01.2020

rkit пишет:

Для начала, наверно, нужно указать модель фотодатчика

Фоторезистор GL5528

rkit
Offline
Зарегистрирован: 23.11.2016

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

vsmityukh
Offline
Зарегистрирован: 30.01.2020

rkit пишет:

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

rkit
Offline
Зарегистрирован: 23.11.2016

Эта схема неработоспособна в принципе.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

vsmityukh пишет:

Фотодатчик для определения заката. Т.к. пчелы перестают работать по закату солнца, автором была решено привязаться именно к этому параметру - закат (срабатывание прерывания по изменению значения LOW--->HIGH -- attachInterrupt(0, SendStat , RISING)) , а не по времени, т.к. в разную пору года будет разное время, когда зашло солнце и пчелы собрались все в улей.

Когда происходит изменение значения с "светло" на "темно" - срабатывает ф-ция SendStat, которая считывает все данные и отправляет смс.

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

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

 

Пчёл нужно измерять именно на закате?
То есть ежедневно  в полночь этого делать нельзя?

vsmityukh
Offline
Зарегистрирован: 30.01.2020

trembo пишет:

Пчёл нужно измерять именно на закате?

То есть ежедневно  в полночь этого делать нельзя?

Да можно, в принципе. Я пытаюсь понять, возможно ли "исправить" проблему с меньшими "изменениями" того, что есть уже сейчас, чтобы не перепаивать то, что спаял.

Мне, в принципе, без разницы когда получать данные, главное чтобы они были объективными. Я в электронике полный 0. Нашел пример, схему, скетч и описание как все делать. Сделал, столкнулся с проблемой.

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

rkit
Offline
Зарегистрирован: 23.11.2016

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

rkit
Offline
Зарегистрирован: 23.11.2016

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

b707
Offline
Зарегистрирован: 26.05.2017

vsmityukh пишет:

Теперь дилема - или убирать фотодатчик (несомненно, более опытный пользователь выше пишет, что схема не рабочая в принципе, не совсем пойму что он имеет ввиду

он имеет в виду, что датчик подключен абсолютно неверно. Убирать датчик не надо, проблема не в нем, а в том, что вы не удосужились прочитать как его нужно подключать, прежде чем собирать схему.

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

а так, как подключили вы - просто удивительно что он хоть что-то показывает.

vsmityukh
Offline
Зарегистрирован: 30.01.2020

Благодарю за ваши подсказки, повторюсь, я 0 в этих делах (схемы, токи, пайки), поэтому понадеялся на "правильность" схемы.

Получается, фоторезистор мне нужно подключить к GND, вторую ногу к любому пину A0-A5, а также ко второй ноге подвести питание от VCC (??) через резистор?

Спасибо!

b707
Offline
Зарегистрирован: 26.05.2017

vsmityukh пишет:

Получается, фоторезистор мне нужно подключить к GND, вторую ногу к любому пину A0-A5, а также ко второй ноге подвести питание от VCC (??) через резистор?

 

да

bwn
Offline
Зарегистрирован: 25.08.2014

vsmityukh пишет:

Благодарю за ваши подсказки, повторюсь, я 0 в этих делах (схемы, токи, пайки), поэтому понадеялся на "правильность" схемы.

Получается, фоторезистор мне нужно подключить к GND, вторую ногу к любому пину A0-A5, а также ко второй ноге подвести питание от VCC (??) через резистор?

Спасибо!

А для совсем нулевых, в "Песочнице" есть краткое описание "простейших" и там сказано как включают фоторезистор.))))

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

1. IMHO тубус - это никак не костыль, костыль - это попытка компенсации аппаратных дефектов программными средствами.

2. Если у Вас возникла потребность в прерывании использовать delay или delayMicroseconds, вы явно что-то неправильно делаете.

3. Собственно, для устройства, которое должно срабатывать единожды в сутки использование прерываний выглядит странным.

4. Прерывание от аналогового датчика - еще более странно.

IMHO задачу следует решать периодическим чтением аналоговым входом напряжения с датчика, а переключение день/ночь реализовать с гистерезисом во избежание "дребезга" в период сумерек. От кратковременной помехи можно отстраниться с помощью ФНЧ (программного), если возникнет такая потребность.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

А потом так внезапно гроза набежит, облака небо закроют, и девайс начнёт лихорадочно слать СМС "Хозяин, ночь наступила!".

Единственно правильный вариант, на мой взгляд - это использовать астрономические расчёты, формулы общедоступны, время - можно получить у сотового оператора или поюзать DS3231, широту и долготу - тупо прописать в скетче, если по-босяцки.

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

Совет: можно взять кусок кода из любого проекта солнечного трекера, который ипользует астрономические расчёты. Вот тут, например - код на JS: https://github.com/udivankin/sunrise-sunset (сам код тут: https://github.com/udivankin/sunrise-sunset/blob/master/src/index.js)- он крайне понятен алгоритмически, и можно это перенести на С++. Там, правда, отсутствует одна тонкость, а именно - расчёт угла зенита Солнца для переданного времени, но для ваших целей - это не сильно существенно.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

DIYMan пишет:
Единственно правильный вариант, на мой взгляд - это использовать астрономические расчёты, формулы общедоступны, время - можно получить у сотового оператора или поюзать DS3231, широту и долготу - тупо прописать в скетче, если по-босяцки.

Ночь наступает, по команде "Отбой". День наступает по команде "Подъем". Обучить пчел и нечего им шарится по ночам. :))

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Вот, вдогонку: беглое гугление по фразе "arduino sunrise sunset" выдало даже библиотеку: https://github.com/dmkishi/Dusk2Dawn

Код бегло просмотрел - используются обычные расчёты.

b707
Offline
Зарегистрирован: 26.05.2017

DIYMan - посмотри тему, ТС не нужно время заката, вот ВООБЩЕ!

все что ему нужно - чтобы СМС посылалаось один раз в сутки, где-то _после_  заката. Выставить раз навсегда отсылку СМС в 23 часа, или в полночь - и никакие расчеты не нужны.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

b707 пишет:

DIYMan - посмотри тему, ТС не нужно время заката, вот ВООБЩЕ!

все что ему нужно - чтобы СМС посылалаось один раз в сутки, где-то _после_  заката. Выставить раз навсегда отсылку СМС в 23 часа, или в полночь - и никакие расчеты не нужны.

Ну если так, то всё ещё проще :)

vsmityukh
Offline
Зарегистрирован: 30.01.2020

Благодарю, коллеги, за такую активную помощь и подсказки!

Тубус не дал необходимого эффекта. СМС пришло первое в 17.05, потом 2 часа тишины и в 19.10+ начался опять карнавал. Видать кто-то в это время включает из соседей фонарь какой-то, что-ли.

На будущее, в целях обучения захотелось поиграться и с фоторезистором (как вы пишите, усредненное значение за длительный промежуток времени с флагом для обозначения дня/ночи) и с отсылкой смс по звонку на номер, уже даже слегка доку начал читать в этом направлении. Но это все на будущее, неизвестно как будут дела в этом случае с потреблением и на сколько хватит батареи и солнечной панели в 1w.

Но самым, наверное, простым решением на этот сезон будет отправка смс в определенное время (20.00-21.00), а время буду пинговать с GSM Сети. Будем двигаться от просто к сложному, на "активный" сезон этого будет достаточно. А вот уже к осени-зиме ежедневные данные не так уж и нужны и там уже необходима статистика раз в 3-7 дней, а зимой раз в 2-4 недели - тут уже можно будет и по звонку, если питание будет позволять.

kolyn
Offline
Зарегистрирован: 18.01.2019

Ерунда это все. Какая Вам разница когда когда получать СМС - с заходом солнца или в 20.00 - суточный привес или убыль одинаковы . Подчеркиваю - суточный.

Но проблема тут совсем не в этом. Весы на тензодатчике под постоянной нагрузкой дают показания "день рождения прабабки снохи". Ставил эксперимент - тензодатчик торговых весов, наша любимая hx711, вес 40 кг. Через 12 часов - вес 40,5 кг. 12 часов - +500 граммов!!!. Со временем врать стали медленнее - 48 часов - 40,7 кг. На этом эксперимент прекратил. При этом - если добавить гирьку 100 гр. - добавляется ровно 100, убрать -уменьшается на 100. Т,е линейность остается в пределах погрешности. Но мы меряем не мгановенное приращение, а длительное - а оно фигня. Кроме того  в ДШ hx711

поют про термостабильность -это бред. При повышении темп. микросхемы на 5 град. и нагрузке в 100 кг. показания "уплывают" в + на 40 граммов, а потом падают до -10 гр. Эксперименты проводил с двумя дешевыми зелеными платами и одной красной экранированной -результат один.

b707
Offline
Зарегистрирован: 26.05.2017

vsmityukh пишет:

Тубус не дал необходимого эффекта. СМС пришло первое в 17.05, потом 2 часа тишины и в 19.10+ начался опять карнавал. Видать кто-то в это время включает из соседей фонарь какой-то, что-ли.

А то что вам сказали. что у вас датчик неверно подключен - вы в это не верите?  переставлять его аналоговый вход не собираетесь?

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

DIYMan, время заката/рассвета есть в системной службе времени, ничего не надо ниоткуда брать. http://arduino.ru/forum/programmirovanie/nedokumentirovannaya-i-nestandartnaya-sluzhba-vremeni-avr-libc#comment-511080

vsmityukh
Offline
Зарегистрирован: 30.01.2020

kolyn пишет:

Ерунда это все. Какая Вам разница когда когда получать СМС - с заходом солнца или в 20.00 - суточный привес или убыль одинаковы . Подчеркиваю - суточный.

Но проблема тут совсем не в этом. Весы на тензодатчике под постоянной нагрузкой дают показания "день рождения прабабки снохи". Ставил эксперимент - тензодатчик торговых весов, наша любимая hx711, вес 40 кг. Через 12 часов - вес 40,5 кг. 12 часов - +500 граммов!!!. Со временем врать стали медленнее - 48 часов - 40,7 кг. На этом эксперимент прекратил. При этом - если добавить гирьку 100 гр. - добавляется ровно 100, убрать -уменьшается на 100. Т,е линейность остается в пределах погрешности. Но мы меряем не мгановенное приращение, а длительное - а оно фигня. Кроме того  в ДШ hx711

поют про термостабильность -это бред. При повышении темп. микросхемы на 5 град. и нагрузке в 100 кг. показания "уплывают" в + на 40 граммов, а потом падают до -10 гр. Эксперименты проводил с двумя дешевыми зелеными платами и одной красной экранированной -результат один.

Суть для чего это делается - не в том, чтобы знать точный вес "до грамма", а видеть динамику в пределах 1-2 суток. Т.е. понимать, идет промышленный взяток/поддерживающий/голодание и в соответствии с этим правильно реагировать или вообще не рыпаться. Погрешность в пределах суток врядли будет громадная и постоянно изменяющаяся от дня на день. А вы сами написали, что линейность остается в приделах погрешности, что мне и нужно.

 

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

vsmityukh
Offline
Зарегистрирован: 30.01.2020

b707 пишет:

А то что вам сказали. что у вас датчик неверно подключен - вы в это не верите?  переставлять его аналоговый вход не собираетесь?

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

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

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

ЕвгенийП пишет:

DIYMan, время заката/рассвета есть в системной службе времени, ничего не надо ниоткуда брать. http://arduino.ru/forum/programmirovanie/nedokumentirovannaya-i-nestandartnaya-sluzhba-vremeni-avr-libc#comment-511080

Всё даже ишшо проще :) Вот только немного смущает, что оно "недокументировано и нестандартно".

sadman41
Offline
Зарегистрирован: 19.10.2016

Ну, не знаю, насколько там всё нестандартно, но вполне себе уже документировано: https://www.nongnu.org/avr-libc/user-manual/group__avr__time.html

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

Ну, не знаю, насколько там всё нестандартно, но вполне себе уже документировано: https://www.nongnu.org/avr-libc/user-manual/group__avr__time.html

Ну тогда ваще лафа :) В следующих проектах, где потребуется - буду юзать. В текущих - оставлю, как есть, ибо - работает, не трожь (это я про закат/восход).

vsmityukh
Offline
Зарегистрирован: 30.01.2020

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

Значит, пытался получить от оператора время, но оператор попался не очень ответственным в этом направлении, и отдавал время 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-данные. Но и тут все удалось))

Конечно, немного замудренно, и я уверен, что более опытные коллеги с этого могут улыбнуться и предложить гораздо более простой способ решения проблемы, но для меня - это победа и определенного рода достижение, т.к. работает! Теперь стоит проверить потребление заряда батареи в таком режиме и немного оптимизировать изначальный скетч-пример, по которому все делалось в самом начале. 

GerAn
Offline
Зарегистрирован: 05.02.2020

Всем привет!

Я тот самый электропчеловод, конструкция которого по словам некоторых из Вас "Неработоспособна в принципе"

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

Если нет, предложите свою, рабочую систему!

Специфику своих весов описал в статье:

https://habr.com/ru/post/487088/

С уважением, Андрей.

kostyamat
Offline
Зарегистрирован: 16.11.2017

Слушайте, честно, почитал вас на Хабре и офигел. Вам люди дело выше говорят, а вы неймете. Во вторых pull_up использую регулярно, для подключения тактовых кнопок к земле (КЗ, как вы это назвали), и ещё ни разу замыкание ВХОДА с pull_up не приводило к тем последствиям, которые вы на Хабре описали.
В третьих почитайте вот эту статью https://elementztechblog.wordpress.com/2016/12/28/getting-time-and-date-... и таки задумайтесь над отправкой СМС в определенное время, а не по фоторезистору. Ну ведь бред же.

rkit
Offline
Зарегистрирован: 23.11.2016

GerAn пишет:

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

Прежде чем советовать людям такие схемы, потрудитесь прочитать даташит atmega328 на предмет допусков параметров входов.

GerAn
Offline
Зарегистрирован: 05.02.2020

Будь arduino платформой матерых разработчиков - да, можно было-бы внимать.

Но 

1. Весьма скоро ИИ будет создавать "каноничную" электронику лучше людей.

2. Книга Массимо Банци - Ардуино для начинающих волшебников - автор прямо рекомендует смело экспериментировать.

И он прав - Arduino - это такая игра для детей и взрослых.

3. У меня и без того настолько серьезная работа, что в своем  хобби хочется пошалить - и получается - собранные мной системы без проблем работают у знакомых. Кто-то успешно повторяет эти конструкции, кто-то не очень. 

4. Я никого не принуждаю повторять мои конструкции, но видел десятки тем, где "правильные" системы так и не заработали, за год я сделал 12 конструктивно разных рабочих вариантов на десятке разных ардуин и уж не счесть действительно глухих ответвлений.

5. Процентов десять кристаллов Atmega 328P скажем так "раненые" - бывает и такое.

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

Я-же дал советы как исправить мою систему в случае фэйлов(п.5 тоже никто не отменял ).

 

С уважением, Андрей

 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

GerAn пишет:

5. Процентов десять кристаллов Atmega 328P скажем так "раненые" - бывает и такое.

Где Вы их такие берёте? Я вот ни одного не встречал. Ситуации, когда мозги у разработчиков раненые - этого добра хоть отбавляй. А вот кристаллы что-то ни разу не попадались. Наверное, что-то не так делаю.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

ЕвгенийП пишет:

GerAn пишет:

5. Процентов десять кристаллов Atmega 328P скажем так "раненые" - бывает и такое.

Где Вы их такие берёте? Я вот ни одного не встречал. Ситуации, когда мозги у разработчиков раненые - этого добра хоть отбавляй. А вот кристаллы что-то ни разу не попадались. Наверное, что-то не так делаю.

Я понял по контексту написанного, что он их сам ранеными делает.
А так похоже очередной гивер.