Problem z zerowaniem licznika - Wersja do druku +- Arduino Polska Forum (https://forum.arduinopolska.pl) +-- Dział: Korzystanie z Arduino (https://forum.arduinopolska.pl/dzial-korzystanie-z-arduino) +--- Dział: Piaskownica (https://forum.arduinopolska.pl/dzial-piaskownica) +--- Wątek: Problem z zerowaniem licznika (/watek-problem-z-zerowaniem-licznika) |
Problem z zerowaniem licznika - kataklysm - 10-09-2019 Mam problem z bardzo prostą funkcją mianowicie kiedy kręcę enkoderem na wyświetlaczu co obrót dodawałem 1 a kiedy osiągnął pewną wartość to się zerwał, mniej więcej tak: int suma = 0; suma = suma + 1; if (suma == 30){ suma = 0; } I to działało ale potrzebowałem miec większą rozdzielczość tego licznika więc użyłem float: float suma = 0; suma = suma + 0.10; if (suma == 30.00){ suma = 0.00; } Niestety ten zapis nie działa licznik w ogóle się nie zeruje a w drugą stronę zaczyna pokazywać liczby ujemne. Proszę o pomoc. RE: Problem z zerowaniem licznika - Robson Kerman - 10-09-2019 Może suma nie osiąga wartości 30? Może osiąga, ale w tym czasie program jest gdzie indziej? Ciężko stwierdzić nie mając schematu i kodu. Na pewno zadziała: if(suma>30) RE: Problem z zerowaniem licznika - semi - 10-09-2019 (10-09-2019, 08:29)Robson Kerman napisał(a): Może suma nie osiąga wartości 30?Dla liczb zmiennoprzecinkowych == często nie mają zastosowania. kataklysm napisał(a):potrzebowałem miec większą rozdzielczość tego licznika więc użyłem float:W ten sposób nie zwiększysz rozdzielczości enkodera tylko sposób reprezentacji. W programach należy unikać liczb zmiennoprzecinkowych, zwłaszcza w powolnych AVR bez FPU. Jeśli dane chcesz reprezentować z rozdzielczością 0,01 użyj liczb stałoprzecinkowych. Jeśli chcesz zwiększyć rozdzielczość enkodera używaj obu zboczy sygnału z enkodera (rozdzielczość x 2) albo obu zboczy obu sygnałów (A i B) wtedy rozdzielczość zwiększysz 4 krotnie. Nie z każdym enkoderem to się uda, niektóre zatrzymują się tylko w takich pozycjach, że rozdzielczość można zwiększyć tylko 2 krotnie. Jeśli potrzeba jeszcze większa precyzja użyj innego enkodera, który daje więcej impulsów na obrót. Porównanie trzeba realizować w procedurze przerwania od enkodera, w przeciwnym wypadku nie zawsze będzie wykonane poprawnie. RE: Problem z zerowaniem licznika - Agregacik - 10-09-2019 Sprawdziłem to na takim przykładzie i stwierdziłem, że program nie działa tak jak pisał autor. float suma = 0; float a = 30; float b = 0.5; //podstawiając za b = 0.5 program działa poprawnie dla b = 0.2 już nie void setup() { Serial.begin (9600); } void loop() { suma = suma + b; Serial.println ( suma ); if (suma == a) // gdy tu zmieni się warunek na >= to działa poprawnie przy b = 0.1 { Serial.println ( "suma = 30" ); suma = 0; } delay (100); } Dlaczego warunek == nie działa poprawnie dla float. Sprawdziłem Liczba 0.1 w systemie dwójkowym przyjmuje wartość przybliżoną a wielokrotna suma tej liczby, nie może być nigdy dokładnie 30 i stąd warunek (suma ==30) nigdy nie będzie spełniony. Trzeba dać warunek (suma >=30) lub (suma > 30). RE: Problem z zerowaniem licznika - kataklysm - 11-09-2019 (10-09-2019, 11:57)Agregacik napisał(a): Sprawdziłem to na takim przykładzie i stwierdziłem, że program nie działa tak jak pisał autor. Zgadza się, ale < > działa więc sobie poradziłem. Dzięki wszystkim RE: Problem z zerowaniem licznika - kaczakat - 11-09-2019 I dlatego wszędzie piszą, by unikać float'ów. W kodzie programu możesz mieć wartości 0-300 z typem np. int czy uint16_t, zastosowanie jest dużo szersze niż float, a gdy potrzeba pokazywać z przecinkiem użyć własną funkcją na kilka linijek. Na liczby ujemne sam musisz napisać obsługę, że jak mniejsze od 0 to =0, dla typów bez znaku przekręci Ci licznik na koniec zakresu typu, np. 255 dla typu uint8_t. |