Skocz do zawartości

Prędkościomierz i zerowanie licznika


jarsek

Pomocna odpowiedź

Witam kolegów .Mam mały problem z poniższym kodem może ktoś znalazł by chwilę czasu.Jest to licznik prędkości na jednym kontaktronie.Licznik mierzy czas między zwarciami kontaktronu i działa bardo dobrze. Tylko w momencie kiedy koło staje i nie daje impulsów to wskazania km/h się nie zerują.Pokazuje ostatnia wartość zmierzona i nie chce pokazać 0,0 km/h ...chodzi o to żeby dopisać funkcję porównania np. trzech ostatnich wartości zmiennej "half_revolution_time" i jeżeli są one takie same to wyzerować wyświetlacz.Ta zmienna liczy czas w milisekundach między zwarciami i jest małe prawdopodobieństwo że podczas normalnej pracy wyniki się powtórzą . Niestety moje arduino jest słabe...Z góry dzięki.

//płytka arduino NANO

//na kole o obwodzie 2 metrów jest jeden kontaktron.Zwiera do masy wejście D2

//program oblicza prędkość km/h,obroty koła,pokonaną drogę i zrobione hektary.

//mierzymy czas jednego obrotu,bo uzyskiweane obroty są małe.

#include

#include

#define OLED_RESET 4

Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)

#error(“Height incorrect, please fix Adafruit_SSD1306.h!”);

#endif

float obwodkola = 2.0; // obwód koław metrach

word obrot;

byte state;

float czas3 = 0;

int czas1 = 0;

int czas2 = 0;

int zerowanie = 7000;

// Odczyt obrotĂłw (RPM)

int half_revolution_time = 0; //Utworzenie zmiennej przechowujÄcej

int rpm = 0; //Utworzenie zmiennej RPM (obroty)

unsigned long lastmillis = 0; //Utworzenie zmiennej long lastmilis

void rpm_fan() {

unsigned long static last_event = 0;

if (millis() - last_event < 5) { //debouncing

return;

}

half_revolution_time = (millis() - last_event);

last_event = millis();

}

void setup() {

Serial.begin(9600);

pinMode(2, INPUT_PULLUP); // Aktywowanie rezystora podciÄgajÄcego na pinie 2

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

display.setTextColor(WHITE);

attachInterrupt(digitalPinToInterrupt(2), rpm_fan, FALLING);

// Przypisanie funkcji rpm_fan przerwania zewnÄtrznego

// Przerwanie zostanie wykonane jeĹli stan zmieni siÄ z wysokiego na niski (Falling)

}

void loop() {

if (millis() - lastmillis >= 1000) //Aktualizuj co sekunda, bÄdzie to rĂłwnoznaczne z odczytem czÄstotliwoĹci (Hz)

{

lastmillis = millis(); // Aktualizacja lastmillis

noInterrupts(); // W trakcie kalkulacji wyłącz obsługę przerwań

rpm = (60000 / half_revolution_time) ;

interrupts() ; //Przywraca przerwania

}

float predkosc = (obwodkola / half_revolution_time) * 3600;

float droga = (obwodkola * obrot) / 1000; // pokonana droga

float hektary = droga * 3.0 / 10; // hektary - obwód koła x szerokość maszyny podzielić przez hektar (10000m20

float czas3 = czas1 - czas2;

if (digitalRead(2) == LOW && state == HIGH)

{

obrot++;

state = LOW;

czas2 = millis();

}

else if (digitalRead(2) == HIGH)

{

state = HIGH;

czas1 = millis();

}

if (czas3 >= zerowanie)// zerowanie liczników powyżej 7 sekund

{

rpm = 0;

predkosc = 0;

}

Serial.print(predkosc,1);

Serial.println(" km/h");

Serial.println();

display.clearDisplay();

display.setCursor(0,0);

display.setTextSize(2);

display.print(predkosc, 1);

display.println(" Km/h");

display.setCursor(0,17);

display.print(rpm); //ilość obrotów koła na minutę

display.println(" obr/m");

display.setCursor(0,33);

display.print(droga, 3); // pokonana droga

display.println(" km");

display.setCursor(0,50);

display.print(hektary, 3); // hektary - obwód koła x szerokość maszyny podzielić przez hektar (10000m20

display.println(" ha");

display.display();

}

Link do komentarza
Share on other sites

Wszystko przez to, że zmienną half_revolution_time ktora używasz do obliczenia prędkości zmieniasz w przerwaniu od kontaktronu. To moze zostac, a prosciej bedzie to zrobić w ten sposob by zalozyc sobie jakis maksymalny czas pomiedzy zwarciami kontaktronu i powyzej tego czasu zalozyc ze stoimi w miejscu i wpisac do zmiennej predkosc wartosc 0 i dopiero potem ja wypisywac. Najprosciej zrobic zmienna last_event globalna i z niej korzystac w petli głównej.

Link do komentarza
Share on other sites

Edytowałem kod. Zrobiłem czas 7 sekund po którym resetują się liczniki.Resetują się gdy na wejściu jest stan wysoki ale jak jest niski(magnes stoi na kontaktronie) to nie resetują.Prośba o linijkę kodu...aby po 7 s przy stanie LOW też był reset licznika.

Link do komentarza
Share on other sites

Szkoda, że edytowałeś kod, a nie zostawiłeś poprzedniej wersji. Zastanawiałem się czy to 7 sekund wybrałeś świadomie czy tak strzelałeś, bo według twojego kodu czas 7 sekund pomiędzy zwarciami kontaktronu daje prędkość około 1km/h, czyli około 27cm\s. No nic tak jak pisałem wcześniej ja bym zmienił zmienną last_event ze statycznej na globalną volatile i w pętli głównej sprawdzał bym warunek coś w rodzaju:

if (millis() - last_event >= zerowanie) 
{
  rpm = 0;
  predkosc = 0; 
} 

wtedy pozbywasz się dodatkowych zmiennych czas1,2,3. Jednak dalej nie jest rozwiązany problem z zerowaniem prędkości, gdy akurat zatrzymasz koło tak by magnes znajdował się około kontaktronu. Na pewno nie będzie to stały sygnał stanu niskiego, bo koło może się przesuwać +- parę cm w przód i w tył i wtedy masz bardzo dużo impulsów w krótkim czasie, więc wyliczona prędkość będzie bardzo duża. Nie napisałeś tak poza tym do czego to konkretnie będzie wykorzystane, mierzysz prędkość czego? Bo Gdybyś znał, lub założył jakąś maksymalną prędkość np 10km/s to wtedy mógłbyś obliczyć minimalny czas pomiędzy zwarciami kontaktronu (dla 10km\s half_revolution_time=720) i poniżej tego czasu również ignorowałbyś pomiary, wtedy warunek byłby taki:

if (millis() - last_event >= zerowanie || half_revolution_time <= 720) 
{
  rpm = 0;
  predkosc = 0; 
} 
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

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!

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

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.