• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
SIM800L i NANO czujnik zalania. Jak odliczyć czas 30 dni?
#11
To może wyglądać tak? Czy coś źle?
Kod:
#include <BareBoneSim800.h>

BareBoneSim800 sim800;
int koniec = 0;
int koniecSMS = 0;
unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzasSMS = 0;
void setup() {
  Serial.begin(9600);
  sim800.begin();
  while(!Serial);
  pinMode(5, INPUT);

  Serial.println("Testing GSM module For SMS Sending");
  delay(8000); // this delay is necessary, it helps the device to be ready and connect to a network

  Serial.println("Should be ready by now");
    bool deviceAttached = sim800.isAttached();
  if (deviceAttached)
    Serial.println("Device is Attached");
  else
    Serial.println("Not Attached");

   const char* number = "+48xxxxxxxxx";
   char* message2 = "GSM dziala poprawnie. SMS testowy";
   delay(2000);
  
   bool messageSent = sim800.sendSMS(number, message2);
   if(messageSent)
      Serial.println("Message Sent");
   else
      Serial.println("Not Sent, Something happened");
}

void loop()
//====================================================================================

{
  aktualnyCzas = millis();

  if (((aktualnyCzas - zapamietanyCzasSMS) >= 2629743830UL)&& koniecSMS == 0) {
        bool messageSent = sim800.sendSMS("+48xxxxxxxxx","SMS testowy co miesiac");

   if((messageSent)&&(koniecSMS == 0))
    koniecSMS = 1;
   else
    koniecSMS = 0;
  }

//====================================================================================
{
  if ((digitalRead(5) == LOW)&&(koniec == 0)) { //Jeżeli czujnik zadziałął
    bool messageSent = sim800.sendSMS("+48xxxxxxxxxx","UWAGA!!! WODA w lazience. Prosze o szybkie sprawdzenie.");
   if((messageSent)&&(koniec==0))
    koniec = 1;
   else
      Serial.println("Not Sent, Something happened");
  }
   if (digitalRead(5) == HIGH) {
    koniec = 0;
   }
   delay(5000);
   }
}
 
Odpowiedź
#12
Musisz dodać jeszcze jedną linijkę kodu. Musisz uaktualniać zapamietanyCzasSMS w ciele funkcji if czyli dodać : zapamietanyCzasSMS = millis(); Można też dodać to po każdym wysłaniu SMSa, aby czas był liczony od ostatniego wysłanego SMSa.
Licznik millis() przekręca się po około 50 dniach ( 4 294 967 295 ms) . Daj sobie krótszy czas niż 30 dni bo luty ma zwykle 28 dni więc 28 powinno wystarczyć.
 
Odpowiedź
#13
Wklejam to co jakiś czas na fora, nikt nie każe porównywać miliardów ms:
Kod:
uint32_t czasTeraz,czasPoprzedni,tik=10; //tik musi byc mniejszy niz 1000 i dzilic 1000ms na rowne czesci
uint8_t nTik,sekundy,minuty,godziny,dni; //liczniki tikow, sekund, itd.
bool fnTik,fsekundy,fminuty,fgodziny,fdni; //flagi zdarzen nowy tik, nowa sekunda,minuta, godzina, dzien
char napis[10];
void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
pinMode(LED_BUILTIN,OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:
czas();






if(fsekundy) {
sprintf(napis,"%03d:%02d:%02d",godziny,minuty,sekundy);
Serial.println(napis);


}

if(fnTik&&! (nTik%20)) digitalWrite(LED_BUILTIN,! digitalRead(LED_BUILTIN));//gdy nowy tik i co 20 tikow
}


void czas()
{
  czasTeraz=millis();
fnTik=fsekundy=fminuty=fgodziny=fdni=0;
if((uint32_t)(czasTeraz-czasPoprzedni)>=tik) //tan napisany warunek jest odporny na "klątwe 50 dni millis()"
{
  czasPoprzedni=czasTeraz;
  fnTik=1;
  nTik++;
  if(nTik>=(1000/tik))
  {
    nTik=0;
    sekundy++;
    fsekundy=1;
     if (sekundy>=60)
    {
      sekundy=0;
      minuty++;
      fminuty=1;
      if (minuty>=60)
      {
        minuty=0;
        godziny++;
        fgodziny=1;
        if (godziny>=24)
        {
          godziny=0;
          fdni=1;
          dni++;
   
        }
      }
    }
  }
}
}
Możesz sobie dorobić warunek, że jeśli fdni (jest 1-ką tylko w jednej pętli na dobę) i liczba dni od poprzedniego wysłania jest większa niż X to wyślij. Do tego zawsze przy uruchomieniu (reset, WD, brak zasilania).
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#14
(28-02-2020, 19:18)Agregacik napisał(a): Hm w tym przypadku nie przychodzi mi nic do głowy co by mogło być złe w jego użyciu.
- Problem 54 dni.
- Używanie 4 bajtów nawet gdy odmierzasz czasy < 256 ms.
- Niektóre wartości czasu nigdy się nie pojawiają i == nie zawsze zadziała.

Arduino to demo. To nie jest coś na czym da się poważne programy pisać. Gdy takowy napiszesz to będziesz miał taka wiedzę, że więcej tego nie zrobisz i sięgniesz po lepsze narzędzia czy miktokontrolery. To jest powód z powodu którego nie ma fachowców od Arduino (od każdej reguły jest wyjątek).
Wiem o czym piszę bo na AVR (Arduino do głównie AVR) napisałem setki programów. AVR był dobry 20 lat temu gdy wyparł z rynku 8051. Teraz AVR jest wypierany przez ARM, który jest tańszy, lepszy, programy na niego pisze się szybciej i łatwiej czyli taniej. Prawdopodobnie za 5 może 10 lat ARm zostanie wypardy przez darmowy RISC-V chyba, że ARM też będzie darmowy. Już można kupić odpowiedniki STM32F1 w wersji RISC-V ale na razie to ciekawostka (jak kiedyś AVR).
Kod z delay to nie kod, to DEMO!
Możliwości sprzętowe uC trzeba wykorzystywać a nie /machać/. GPIO!
Jestem a usilnie chcę być amatorem to dwie różne rzeczy.

http://er-mik.prv.pl/projekty edw.php 
http://er-mik.prv.pl/projekty_avt.php
 
Odpowiedź
#15
(29-02-2020, 07:29)MERASerwis napisał(a):
(28-02-2020, 19:18)Agregacik napisał(a): Hm w tym przypadku nie przychodzi mi nic do głowy co by mogło być złe w jego użyciu.
- Problem 54 dni.
- Używanie 4 bajtów nawet gdy odmierzasz czasy < 256 ms.
- Niektóre wartości czasu nigdy się nie pojawiają i == nie zawsze zadziała.
Powyższe nie jest przeszkodą w zastosowaniu w projekcie autora więc dalej nie widzę przeszkód w użyciu millis() w tym przypadku.
Masz rację co do ograniczeń czasowych, zjadania 4 bajtów pamięci czy równania, które wymieniłeś i tego trzeba być świadomym przy jego wykorzystaniu.
 
Odpowiedź
#16
(29-02-2020, 09:05)Agregacik napisał(a): Masz rację co do ograniczeń czasowych, zjadania 4 bajtów pamięci czy równania, które wymieniłeś i tego trzeba być świadomym przy jego wykorzystaniu.
Moja świadomość ograniczeń arduino jest taka, że go nie używam. Czego się tam nie tknę wymaga gruntownej modyfikacji. Po takich modyfikacjach z arduino pozostaje tylko nazwa.
Kod z delay to nie kod, to DEMO!
Możliwości sprzętowe uC trzeba wykorzystywać a nie /machać/. GPIO!
Jestem a usilnie chcę być amatorem to dwie różne rzeczy.

http://er-mik.prv.pl/projekty edw.php 
http://er-mik.prv.pl/projekty_avt.php
 
Odpowiedź
#17
@OMK jeśli chcesz coś bardzo prostego to proponuję zrobić tak:
1) po włączeniu urządzenia wysyłasz sms z informacją o jego uruchomieniu. Dzięki temu wiesz że np. była przerwa w zasilaniu, a jednocześnie nie musisz się przejmować zapisami w pamięci nieulotnej
2) potrzebujesz wysyłać sms raz w miesiącu, ale jeśli wyślesz dwa to też się nic nie stanie - więc najprościej odliczyć ok 30 dni za pomocą millis i wysłać sms-a
3) poprawne użycie millis nie powoduje problemów po przekroczeniu 49dni, natomiast użycie 4 bajtów to najmniejszy problem. W końcu i tak nie używasz całej pamięci RAM, więc i tak te bajty pozostaną niewykorzystane. Zbyt wczesna optymalizacja to błąd, więc na razie możesz zrobić tak jak jest najłatwiej
 
Odpowiedź
#18
A czy to zadziała??? Nie rozumie tej funkcji reset ale jakby działała to chyba można i tak:
Kod:
#include <BareBoneSim800.h>

BareBoneSim800 sim800;
int koniec = 0;
int koniecSMS = 0;
unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzasSMS = 0;
void setup() {
  Serial.begin(9600);
  sim800.begin();
  while(!Serial);
  pinMode(5, INPUT);

  Serial.println("Testing GSM module For SMS Sending");
  delay(8000); // this delay is necessary, it helps the device to be ready and connect to a network

  Serial.println("Should be ready by now");
    bool deviceAttached = sim800.isAttached();
  if (deviceAttached)
    Serial.println("Device is Attached");
  else
    Serial.println("Not Attached");

   const char* number = "+48XXXXXXXXX";
   char* message2 = "GSM dziala poprawnie. SMS testowy";
   delay(2000);
  
   bool messageSent = sim800.sendSMS(number, message2);
   if(messageSent)
      Serial.println("Message Sent");
   else
      Serial.println("Not Sent, Something happened");
}

void (* resetFunc) (void) = 0; // funkcja resetowania

void loop()
//====================================================================================

{
  aktualnyCzas = millis();
  if (aktualnyCzas >= 2629743830UL) {  
resetFunc (); // Restart układu
  }

//====================================================================================
{
  if ((digitalRead(5) == LOW)&&(koniec == 0)) { //Jeżeli czujnik zadziałał
    bool messageSent = sim800.sendSMS("+48XXXXXXXXX","UWAGA!!! WODA. Prosze o szybkie sprawdzenie.");
   if((messageSent)&&(koniec==0))
    koniec = 1;
   else
      Serial.println("Not Sent, Something happened");
  }
   if (digitalRead(5) == HIGH) {
    koniec = 0;
   }
   delay(5000);
   }
}
 
Odpowiedź
#19
Najlepiej jeśli sam sprawdzisz czy zadziała - zmniejsz opóźnienie np. do 10 min. uruchom i zobacz czy działa Smile
Nie jestem pewien czy skok pod adres 0 to najlepszy sposób resetowania układu, ale i tak warto sprawdzić czy taki program działa, później zawsze można go udoskonalać.
 
Odpowiedź
#20
(29-02-2020, 13:59)elvis napisał(a): Najlepiej jeśli sam sprawdzisz czy zadziała - zmniejsz opóźnienie np. do 10 min. uruchom i zobacz czy działa Smile
Nie jestem pewien czy skok pod adres 0 to najlepszy sposób resetowania układu, ale i tak warto sprawdzić czy taki program działa, później zawsze można go udoskonalać.
Dzięki sprawdzę. Dam znać. Pozdrawiam
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości