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);
}
}
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ć.
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).
(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).
(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.
(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.
@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
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);
}
}
Najlepiej jeśli sam sprawdzisz czy zadziała - zmniejsz opóźnienie np. do 10 min. uruchom i zobacz czy działa
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ć.
(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
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