Skocz do zawartości

Wielozadaniowość, millis, automatyka domowa


Philip

Pomocna odpowiedź

@Elvis: z tą armatą lekko przesadziłeś. Masz przed sobą kod jednej funkcji - a spójrz na pierwszy post: ile tam masz reakcji na klawiaturę? Wszędzie chcesz wstawiać jakieś prywatne odczyty zmiennych czy lepiej użyć zunifikowanej (i sprawdzonej) biblioteki?

Nie można się uczyć wszystkiego na raz.

A tak wracając do kodu... błąd jest w zupełnie innym miejscu: przy stanie 4 zmiana stanu na 1 nie powoduje zapamiętania bieżącego czasu. Dodatkowo sugerowałem, aby stan 4 był stanem początkowym... a nie jest.

A użycie biblioteki zwalniałoby autora z obowiązku zapamiętywania czasów i tym podobnych szczegółów, pozwalając skupić się na właściwym algorytmie.

Link do komentarza
Share on other sites

ethanak, chodziło mi tylko o to że w programie jest już wszystko co potrzebne, zabrakło jednego ustawienia zmiennej. A czasy i tak trzeba zapamiętywać na potrzeby melodyjek 🙂

Nie mam za grosz zaufania do bibliotek dla Arduino, stąd uważałem że lepiej poprawić program niż dodawać bibliotekę - inna sprawa, że i tak wypadałoby ten błąd poprawić.

Link do komentarza
Share on other sites

Arduinowe biblioteki nie są takie złe, szczególnie jak się przejrzy kod i kawałek dokumentacji, jeśli istnieje taka 😋 Fajnie eliminuje się z nimi niektóre problemy, ale też wypada wiedzieć jak one działają (jak np. biblioteka servo które wyłącza pwm na chyba jednym pinie, o ile dobrze pamiętam... a chyba pół dnia mi kiedyś zajęło z dojściem, czemu to cholerstwo nie działa) 😃

Link do komentarza
Share on other sites

      case 4:
     if(digitalRead(KONTAKTRON)==HIGH){           //Jeśli drzwi otwarte
     } else {                                     //Nic nie robię
       if(aktualnyCzas - zapamietanyCzas >=500UL){
         stan = 1;                                //Jeśli nie przełączam na stan1
         zapamietanyCzas = aktualnyCzas;
       }

     }
     break;
  } 

Elvis, o takie coś ci chodziło? Dalej są te ciche drgania... 😐

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Oj tam... już tu taki jeden się produkował co biblioteki do Arduino pisywał bo wszystkie są niedobre...

Akurat kod Bounce2 sobie przejrzałem i nie widzę w nim nic, co mogłoby źle działać.

A pisanie czegoś, co ktoś już dawno napisał i przetestował uważam za zwykłą stratę czasu.

[ Dodano: 01-08-2018, 17:16 ]

@BananWszyscy: co do servo... gdybyś przeczytał dokumentację to byś nie musiał pół dnia szukać w kodzie.

  • Lubię! 1
Link do komentarza
Share on other sites

Elvis, powiedz wprost jak to ma być, bo sam do tego nigdy nie dojdę. A nie chce tracić czasu nad taką zapewne drobnostką.

Tak program dalej odtwarza sygnał po ponownym otwarciu drzwi.

Z tą biblioteką, ethanak, mógłbyś napisać coś więcej? Jak użyć? Jakieś podstawowe funkcje?

Link do komentarza
Share on other sites

Te cichutkie odgłosy z buzzera nadal sobie chodzą kiedy chcą. To raczej nie było to.

Tak przy okazji jutro albo po jutrze będę dodawał kolejne elementy do tego całego układu. Czujnik ruchu PIR,, zegar RTC (z którym dzisiaj się namęczyłem, a dokładnie z biblioteką RTClib) oraz chce jeszcze poprzednio gotowe czujniki połączyć w automat skończony razem z wyświetlaczem LED.

Link do komentarza
Share on other sites

@Philip: co do Bounce2 - podawałem link, tam masz wszystko łącznie z przykładami (jak sobie zainstalujesz). Owszem, można to zrobić lepiej, ale jeśli się zacznie robić kilka rzeczy na raz to nie wyjdzie żadna.

Tak więc skorzystaj z biblioteki, a jak już reszta kodu będzie działać to ewentualnie pomyślimy nad lepszym rozwiązaniem.

Tak przy okazji (bo już wczoraj miałem to napisać): dzisiaj w swoim automacie masz cztery stany, jutro w innym będziesz ich miał 40. Czy naprawdę chce Ci się zapamiętywać że np. 17 to "odczytuję bajt z wejścia" a 23 to "sprawdzam czy minęła określona godzina"?

A istnieje takie magiczne słowo "enum" 🙂

Link do komentarza
Share on other sites

1.Do biblioteki Bounce2 jeszcze wrócę. Tyle ile wyczytałem z wikipedii to enum to jest wyliczeniowy typ danych. Trochę trudne określenie. Nie do końca rozumiem jej działanie.

2.Próbuję ogarnąć bibliotekę RTClib i wyświetlenie aktualnej daty i godziny na wyświetlaczu LCD. Mam scalaka DS 1307, ten Tylko cały czas wyświetla mi się data początkowa ustawiona w kodzie we void setup(). Nie wiem jak zmienić. aby godzina się zmieniała z sekundami, minutami itd. Moglibyście mnie nakierować albo wskazać gdzie robię błąd?

3.Takie pytanie poza tym. Czy biblioteka gryzie się z ?

#include "RTClib.h"      //Biblioteki
#include <Wire.h>
#include <LiquidCrystal.h>

RTC_DS1307 rtc;                             //Inicjalizacja obiektów
LiquidCrystal lcd(8,9,10,11,12,13);

void setup() {
 rtc.begin();
 Wire.begin();
 rtc.adjust(DateTime(2018, 8, 2, 11, 0, 0));  //Ustawienie daty i godziny

 if( !rtc.isrunning()){
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("RTC nie dziala");
}


 Serial.begin(9600);         //Prędkość transmisji
 lcd.begin(16,2);                  
 lcd.clear();                      
}

void loop() {
 DateTime now = rtc.now();  //Pobranie aktualnego czasu i daty
 lcd.clear();                           //Wyświetlenie aktualnej daty i godziny
 lcd.setCursor(0,0);
 lcd.print(now.year(),DEC);
 lcd.print('/');
 lcd.print(now.month(), DEC);
 lcd.print('/');
 lcd.print(now.day(), DEC);
 lcd.setCursor(0,1);
 lcd.print(now.hour(), DEC);
 lcd.print(':');
 lcd.print(now.minute(), DEC);
 lcd.print(':');
 lcd.print(now.second(), DEC);
delay(1000);
}
Link do komentarza
Share on other sites

Przede wszystkim nie sprawdzasz, czy zegarek działa.

To znaczy inaczej: sprawdzasz i przechodzisz nad tym do porządku dziennego. Może i coś tam chciałbyś na wyświetlaczu wyświetlić, ale po pierwsze wyświetlanie przed begin() to zły pomysł (pytanie: najpierw otwierasz butelkę a potem pijesz piwo czy pijesz piwo, a potem otwierasz butelkę?), po drugie nawet gdybyś przeniósł inicjalizację lcd na właściwe miejsce to i tak nawet tego nie zobaczysz bo za chwilę masz clear().

Jeśli zegar nie działa, dalsze działanie nie ma sensu, zatrzymaj program i czekaj na reset, czyli:

while(1); // odpowiednik delay(infinity)

Popraw to.

Co do enuma to nic skomplikowanego. Fragment kodu automatu do pikania pipkiem przy otwieraniu drzwi:


enum {
  STAN_OTWIERAMY_DRZWI = 1,
  STAN_PIPKAMY_TON_1,
  STAN_PIPKAMY_TON_2,
  STAN_POPIPKANE
};

/* a teraz w loop */

switch(stan) {
   case STAN_OTWIERAMY_DRZWI:
   /* coś robimy */
   case STAN_PIPKAMY_TON_1:
  /* coś robimy */

I tak dalej...

Zauważ - bez analizy kodu nie wiem jaka jest wartość np. STAN_POPIPKANE i szczerze mówiąc mało mnie to obchodzi, prawda?

Łatwiej się czyta czy nie?

Co do gryzienia się wire i onewire - pierwszy raz słyszę.

Link do komentarza
Share on other sites

Zrozumiałem o co chodzi z tymi danymi wyliczeniowymi. 😃 Myślałem, że jest to trudniejsze. Jeśli do tego enuma przypiszemy jakieś określone argumenty, to ich wartości zostaną same przypisane od 0. W naszym przypdaku od 1, później 2,3,4. Tak zmieniłem ten automat i działa tak samo:

#define KONTAKTRON 16
#define BUZZER 17

[...]

unsigned long aktualnyCzas = 0;             //Zmienne do liczenia czasu
unsigned long zapamietanyCzas = 0;

int glosnosc1 = 500;                        //Zmienne do zmiany glośności buzzera i otworzenia drzwi
int glosnosc2 = 1000;
int stan = 1;

enum {
 czyOtworzonoDrzwi = 1,
 odegranoDzwiek1,
 odegranoDzwiek2,
 czyZamknietoDrzwi
};

void setup() {
 Serial.begin(9600);
 lcd.begin(16,2);                  //Deklaracja typu
 lcd.clear();                      //Wyczyszczenie

 sensors.begin();                  //Inicjalizacja czujników

 dht.setup(CzDHT);                 //Inicjalizacja DHT11

 pinMode(KONTAKTRON,INPUT_PULLUP); //Deklaracja dla kontaktronu jako wyjście
 pinMode(BUZZER,OUTPUT);           //Deklaracja buzzera wyjście
 pinMode(PIR,INPUT);               //Deklaracja czujnika ruchu jako wejście
}
void loop() {
[...]
aktualnyCzas = millis();
switch(stan){
   case czyOtworzonoDrzwi:
   if(digitalRead(KONTAKTRON)==HIGH){              //Jeśli drzwi otwarte
       if(aktualnyCzas - zapamietanyCzas >=500UL){ //Ile upłynęło
       zapamietanyCzas = aktualnyCzas;
       tone(BUZZER,glosnosc1);                     //Odtwarzam dźwięk1
       stan = odegranoDzwiek1;                     //Przełączam na stan2
     }
   }
   break;

   case odegranoDzwiek1:
   if(aktualnyCzas - zapamietanyCzas >=500UL){    //Jeśli upłynął czas
       zapamietanyCzas = aktualnyCzas;
       tone(BUZZER,glosnosc2);                    //Odtwarzam dźwięk2
       stan = odegranoDzwiek2;                    //Przełączam na stan3
     }
    break;

     case odegranoDzwiek2:
     if(aktualnyCzas - zapamietanyCzas >=500UL){  //Jeśli upłynął czas
       zapamietanyCzas = aktualnyCzas;
       noTone(BUZZER);                            //Nie odtwarzam dźwięków
       stan = czyZamknietoDrzwi;
     }
     break;

     case czyZamknietoDrzwi:
     if(digitalRead(KONTAKTRON)==HIGH){           //Jeśli drzwi otwarte
     } else {                                     //Nic nie robię
       if(aktualnyCzas - zapamietanyCzas >=500UL){
         stan = czyOtworzonoDrzwi;                //Jeśli nie przełączam na stan1
         zapamietanyCzas = aktualnyCzas;
       }
     }
     break;
  }
[...]
} 

Teraz zegar 😃 Teoretycznie łatwiejsza część, a jednak nie. Próbowałem z wyświetlaniem w porcie szeregowym, ale nie działa, tak samo jak na wyświetlaczu. Nic się nie wyświetla. Patrzyłem na jeden z przykładów i było tam tak samo jak mam. Praktycznie cały kod jest taki sam. Prędkość transmisji danych była inna tylko... 57600

#include "RTClib.h"
#include <Wire.h>
#include <LiquidCrystal.h>

RTC_DS1307 rtc;
LiquidCrystal lcd(8,9,10,11,12,13);

void setup() {
 Serial.begin(9600);
 Wire.begin(); 
 lcd.begin(16,2);

 if (! rtc.begin()) {
   lcd.setCursor(0,0);
   lcd.print("Nie moge znalezc RTC");
   while (1);
 }
 if( !rtc.isrunning()){
   lcd.setCursor(0,0);
   lcd.print("RTC nie dziala");
   rtc.adjust(DateTime(2018,8,3,11,0,0));
 }
}

void loop() {
 DateTime now = rtc.now();

 lcd.setCursor(0,0);
 lcd.print(now.year(),DEC);
 lcd.print('/');
 lcd.print(now.month(), DEC);
 lcd.print('/');
 lcd.print(now.day(), DEC);
 lcd.setCursor(0,1);
 lcd.print(now.hour(), DEC);
 lcd.print(':');
 lcd.print(now.minute(), DEC);
 lcd.print(':');
 lcd.print(now.second(), DEC);
 lcd.clear();

delay(1000);
}

Podsyłam jeszcze schemat podłączenia zegara, ale myślę, że w tym nie tkwi problem, tylko w kodzie. Pinu SQW nie podłączałem.

[ Dodano: 03-08-2018, 11:56 ]

Cofam wszystko. Teraz działa. Wyświetla się na lcd. W pętli loop trzeba było całkowicie usunąć:

lcd.clear();

,które cały czas usuwało czas. Dziwiło mnie to, że diodka na Uno cały czas migała... 😉 Działa także z prędkością 9600.

[ Dodano: 03-08-2018, 12:02 ]

Hmmm... ale trzeba by było to udoskonalić, bo po tym jak minęła teraz 12:00 została 9 z 59 sekundy minuty i brzydko to wygląda. Liczą się sekundy z 9.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.