Skocz do zawartości

Błędny odczyt prędkości w liczniku rowerowym Arduino-Dem


Pomocna odpowiedź

Tak przy okazji: istnieją metody EEPROM.Get() i EEPROM.Update().

I jeszcze przy okazji: nie liczyłbym na wbudowany EEPROM w Arduino, bo po pewnym czasie zacznie robić jaja (teoretycznie jest gwarancja 100.000 zapisów do konkretnej komórki, czyli po 100 km jest duża szansa na to, że będziesz musiał bawić się w nowe Arduino).

Małe EEPROM-y (takie kilobitowe) na I2C mają dużo wyższą trwałość - dla 24LC01B gwarantowany jest milion zapisów, czyli jaja się zaczną dziać po 1000 km a nie 100. W rzeczywistości mogą wytrzymać dużo więcej. Poza tym w razie czego wymieniasz szybko siedzący sobie w podstawce scalaczek za 2 PLN a nie całe Arduino.

2 godziny temu, Gintek napisał:

 a lok to jest ilość impulsów.

Nie liczysz zadnych impulsow...bo zawsze beda bledy, bo nie jestes w stanie zmierzyc np. 0.3/0.7/0.1 obrotu itp...podczas ruszenia czekasz na wykrycie ustalonego stanu czujnika, zapisujezz aktualny czas np. millis()..czekasz az kolo zrobi pelny cykl/obrot i wtedy pobierasz czas jaki uplynal od startu i robisz obliczenia...poprostu podczas kazdego obrotu robisz obliczenia i wtedy nie ma zadnego bledu...jedyne co to to ze im wolniej jedziesz tym wolniej sa odswiezane dane..

10 minut temu, farmaceuta napisał:

podczas kazdego obrotu robisz obliczenia i wtedy nie ma zadnego bledu...

Będzie błąd spowodowany rozdzielczością millis().

Przy prędkości jest to mało ważne, ale przy obliczaniu drogi błąd się może skumulować.

Ja bym to zrobił inaczej:

Droga obliczana poprzez zliczanie impulsów (tak jak jest w tej chwili w programie)

Prędkość obliczana tak jak pisałeś (poprzez pomiar czasu między impulsami, najlepiej w mikrosekundach), przy czym powyżej pewnej prędkości brałbym pod uwagę średnią z kilku poprzednich pomiarów.

W takiej sytuacji pomiar prędkości nawet obarczony pewnym błędem nie wpłynie na pomiar dystansu, który zawsze będzie dokładny (pomijając poślizg kół).

Tu jeszcze pytanie do autora: co będzie, jeśli pojedziesz ciągnikiem na wstecznym?

 

55 minut temu, ethanak napisał:

Będzie błąd spowodowany rozdzielczością millis().

Przy prędkości jest to mało ważne, ale przy obliczaniu drogi błąd się może skumulować.

Tak tak...o tym nie wspomnialem bo zakladam ze kazdy wie ze millis() nie jest zbyt dokladne jesli chodzi o liczenie czasu...

Zliczanie trasy/drogi no to wiadomo..co obrot dodaje wartosc obwodu kola 

59 minut temu, ethanak napisał:

przy czym powyżej pewnej prędkości brałbym pod uwagę średnią z kilku poprzednich pomiarów.

A czemu tak? Da to jakis lepszy/dokladniejszy wynik?

(edytowany)
2 godziny temu, farmaceuta napisał:




d_etapu = lok * d_kola;                                 //długość etapu w metrach   
   de_km = d_etapu/100;
   
     
   de_int = int(de_km);  

Rzutujesz do int cos co chyba jest po przecinku tak??

Tak zgadza się.

Prędkość jest pokazywana bardzo dokładnie i zmienia się płynnie, sprawdzałem przy pomocy GPS. Problem jest z pokazywaniem przejechanej drogi. W monitorze portu szeregowego pokazuje mi ilość impulsów i jak tą ilość pomnoże według wzoru z tego programu to wyniki pokrywają się z wyświetlanym na wyświetlaczu. Problem występuje po zamontowaniu tego do ciągnika.

Edytowano przez Gintek
6 minut temu, Gintek napisał:

Tak zgadza się.

No i pewnie stad ten blad...wszystko co masz po przecinku po rzutowanie przepadnie czyli np...2.7/4.8/1.2 da Ci ostatecznie 2/4/1 

ehh...chyba ze ja sie zamotalem i nie rozumiem czegos...po co tak wogole rzutujesz??

4 minuty temu, farmaceuta napisał:

No i pewnie stad ten blad...wszystko co masz po przecinku po rzutowanie przepadnie czyli np...2.7/4.8/1.2 da Ci ostatecznie 2/4/1 

ehh...chyba ze ja sie zamotalem i nie rozumiem czegos...po co tak wogole rzutujesz??

Ja tego programu nie robiłem moja wiedza na ten temat jest za skromna.

(edytowany)
29 minut temu, Gintek napisał:

 Problem jest z pokazywaniem przejechanej drogi.

Akurat to jest prostsza sprawa do obliczenia...poprostu zrob tak zeby co obrot kola dodawac stala/obwod kola i tyle...i masz gotowy wynik...tylko zmienne jesli sa typu float to nie rzutuj ich do int bo stracisz po przecinku wszystko...i blad bedzie duzy..

Edytowano przez farmaceuta
(edytowany)

Tu problem chyba leży w tym że nie wszystkie impulsy są liczone. Przy wolnym jednostajnym zbliżaniu do czujnika indukcyjnego metalu tylko co któryś impuls jest dodany mimo że dioda na czujniku miga w rytm zbliżania metalu. Np. na podanych 10 impulsów naliczyło tylko 3.

Edytowano przez Gintek
7 minut temu, farmaceuta napisał:

obrot kola dodawac stala/obwod kola

Bez sensu. Jaka jest dokładność floatów (szczególnie przy dodawaniu liczb różniących się o kilka rzędów wielkości)? Pamiętaj, że to Arduino i tu nie ma double.

Liczysz impulsy, a przed pokazaniem mnożysz ilość przez obwód. Licznik impulsów typu uint32_t (zwykły int przekręci się po paru kilometrach).

59 minut temu, farmaceuta napisał:

Da to jakis lepszy/dokladniejszy wynik?

teoretycznie tak. Jeśli jednak (jak pisze autor wątku) prędkość pokazywana jest prawidłowo, nie ma sensu komplikowanie programu.

3 minuty temu, Gintek napisał:

Tu problem chyba leży w tym że nie wszystkie impulsy są liczone

Bo tak się impulsów nie liczy. A delay() w loop wcale w tym liczeniu nie pomaga.

 

10 minut temu, ethanak napisał:

Bez sensu. 

No jak? Skoro obliczam predkosc co obrot to przy okazji zwiekszam licznik trasy o ten obwod...moja rozdzielczoscia wtedy jest wielokrotnosc obwodu kola, ale to bez znaczenia i bledu nie ma...

 

10 minut temu, ethanak napisał:

Liczysz impulsy, a przed pokazaniem mnożysz ilość przez obwód. Licznik impulsów typu uint32_t (zwykły int przekręci się po paru kilometrach).

Oczywiscie ja tez bym zrezygnowal z floata a tylko calkowite zmienne...jedynie finalny wynik no to wiadomo po przecinku jesli chcemy np wynik 12.68km...a impulsow nie trzeba liczyc bo tu wystepuje tylko jeden na obrot...jak w temacie (rowerze)

32 minuty temu, farmaceuta napisał:

to bez znaczenia i bledu nie ma...

Tak mówisz?

#include <stdio.h>

void main(void)
{
    float wynik,wynik2;
    float obwod=0.231;
    long int p_dystans=10000; // dla 10 km
    long int p_count = p_dystans/obwod;
    long int i;
    printf("Liczymy %d impulsów\n", p_count);
    for (i=0, wynik=0;i<p_count;i++) wynik += obwod;
    wynik2=p_count * obwod;
    printf("%f %f\n", wynik, wynik2);
}

Wynik:

Liczymy 43290 impulsów
10002.167969 9999.990234

Pozostawię bez komentarza.

18 minut temu, ethanak napisał:

Tak mówisz?

Nie no ja sie zgadzam calkowicie z Toba..😉 

Mowiac ze nie bedzie bledow mialem na mysli caly czas tylko(!) liczby calkowite...czyli zamiast 0.231 lub w metrach 2.31 zapisuje sobie 231(cm) i podczas dodawania do np. uint32_t bledu nie mam...floata uzywam tylko jako ostateczny wynik do wyswietlenia...(teraz tez rozumiem o co z tym mnozeniem przez ilosc impulsow chodzilo, bo ja to blednie rozumialem przed chwila) i jak najbardziej mozna i mnozyc...😅

Dnia 8.08.2021 o 22:07, Gintek napisał:

Dziękuję za podpowiedź, zsumowałem oba czasy stanu wysokiego i niskiego i wygląda na to że będzie dobrze. Nie potrafię jeszcze sobie poradzić z naliczaniem czasu przejazdu który uruchamia się po ruszeniu wskazania licznika. Wygląda to tak że im prędkość jest większa tym czas szybciej leci.

Chyba mam winowajcę błędnego naliczania obrotów przez co jest błędnie podawana przejechana droga. Wygląda na to że winne jest sumowanie czasów impulsu i przerwy między impulsami. Bo jak jest brana pod uwagę tylko długość impulsu to wtedy licznik drogi działa poprawnie.

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...