Skocz do zawartości

Zwracanie wartości TRUE lub FALSE przez instrukcje if w pętli


LieutenantDan

Pomocna odpowiedź

Witam, przechodząc powoli przez kurs arduino 1 próbuje wdrażać swoje pomysły, czego efektem jest między innymi poruszony tutaj problem.
Wiem, że nazewnictwo przeze  mnie  używane może być dla niektórych bardziej doświadczonych osób irytujące, za co z góry przepraszam.

Tak więc posługując się intuicyjnie wykreowaną nomenklaturą:

Mam podłączone na płytce stykowej 6 diod:

- 3 czerwone
- 1 niebieska
- 1 żółta
- 1 zielona

Chciałem napisać program który umożliwiałby sterowanie tymi diodami przez monitor portu szeregowego,
w sposób następujący:

-wpisanie blue/green/yellow ma zmieniać stan diody o wskazanym kolorze (włączać lub wyłączać)

-dla 3 diod red , po wpisaniu tego koloru diody migać mają w regularnych odstępach czasu,
aż do momentu ponownego wpisania red, które to miganie wyłączy

Problem polega na tym że nie wiem jak uzyskać ten efekt migania czerwonych tak, aby
kontrolowanie stanów pozostałych diod było cały czas możliwe (podczas migania czerwonych)

Napisałem program który to działania potrzebowałby teoretycznie 1 rzeczy, mianowicie aby pierwszy if w pętli loop
wypluwał wartość RedAllow i przypisywał ją do zmiennej RedAllow tak jakby już w setupie przed rozpoczęciem programu.
To pozwoliłoby żeby czerwone migały bo przy każdym przejściu przez pętle RedAllow byłby dostępny dla ostatniego ifa.

Wiem że ostatnie 2 zdania są dość dziwne oraz że takie rozwiązanie problemu jest prawdopodobnie niemożliwe,
ale celem było tutaj pokazanie mojego rozumowania.

Jeśli ktoś jeszcze się nie obraził słysząc te herezje to proszę o pomoc i z góry dziękuje, prosząc o wyrozumiałość, jeśli to co pisze nie ma sensu.


#define RED1 4
#define RED2 5
#define BLUE 6
#define YELLOW 7
#define GREEN 8
#define RED3 9

String odebraneDane = ""; 
int lastmillisR, act, TR=1000;

boolean AreGreenON = false, AreRedON = false, AreYellowON = false, AreBlueON = false;
boolean RedAllow = false; 

void setup() {
 Serial.begin(9600);
 pinMode(RED1, OUTPUT);
 pinMode(RED2, OUTPUT);
 pinMode(BLUE, OUTPUT); 
 pinMode(GREEN, OUTPUT); 
 pinMode(RED3, OUTPUT);
 pinMode(YELLOW, OUTPUT);

 digitalWrite(RED1, LOW);
 digitalWrite(RED2, LOW);
 digitalWrite(BLUE, LOW);
 digitalWrite(GREEN, LOW); 
 digitalWrite(RED3, LOW);
 digitalWrite(YELLOW, LOW);
}

void loop() {
act = millis();


 if (Serial.available() > 0) {

    odebraneDane = Serial.readStringUntil('\n'); 

    if(odebraneDane == "green"){
      delay(100);
       AreGreenON = !AreGreenON;     
       digitalWrite(GREEN, AreGreenON); 
       delay(500);
       Serial.println("AreGreenON = ");
       Serial.println(AreGreenON);
       Serial.println("");
    }
      else if(odebraneDane == "yellow"){
      delay(100);
       AreYellowON = !AreYellowON;
       digitalWrite(YELLOW, AreYellowON);
       delay(500);
       Serial.println("AreYellowON = ");
       Serial.println(AreYellowON);
       Serial.println("");
       }
    else if(odebraneDane ==  "blue"){
       delay(100);
       AreBlueON = !AreBlueON;
       digitalWrite(BLUE, AreBlueON);
       delay(500);
       Serial.println("AreBlueON = ");
       Serial.println(AreBlueON);
       Serial.println("");
    }
    else if(odebraneDane == "red"){
      RedAllow != RedAllow;
      }
    else {
      Serial.println("Blad. Wprowadzona nazwa nie jest obslugiwanym kolorem diody.");
      Serial.println("Obslugiwane kolory: 'green' lub 'red' lub 'blue' lub 'yellow'.");
   } 

  }
    if( (act-lastmillisR) >= TR && RedAllow == true){
       lastmillisR = millis(); 
        AreRedON = !AreRedON;
       digitalWrite(RED1, AreRedON);
       digitalWrite(RED2, AreRedON);
       digitalWrite(RED3, AreRedON);
    }
   

 }
 

 

Link do komentarza
Share on other sites

Wstępnie kod wygląda wporzadku i te red'y mają migać nie blokując pozostałych ledów...jedyne co mi tu nie pasuje to typ zmiennej  (być może nie widzę dobrze bo na tel patrzę i do tego już mnie słońce przygrzalo 😜)

int lastmillisR;
// a ma być
uint32_t lastmillisR;

 

Edytowano przez farmaceuta
Link do komentarza
Share on other sites

(edytowany)
16 minut temu, farmaceuta napisał:

Wstępnie kod wygląda wporzadku 

 

Może i tak wygląda (nie znam się) ale gdy wpisuje red to czerwone się wogóle nie zapalają, bo ...?
Bo jak sądze RedAllow jest cały czas false dla ostatniego ifa.
Rozumiem , na telefonie to może tak nie widać

Edytowano przez LieutenantDan
Link do komentarza
Share on other sites

31 minut temu, LieutenantDan napisał:


Bo jak sądze RedAllow jest cały czas false dla ostatniego ifa.
 

A no widzisz! Ma być tak i działa 

RedAllow = !RedAllow;

I zmień tego lastmillis tak jak napisałem wcześniej

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

Niestety program działa poprawnie do ~35sekund od momentu wgrania do arduino.
(Pod warunkiem, że wpiszemy red, aby wyłączyć uprzednio już włączone diody tylko gdy są w stanie wygaszenia)

Jeśli  tych warunków nie spełnimy to robi się coś takiego:

case1. (chcemy korzystać z programu po ~35 sek od wgrania, po około 15-16 okresach migania  red od startu)
- red zawiesza się w stanie ON (można to wyłączyć jeśli wpisze się red) ale zachodzą wtedy mniej więcej takie sekwencje:

(za każdym ponownym wpisaniem red zmienia się stan świecenia w taki oto sposób, diody oczywiście nie mrugają)

0. Wcale      0.Wcale    0.Wcale
1. Słabo       1.Słabo     1. Słabo
2.Mocniej    2.Wcale   2.Mocno
                                    3. Słabo
                                    4.Mocno
                                    5.Słabo
                                    6. Wcale

case 2.(chcemy wyłączyć miganie diod czerwonych gdy program nie pracuje jeszcze 35 sekund)

- jeśli robimy to gdy diody są w stanie wysokim to wszystko znowu się psuje

diody najpierw nie reagują, potem (za kolejnym wpisaniem red) wyłączają się i zaczynają migać od nowa
Oczywiście to do momentu ~35 sek od początku potem wszystko się totalnie psuje

 

Link do komentarza
Share on other sites

2 minuty temu, LieutenantDan napisał:

Niestety program działa poprawnie do ~35sekund od momentu wgrania do arduino.
 

Napisałem dwa razy....a tam niech strace i napiszę trzeci raz😉 ZMIEŃ TYP ZMIENNEJ o której wspominałem...(do 10 litrowego wiadra nie wlejesz 200-stu litrów wody tak?) Ze zmiennymi jest tak samo

Link do komentarza
Share on other sites

Nie widzę tu niczego w kodzie co by miało powodować przypadek 1. Nawet gdyby został ten int (technicznie rzecz biorąc niepoprawnie, ale akurat arytmetyka tutaj by zadziałała, przypadkiem). Chyba że problem jest w samym obwodzie i za dużo prądu bierzesz? Przypadek 2 jest prosty, no bo nie masz niczego, co by wyłączało te diody, skoro jedyne miejsce, które zmienia ich stan, uruchomi się, gdy RedAllow będzie true. Jedna z wielu możliwości to dodać trzy digitalWrite() w warunku po odebraniu "red", robiąc tam np. if (!RedAllow) {.

No i przede wszystkim, co do przypadku 1, to co tu by miało zmieniać ich jasność? Poza brakiem mocy.

Edytowano przez trainee
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Update 18:38

Działa już wszystko. Zrobiłem tak:

2 godziny temu, farmaceuta napisał:

Dobra dobra wporzadku 😉 myślałem że tego nie zmieniłeś...no to chyba niejawne rzutowanie nam bruździ...ten TR też jako uint32_t zapisz lub zastąp go w kodzie jako "1000UL"

A następnie tak:

else if(odebraneDane == "red"){
      RedAllow = !RedAllow;
      if(AreRedON = true){
        AreRedON = false;
       digitalWrite(RED1, AreRedON);
       digitalWrite(RED2, AreRedON);
       digitalWrite(RED3, AreRedON);
        
      }

Nie rozumiem tylko dlaczego zmienne lastmillisR, act, TR = 1000; musiały zostać zmienione na uint32_t żeby działało? Czy integer ma jakąś własność magiczną,
czy też to że int może przyjmować wartości ujemne coś pomieszało. No z tego co ja widze to zakres ma do  ponad 2 miliardów na + , więc jak w kilkanaście sekund licząc nawet po 1000 bo w milis. to mogło wyjść za zakres?

Link do komentarza
Share on other sites

12 minut temu, LieutenantDan napisał:

 



 

Nie rozumiem tylko dlaczego zmienne lastmillisR, act, TR = 1000; musiały zostać zmienione na uint32_t żeby działało?

Bo używasz ich w odniesieniu do millis() który zwraca wynik 4-bajtowy, więc pasuje żeby te zmienne były również 4-bajtowe bo możesz mieć kłopoty 😉 

 

12 minut temu, LieutenantDan napisał:

 



 

 Czy integer ma jakąś własność magiczną,
czy też to że int może przyjmować wartości ujemne coś pomieszało. No z tego co ja widze to zakres ma do  ponad 2 miliardów na + 

Cytat..."Rozmiar danych typu int wynosi dwa bajty (16 bitów). Zakres danych typu int obejmuje liczby z przedziału od -32768 to 32767 lub w zapisie potęgowym od – (215) do ((215) – 1). W mikrokontrolerach AVR ATmega i płytce Arduino UNO R3, typ danych int przechowuje wartości o rozmiarze do dwóch bajtów."..... (więc raczej o 2 miliardach zapomnij😜)

Edytowano przez farmaceuta
Link do komentarza
Share on other sites

Zakres int zależy od platformy. Sprawdź sobie na Arduino:

#include <limits.h>

void setup() {
  Serial.begin(9600);
  Serial.println(String("int: ") + INT_MIN + " - " + INT_MAX);
  Serial.println(String("uint32_t: ") + "0 - " + UINT32_MAX);
  Serial.println(String("unsigned long: ") + "0 - " + ULONG_MAX);
}

void loop() {
}

unsigned long dodałem tu nie przez przypadek. Dokumentacja millis() mówi, że typ zwracany przez tę funkcję, to unsigned long. I takiego powinieneś użyć, nawet jeżeli na danej platformie uint32_t ma tę samą długość.

Link do komentarza
Share on other sites

Btw, na czym Ty dokładnie odpalałeś ten kod? Ja nie odczuwam satysfakcji "losowe spawki, spawiki, zadziałało, do przodu!". Bo choć te "~35 sekund" pasuje do limitu int, to i tak nie widzę tego przypadku, dla którego miało się to popsuć. Tym bardziej zmieniać jasność świecenia...

Link do komentarza
Share on other sites

4 minuty temu, trainee napisał:

Btw, na czym Ty dokładnie odpalałeś ten kod? Ja nie odczuwam satysfakcji "losowe spawki, spawiki, zadziałało, do przodu!". Bo choć te "~35 sekund" pasuje do limitu int, to i tak nie widzę tego przypadku, dla którego miało się to popsuć. Tym bardziej zmieniać jasność świecenia...

Użyłem arduino uno R3

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • 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.