Skocz do zawartości
slon2005

Co robię nie tak, mruganie diody podczas gdy powinna świecić ciągle

Pomocna odpowiedź

Cześć, konstruuję urządzenie do informowania czy dany cykl jest robiony w normie czasowej, czy po za normą czy tez z zapasem. I teraz wszystko wydaję mi się, że powinno działać dzieje się tak że dioda przygasa tak jak by wraz "odświeżaniem" pętli loop. Wcześniej miałem problem, że dioda nie świeciła tylko pomrugiwała ledwo świecąc ale jak przeniosłem kod od diody przed delay to się problem odwrócił na ten obecny. Czy coś źle to logicznie sobie w głowie ułożyłem,  czy wystarczy coś miejscami zamienić. Dla bardziej zainteresowanych załączam film w zipie, jednak na nim nie widać tak dokładnie tych przygasań, za to dla oczu są one nieprzyjemne.

#include <LiquidCrystal.h> 
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
int zmienna = 0;
float czas = 0;
void setup() {

pinMode(7, INPUT);// ustawienie pinow
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
  lcd.begin(16, 2);// ustawienia wyswietlacza
  lcd.setCursor(0, 0);
  lcd.print("Witaj!!!"); 
  lcd.setCursor(0, 1);
  lcd.print("Zaczynajmy");
Serial.begin(9600);// monitor portu szeregowego
Serial.println(zmienna);
}

void loop() {
if (digitalRead(7) == LOW){ // odbieranie sygnału z czujnika indukcyjnego
  czas = czas+0.25; 
  Serial.println(zmienna);// wyswietlanie w porcie szeregowym
  Serial.println(czas);
  digitalWrite(4, LOW); // wyłączenie wszystkich diód
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  lcd.clear();// formula wyswietlania
  lcd.setCursor(0, 0);
  lcd.print("Czas:"); 
  lcd.print(czas);
  lcd.setCursor(0, 1);
  lcd.print("Cykl:");
  lcd.print(zmienna);
 if (czas > 1 && czas < 25){ // warunek dla zielonej diody
digitalWrite(4, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
 }
 if (czas > 25 && czas < 30){//warunek dla diody zoltej
  digitalWrite(4, LOW);
    digitalWrite(5, HIGH);
    digitalWrite(6, LOW);
 }
  if (czas > 30){//warunek dla diody czerwonej
     digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, HIGH);
  }
   delay(250);/przerwa 

  if (czas == 20){ // formula do liczenia cykli ktora eliminuje poprawianie szybkie nabijanie cykli
    zmienna = zmienna + 1;
  }}else (czas = 0); // zerowanie licznika
}
  
 


 

87447560_2261823544120468_102867739504279552_n.jpg

video-1582714045.zip

Udostępnij ten post


Link to post
Share on other sites

Nie mam aktualnie możliwości przetestowania kodu (piszę na telefonie), ale podejrzewam, że jest to związane z charakterystyką zmiennych typu float. 

Arduino reference: float

Wszędzie gdzie masz porównania do float dodaj „.0” czyli:

„if (czas > 1.0 && czas < 25.0){ // warunek dla zielonej diody”

Jeżeli to nie rozwiąże problemu to wieczorem spróbuje pomóc ponownie już z PC. 

Udostępnij ten post


Link to post
Share on other sites

Nie pomogło, tutaj coś jest czego nie rozumiem w pętli loop bo jak delay zmienię na 1000 to to przygaszenie występuje co sekundę. W tym samym czasie jest mrugnięcie diody  TX na płytce. Za to jak przerzucę delay ponad  warunki do zaświecenia diód w kodzie to dioda mruga w tej częstotliwości co wcześniej przygasała. Więc wrzuciłem warunki zaświecania diód przed delay i po delay ale nadal jest mrugnięcie:)

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Nie, nie, ta dioda nie powinna świecić, kazałeś jej przecież mrugać!

Zobacz co robisz.

Jeśli na pinie masz stan niski, wykonujesz kolejno:

a) gasisz wszystkie diody;

b) robisz jakieś czary z wyświetlaczem (które trochę trwają) i w czasie tych czarów diody są zgaszone

c) ewentualnie zapalasz jakąś diodę - chociaż niekoniecznie, bo np. jeśli czas == 25 to nie zapalasz, prawda?)

d) czekasz jakiś czas i wracasz do a)

No i jak to ma nie migać?

Tu nie trzeba czegoś gdzieś przestawić, tylko po prostu napisać to od początku, ale tym razem porządnie:

a) do mierzenia czasu służy funkcja millis() a nie liczenie obrotów pętli, która wcale nie wykonuje się tyle czasu ile wpisałeś w delay() tylko z reguły więcej.

Przykładowo (nie jest to prawidłowe rozwiązanie, ale bliskie Twojemu i jako-tako działające):

uint32_t czas;
static uint32_t poczatek;

if (digitalRead(7) == LOW) {
  czas = millis() - poczatek;
  /* tu już mamy czas w milisekundach od pojawienia się zera na pinie
  * robimy jakieś czary mary z diodamii wyświetlaczami
  */
} else {
  poczatek = millis();
}

  

b) instrukcja "if" ma również klauzulę "else", czyli zamiast powielać warunki można napisać:

if (czas < 25000) {
  zapal_zielona_leda();
}
else if (czas < 30000) {
  zapal_zolta_leda();
}
else {
  zapal_czerwona_leda();
}

    

Prawda, że prościej?

 

Przy okazji - zapewniam, że nie ma to nic wspólnego z floatami (co nie znaczy że trzeba ich używać do liczenia czegokolwiek - wręcz przeciwnie!).

Edytowano przez ethanak
  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites

Dzięki wielkie, faktycznie przecież ja mu każe w pętli wyłączyć wszystkie diody więc musi migać 😆 Czasami jak się mózg zablokuje to nie widzi tego co przed oczami leży... co do millis to jeszcze nie doszedłem do tego w kursie więc lada moment będę się tego uczył. Więc programy niedługo powinny wyglądać lepiej:) jeszcze raz dzięki 

Udostępnij ten post


Link to post
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!

Gość
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...