Arduino Polska Forum

Pełna wersja: Prosty stoper - problem z uruchomieniem
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Stron: 1 2
Hej, właśnie jestem na początku mojej drogi w programowaniu Arduino i trochę się wyboista zrobiła Big Grin

Napisałam taki oto kod i wszystko się kompiluje, ale odliczanie czasu nie działa. Ktoś podpowie gdzie szukać błędu?

Kod:
void minutes() {
  if (mins < 10) { //for one digit
    lcd.setCursor(1, 1);
    lcd.print(mins);
    lcd.setCursor(0, 1);
    lcd.print(0);
  }
  else { //for two digits
    lcd.setCursor(0, 1);
    lcd.print(mins);
  }
}

void seconds() {
  if (sec < 10) {
    lcd.setCursor(4, 1);
    lcd.print(sec);
    lcd.setCursor(3, 1);
    lcd.print(0);

  }
  else {
    lcd.setCursor(3, 1);
    lcd.print(sec);
  }

  if (sec == 60) { //changing minutes
    mins++;
    minutes();
    lcd.setCursor(3, 1);
    lcd.print("00");
  }
}

void miliseconds() {
  if (ms < 10) {
    lcd.setCursor(7, 1);
    lcd.print(ms);
    lcd.setCursor(6, 1);
    lcd.print(0);

  }
  else {
    lcd.setCursor(6, 1);
    lcd.print(ms);
  }
  delay(10);
  ms++;

  if (ms == 100) {
    sec++;
    ms = 0;
    seconds();

  }
}
Kod:
void startWatch() {
  GreenState = analogRead(Green);

  if (GreenState == LOW) { //button pressed
    while (1) {
      miliseconds();
      stopWatch();//check if stop was pressed
    }
  }
}
potem wywołuję startWatch(); w loop 
wszystkie deklaracje mam w innym pliku, jest ustawienie pinów i konfiguracja wyświeltacza
Zakładam że nakręciłam w tej części z czasem :/
Pokaz to " stopWatch();"
(10-08-2019, 19:46)Jarewa0606 napisał(a): [ -> ]Pokaz to " stopWatch();"
Kod:
//for stop the clock

void stopWatch() {
  RedState = analogRead(Red);
  if (RedState == LOW) { //button pressed
    while (1) {
      lcd.setCursor(9, 1);
      lcd.print("finish");
    }
  }
}
A wyświetla się coś?? błąd jest ale mimo to jakieś krzaczki na wyświetlaczu powinny być do 60s powinno liczyć w miarę dobrze choć użycie funkcji delay w tym to pomyłka na 1s możesz mieć pomyłki  15%..



Kod:
  if (sec == 60) { //changing minutes
    mins++;
    minutes();
    lcd.setCursor(3, 1);
    lcd.print("00");
  }


Nie resetujesz zmiennej "sec"   a po drugie wysyłasz gdzieś indziej a jeszcze nie wyświetliło powinno być

Kod:
  if (sec == 60) { //changing minutes
    mins++;
    lcd.setCursor(3, 1);
    lcd.print("00");
    sec=0;
    minutes();

  }


No i ten if powinien być pierwszy by widzieć 59s-0s a nie 59s-60s-0s

No i najważniejsze sekundnik powinien być na przerywaniach to da bardzo dokładne wyniki. Wykorzystaj timer a nie delay. Od biedy można jeszcze użyć funkcji millis.
Niestety tak to nie zadziała, nawet jak Ci się będzie wydawało, że działa, to tylko tak sobie. Minimum to użycie funkcji millis() do odmierzania czasu. Możesz użyć funkcji z C sprinf do formatowania ciągu znaków tak by wyrzucać na ekran całą linię tekstu:

Kod:
char napis[17]; 
sprintf(napis,"%02d:%02d:%02d:%02d",godziny,minuty,sekundy,dziesiatkims); //to wrzuca zmienne spoza napisu do napisu, a calosc jest wrzucana do tablicy char napis.
  lcd.print(napis);

Znajdź sobie w historii postów funkcję czas(), wrzuciłem tam przykład jak odliczać czas z millis().
Jak już będziesz chciała bardziej dokładnie to trzeba użyć swojego timera i przerwań.
Użycie delay() powoduje, że każde dodanie/odjęcie polecenia w loop zmieni sposób zliczania czasu. 
Użycie millis() do odmierzenia 10ms też może być niedokładne, czasami coś może umknąć gdy pętla będzie dłuższa niż kilka ms. Lepiej byłoby zarejestrować stan początkowy z millis, końcowy i z tego obliczyć czas zmierzony stoperem, a te pośrednie wyliczenia ms pokazywane w czasie mierzenia  traktować tylko orientacyjnie (i tak cyferki szybko przelatują).
Można jeszcze tak formatować 
Kod:
    lcd.setCursor(15, 0);
    lcd.print(int(czas_godz / 10));
    lcd.print(czas_godz % 10);
    lcd.print(":");
    lcd.print(int(czas_min / 10));
    lcd.print(czas_min % 10);

I tak zliczac 
Kod:
  ////////////  czas MTh

  if (Time_czas >= 2)
  {

    Time_czas = 0;
    czas_sek++;

    if (czas_sek == 60)
    {
      czas_sek = 0;
      czas_min++;
    }
    if (czas_min == 60)
    {
      czas_min = 0;
      czas_godz++;
    }
    //if(czas_godz==24){h=0;}
  }

Time_czas pochodzi od timera ustawiony na 2Hz..  

Bez problemu ustawisz timer1 na 100Hz wtedy przerywanie będzie dokładnie co 10ms.. 

Cod w setup dla Ardunio 16MHz użycie TIMER1

Kod:
cli();
TCCR1A = 0;
TCCR1B = 0;
TCNT1  = 0;
OCR1A = 19999;
TCCR1B |= (1 << WGM12);
TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10);
TIMSK1 |= (1 << OCIE1A);
sei();

 


Kod:
ISR(TIMER1_COMPA_vect){
   ms++;
}


ms będzie dodawało dokładnie co 10ms
Do timerów to ja jeszcze nie doszłam, ale na pewno biorę się za lekturę.
Dziękuję wszystkim za wypowiedzi
(11-08-2019, 09:54)Jarewa0606 napisał(a): [ -> ]Można jeszcze tak formatować 
Kod:
    lcd.setCursor(15, 0);
    lcd.print(int(czas_godz / 10));
    lcd.print(czas_godz % 10);
    lcd.print(":");
    lcd.print(int(czas_min / 10));
    lcd.print(czas_min % 10);
W porównaniu do kodu kaczakat ten jest dłuższy a zmienne będzie wyświetlał bez poprzedzającego zera co w przypadku sekund i dziesiątych części sekund nie wygląda zbyt ciekawie.
A po co ci 056 sekud?? Jak wystarczy 56.

Nie wiem co jest lepsze ale tutaj nie ma tablicy więc ta metoda mniej zajmuje. Pierwsze dzieli przez 10 i pokazuje dziesiątki drugie pokazuje końcówkę czyli od 0-9
(13-08-2019, 14:38)Jarewa0606 napisał(a): [ -> ]A po co ci 056 sekud?? Jak wystarczy 56.
Napisałeś tak jakbys nigdy nie widział zegara cyfrowego lub stopera. K0d, który pokazałeś wyświetli tak:
0:0
0:1
...
0:9
0:10
0:11
Widziałeś zegar czy stoper wyświetlający czas w ten sposób? Jak dodasz sekundy jeszcze ciekawsze efekty będą.

(13-08-2019, 14:38)Jarewa0606 napisał(a): [ -> ]ale tutaj nie ma tablicy
Jakiej tablicy? Ile mniej?

(13-08-2019, 14:38)Jarewa0606 napisał(a): [ -> ]więc ta metoda mniej zajmuje.
Jakiej tablicy? Ile mniej?

Dodaj jeszcze wyświetlanie w prawidłowy sposób i ponownie sprawdź ile zajmie pamięci.
Stron: 1 2