Skocz do zawartości

Zmienne millis, prośba o pomoc


SOYER

Pomocna odpowiedź

Proszę jaka dyskusją się rozpoczęła 🙂 Dotarłem w końcu do knajpy, można spokojnie połączyć się z netem i wrócić to przerwanego wątku.

Więc jak chodzi o oryginalny kod i negację, to nie ma tutaj różnicy - chociaż jest pojęciowa.

Tak się składa, że LOW i HIGH są zdefiniowane jako 0 i 1, ale tak wcale nie musi być. To jest po prostu wartość, można przyjąć LOW = 50, HIGH = -10 i też będzie dobrze.

Typ logiczny (bool) powinien przyjmować tylko dwie wartości prawdę (true) lub fałsz (false). Jednak adresowanie bitowe jest mało wydajne, więc najczęściej bool to bajt lub całe słowo (np. 32-bitowe). Co wiecej fałsz jest reprezentowany jako wartość zerowa, cokolwiek innego interpretowane jest jako true. Kompilatory używają jedynki na określenie true.

Negacja ma dwie postaci:

* logiczną, czyli !wartość, działa ona tak, że zero zamienia na 1, a cokolwiek innego na zero

* arytmetyczna ~wartość - wszystkie bity są negowane.

Kod z if-em moze nie był krótki, ale dziłał poprawnie dla dowolnej reprezentacji LOW, HIGH. Użycie negacji działa przypadkiem, gdyby LOW lub HIGH były inaczej zdefiniowne, po prostu by nie działało.

Jednak kod typu:

stan = !stan;

Jest ładny i zwarty, więc można byłoby to zaakceptować, nawet jeśli logicznie jest to błąd.

Natomiast przypisanie z negacją w parametrze funkcji to herezja czystej postaci 🙂

Jak chodzi o chwalenie się dokonaniami, to niewiele mogę napisać poza tym że pracuję jako konsultant. Zwiedziłem więc nieco firm, widziałem różne style i kody programów. Każda firma ma lub próbuje mieć własny styl kodowania, ale są pewne wspólne elementy. I pisanie tak żeby było ciekawie i nieczytelnie raczej nie jest mile widziane. A żeby też jakiegoś linka podać, to np tomtom.com - ale to dawno temu, jeszcze jak biuro było w Amsterdamie. To były czasy 🙂

Zmianna stan nie jest typu logicznego. Więc wykonywanie na niej operacji logicznej (!stan) jest nie do końca poprawne - to chciałem napisać. Natomiast użycie if-ów zadziała dla dowolnych wartości, nie ma problemu jeśli będzimy mieli np. Trzy stany.

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

Dobra, heretyku, też już siedzę w barze i wznoszę szklenicę do ust 🙂

Nie zgodzę się z Tobą w kwestii umieszczenia w parametrze wyrażenia dającego efekt uboczny. Ale to zostawmy sobie na chwilę, gdy przypadkowo znajdziemy się w jednej knajpie 🙂

Ty pracujesz jako konsultant - ja jako (jak to nazwać... Nie wiem...) taki gość co w firmie robi różne takie dziwne rzeczy, które mają zwyczaj działać wbrew oczekiwaniom różnych fachmanów od php, majskula i innych wynalazków 😉

Niech więc koledzy, którzy chcą się nauczyć programowania, uczą się nie na przykładach typu forum arduino (bo mnie to działa i tak jest fajnie) - ale od kogoś mądrzejszego. Nie mówię że to ja jestem ten najmądrzejszy - ale negowanie jakiejś konstrukcji języka tylko dlatego, że "mnie siem nie podoba" to błąd, którego żaden nauczyciel nie ma prawa popełnić.

Zdrówko!

(Edytka) od kiedy w C są typy logiczne?

Link do komentarza
Share on other sites

Dobra ja siedzę przy herbacie i bułce z pasztetem 😅

const int czerwona =  10;
const int zielona = 8;
int stanC = LOW;  
int stanZ = LOW;           
unsigned long previousMillisC = 0; 
unsigned long previousMillisZ = 0;     
const long intervalZ= 1000; 
const long intervalC = 300;     
void setup() { 
pinMode(czerwona, OUTPUT); 
pinMode(zielona, OUTPUT);
} 

void loop() { 

 unsigned long currentMillis = millis();
 if (currentMillis - previousMillisC >= intervalC) {
   previousMillisC = currentMillis;

 if (stanC == LOW) { 
     stanC = HIGH;\\plan był taki:załącza się co 300ms na 200ms
     delay(200);
     stanC = LOW; [code]
   } 
  digitalWrite(czerwona, stanC);
 }
  if (currentMillis - previousMillisZ >= intervalZ) {
   previousMillisZ = currentMillis;

 if (stanZ == LOW) { 
     stanZ = HIGH;
   } else { 
     stanZ = LOW; 
   } 
  digitalWrite(zielona, stanZ);
  }
} 

Jaki był plan jest w komentarzu, dlaczego nie działa?
sorry za pomyłkę slasha i backslasha...[/code]

już doszedłem, prosty błąd był, ma być:


const int czerwona =  10;
const int zielona = 8;
int stanC = LOW;  
int stanZ = LOW;           
unsigned long previousMillisC = 0; 
unsigned long previousMillisZ = 0;     
const long intervalZ= 1000; 
const long intervalC = 300;     
void setup() { 
pinMode(czerwona, OUTPUT); 
pinMode(zielona, OUTPUT);
} 

void loop() { 

 unsigned long currentMillis = millis();
 if (currentMillis - previousMillisC >= intervalC) {
   previousMillisC = currentMillis;

 if (stanC == LOW) { 
    stanC = HIGH;//plan był taki:załącza się co 300ms na 200ms 
     digitalWrite(czerwona, stanC); 

     delay(200); 
     stanC = LOW; 
     digitalWrite(czerwona, stanC); 

   } 

  }
  if (currentMillis - previousMillisZ >= intervalZ) {
   previousMillisZ = currentMillis;

 if (stanZ == LOW) { 
     stanZ = HIGH;
   } else { 
     stanZ = LOW; 
   } 
  digitalWrite(zielona, stanZ);
  }
} 
Link do komentarza
Share on other sites

Ktoś tu dał przykład zegarka na lodówce...

Gotujesz gulasz (50 minut), a po upływie 50 minut sprawdzasz czy minęły trzy minuty...

Tak przy okazji: stanz i stanc mają być typu bool a nie int - za dużo kasz ramu w arduino czy co?

Link do komentarza
Share on other sites

Typ logiczny jest chyba od C99, ale długo o tym nie wiedziałem. Ostatnio studiowałem nowości w C++14 i nadal twierdzę, że ostatni sensowny C++ był w 93, a od 98 to tylko C--. Jak chodzi o C to mniej się zmieniło, ale typ bool niby istnieje. Chociaż tradycyjnie na int moża zamienić. Za to zawsze były logiczne operatory np. &&, || w odróżnieniu od bitowych &, |. To samo dotyczy negacji ! Vs ~ (jeśli pomyliłem nazewnictwo to z góry przepraszam).

Co do pogadania w knajpie to jak najbardziej, ale teraz mam kontrakt w Kopenhadze, więc może być nieco daleko. Pozostaje zdalny toast za zgodę i zrozumienie zamiast wykazywania jedynie słusznej racji.

SOYER, używasz delay, a to nie działa dobrze z millis() - albo jedno albo drugie

Link do komentarza
Share on other sites

Już poprawiłem, spójrz do góry... co zmienić by miało look? Elvis? ethanak?

[edit] Rzeczywiście, przy wstawianiu różnych wartości gryzie się... 😥

Czyli delay wpływa na odliczanie czasu millis...

[edit2] gryzie się gdy oba interwały są podzielne przez siebie... dobrze obserwuję?

Link do komentarza
Share on other sites

Nie, ale jak program wykonuje delay() to nic innego nie może zrobić. A poza tym brakuje drugiego delay - ustawiasz stan wysoki dla diody "czerwona", czekasz 200 ms, później stan niski. Tutaj nie czekasz i znowu stan wysoki - więc nawet nie widać, że coś się dzieje.

Ale ogólnie - jak delay() to nie milis()

Link do komentarza
Share on other sites

O używaniu millis() możesz myśleć jak o zegarku - patrzysz która godzina i jeśli od rozpoczęcia np. Gotowania/pieczenia nie minęło odpowiednio dużo czasu, to robisz cokolowiek innego. Za moment patrzysz na zegarek znowu itd.

Delay to drzemka, albo ważny telefon - choćby wszystko poszło z dymem i wykipiało, jesteś tym zajęty i do końca czasu nic innego nie zrobisz.

Mieszanie drzemki z gotowaniem jajek na twardo nie wychodzi i dlatego program nie działa.

Link do komentarza
Share on other sites

#include <LiquidCrystal.h> //Dołączenie bilbioteki
#include <SimpleDHT.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7); //Informacja o podłączeniu 
int pinDHT11 = 13; //pin czujnika
SimpleDHT11 dht11; 
unsigned long poprzedniMillis = 0;
unsigned long aktualnyMillis = 0;
const long interval = 1000;

void setup() {
 pinMode(8, INPUT_PULLUP);
 Serial.begin(9600);

}

void loop() {
 Serial.println(digitalRead(8));

byte temperature = 0; 
 byte humidity = 0; 
 dht11.read(pinDHT11, &temperature, &humidity, NULL);  //odczyt z czujnika
 aktualnyMillis = millis(); 
 if (aktualnyMillis - poprzedniMillis >= interval) {
   poprzedniMillis = aktualnyMillis;
   if(digitalRead(8)==LOW){
     wyniki();
   }

   else{ 
 dzieci();
 wyniki();
 franek();
 wyniki();
 dominik();
 wyniki();
 zosia();
 }

 }
}
void zosia(){
 lcd.begin(16, 2);
 lcd.setCursor(16,0);
 lcd.print(" Czesc Zosia :-)");  //tekst 1 linii
 for (int positionCounter = 0; positionCounter < 33; positionCounter++) {
   lcd.scrollDisplayLeft(); // przesuwamy ww tekst o 15 pozycji w lewo czyli "poza ekran"
   delay(600);  //czas przeskoku o ledną pozycję na wyświetlaczu (szybkosc przewijania)
 }
}
void franek(){
 lcd.begin(16, 2);
 lcd.setCursor(16,1);
 lcd.print(" Czesc Franek :-)");  //tekst 2 linii
 delay(1500);  // czekamy z ww. tekstem
 for (int positionCounter = 0; positionCounter < 35; positionCounter++) {
   lcd.scrollDisplayLeft(); // przesuwamy ww tekst o 15 pozycji w lewo czyli "poza ekran"
   delay(600);  //czas przeskoku o ledną pozycję na wyświetlaczu (szybkosc przewijania)
 }
}
void wyniki(){
 byte temperature = 0; 
 byte humidity = 0; 
 dht11.read(pinDHT11, &temperature, &humidity, NULL);  //odczyt z czujnika
 lcd.begin(16, 2); // ustawiamy lcd dla nast. wyswietlenia
 lcd.setCursor(2, 0); 
 lcd.print("Wilg.: "); 
 lcd.print((int)humidity); 
 lcd.print("%RH"); 
 lcd.setCursor(2, 1); 
 lcd.print("Temp.: "); 
 lcd.print((int)temperature); 
 lcd.print("*C"); // wyswietlamy temp. i wilgotnosc wraz z jednostkami
 delay(3000); // czekamy z ww. tekstem 
 for (int positionCounter = 0; positionCounter < 2; positionCounter++) {
   lcd.scrollDisplayRight(); //przewijamy ww tekst do prawej krawedzi lcd
   delay(1000);// szybkosc przewijania
 }
 for (int positionCounter = 0; positionCounter < 4; positionCounter++) {
   lcd.scrollDisplayLeft(); //przewijamy do lewej krawedzi ww tekst
   delay(1000); // szybkosc przeijania
 }
 for (int positionCounter = 0; positionCounter < 2; positionCounter++) {
   lcd.scrollDisplayRight(); // przewijamy teks znowu do srodka lcd
   delay(1000); //czekamy
 }
 delay(3000);
}
void dominik(){
 lcd.begin(16, 2);
 lcd.setCursor(16,0);
 lcd.print(" Czesc Dominik :-)");  //tekst 2 linii
 delay(1500);  // czekamy z ww. tekstem
 for (int positionCounter = 0; positionCounter < 35; positionCounter++) {
   lcd.scrollDisplayLeft(); // przesuwamy ww tekst o 15 pozycji w lewo czyli "poza ekran"
   delay(600);  //czas przeskoku o ledną pozycję na wyświetlaczu (szybkosc przewijania)
 }
}
void dzieci(){
 int migniecie = 0;
 lcd.begin(16, 2);
 lcd.setCursor(4,0);
 lcd.print("Dominik");  //tekst 2 linii
 lcd.setCursor(2,1);
 lcd.print("Zosia Franek");
  for(int migniecie =0; migniecie <10; migniecie++){
    lcd.noDisplay();
    delay(500);
    lcd.display();
    delay(500);
  }
}

Proszę o pomoc przy millis. Plan był taki by program co 1 sekundę sprawdzał czy jest wcisnięty przycisk, jeśli tak to włącza funkcję wyniki, jeśli nie to sobie wykonuje spokojnie kolejne funkcje...

Inaczej, chodzi o to wy w dowolnym momencie programu nacisnięcie przycisku powodowało przejście do funkcji wyniki();

Da się? W powyższym kodzie sprawdza tylko przy uruchomieniu programu...🙁

Edit 19:23 doczytałem, że powinienem to zrobić na przerwaniach a nie na millis, jeszcze nie wiem jak ale czytam dalej....🙂)

Edit 19:40 no i jajo. Treker pisze w kursie, że w przerwaniach absolutnie nie robić delay...

Więc ponawiam pytanie: jak w dowolnym momencie programu po nacisnięciu przycisku przerwać pętlę loop i przejść do funkcji wyniki();

A może jednak millis? 😐

Edit 21:00 Jedyne co mi przychodzi do głowy to olać funkcję wyniki(). Wstawić do funkcji przerwania pętlę while. Jak długo będzie naciśnięty przycisk tak długo będą wyświetlone wartości czujnika, bez żadnych delay i przewijania... Co wy na to?

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.