Skocz do zawartości

ESP32 - licznik do rowerka treningowego


roz

Pomocna odpowiedź

(edytowany)

@ethanak zrobiłem tak (googlając):

xTaskGetTickCount(); //version of millis() that works from interrupt

Spróbowałem zmienić 40ms na 20ms i działa również idealnie.

void IRAM_ATTR counterUp()
{
    
    unsigned long now = xTaskGetTickCount();
    if (now < next_pulse)
    {
        return;
    }
    counter++;
    next_pulse = now + 40; // następny impuls za nie mniej niż 40ms
}

 

Efekt taki, że liczy dokładnie, idealnie po jednym w górę. bez względu na prędkość obrotu korbami 🙂

 

---- Otwarto port szeregowy COM14 ----
20:32:32:688 -> 0
20:32:35:618 -> 1
20:32:37:016 -> 2
20:32:38:077 -> 3
20:32:38:807 -> 4
20:32:39:375 -> 5
20:32:39:905 -> 6
20:32:40:455 -> 7
20:32:40:994 -> 8
20:32:41:532 -> 9
20:32:42:112 -> 10

 

Edytowano przez roz
Link do komentarza
Share on other sites

3 minuty temu, roz napisał:

@ethanak

void IRAM_ATTR counterUp()
{
    
    unsigned long now = xTaskGetTickCount();
    if (now < next_pulse)
    {
        return;
    }
    counter++;
    next_pulse = now + 40; // następny impuls za nie mniej niż 40ms
}

 

Efekt taki, że liczy dokładnie, idealnie po jednym w górę. bez względu na prędkość obrotu korbami 🙂

 

 

 

Ale z tym moim kodem to nie zrobi różnicy bo zawsze reagujesz na zmiany stanów

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

(edytowany)

Bo w twoim kodzie trzeba było dodać sprawdzenie. Pokazałem wyżej jak.

Ma być nie "zawsze reagujesz" tylko "reagujesz kiedy trzeba".

Edytowano przez ethanak
Link do komentarza
Share on other sites

@ethanak

9 minut temu, ethanak napisał:

To się właśnie nazywa debouncing 🙂

Tak, ale tamten był z millis() i nie chciało to współpracować ze sobą jak widać.

Kontaktron daje jeden impuls w tej chwili. 

Ważne, że jest jeden a nie trzy czy więcej..

Dziękuję wszystkim za pomoc oraz poświęcony czas.

Link do komentarza
Share on other sites

(edytowany)

No chyba się poddam z tym, to jakieś niemożliwe...

kod:

 

volatile unsigned long old_counter = 1, next_pulse = 0, counter_one = 0, counter_two = 0;
volatile bool first = true;

void IRAM_ATTR counterUp()
{
    unsigned long now = xTaskGetTickCount(); // millis(); // xTaskGetTickCount();
    if (now < next_pulse)
    {
        return;
    }
    if (first)
    {
        counter_one = xTaskGetTickCount(); // millis();
        first = false;
    }
    else
    {
        counter_two = xTaskGetTickCount(); // millis();
        first = true;
    }
    // counter = now;
    next_pulse = now + 40; // następny impuls za nie mniej niż 10ms
}

void setup()
{
    Serial.begin(115200);
    pinMode(reed_pin, INPUT);
    attachInterrupt(digitalPinToInterrupt(reed_pin), counterUp, RISING);
}

bool stan = true;
unsigned long czas_s, last_time;
float trasa;
float obwod_k = 0.74;

void loop()
{
    unsigned long timenow = millis();
    if ((counter_one > 0) && (counter_two > 0))
    {
        Serial.println("START");
        Serial.print("counter one ");
        Serial.println(counter_one);
        Serial.print("counter two ");
        Serial.println(counter_two);
        long x = (counter_two - counter_one);
        unsigned long xx = abs(x);
        Serial.print("xx ");
        Serial.println(xx);
        czas_s = xx / 1000.00;
        Serial.print("czas_s ");
        Serial.println(czas_s);

        float obroty = 3600 / czas_s;
        Serial.print("obroty ");
        Serial.println(obroty);
        float predkosc = (obroty * obwod_k) / 1000.00;
        trasa = trasa + obwod_k; // metry
        // Serial.println(predkosc);
        // Serial.println(trasa);

        Serial.print("predkosc ");
        Serial.println(predkosc);
        Serial.println("KONIEC");
    }
    else
    {
        Serial.println("nic tu nie ma...");
    }
    delay(2000);
}

 

Wynik (skróciłem, żeby bałaganu nie robić).

Pytanie: dlaczego xx / 1000 = 0 ?

 

START
counter one 94416
counter two 94722
xx 306
czas_s 0
Guru Meditation Error: Core  1 panic'ed (IntegerDivideByZero). Exception was unhandled.
 

START
counter one 4232
counter two 4388
xx 156
czas_s 0
Guru Meditation Error: Core  1 panic'ed (IntegerDivideByZero). Exception was unhandled.
Edytowano przez roz
Link do komentarza
Share on other sites

39 minut temu, roz napisał:

Bo zmienna czas_s ma być float a nie long....

A wczoraj farmaceuta o tym wspominał 😜 i Po co Ci ten counter? I to przerwanie? To tylko komplikuje cały kod który jest bardzo prosty

Link do komentarza
Share on other sites

11 minut temu, farmaceuta napisał:

Po co Ci ten counter? I to przerwanie? To tylko komplikuje cały kod który jest bardzo prosty

Jest prosty, bo procesor nie ma nic innego do roboty. A jak @roz będzie chciał pododawać jakieś dalsze funkcjonalności do tego liczniczka, angażujące moc obliczeniową procesora, to nie wiem czy nie będzie musiał się w końcu przeprosić z przerwaniami.

Link do komentarza
Share on other sites

10 minut temu, jand napisał:

Jest prosty, bo procesor nie ma nic innego do roboty. A jak @roz będzie chciał pododawać jakieś dalsze funkcjonalności do tego liczniczka, angażujące moc obliczeniową procesora, to nie wiem czy nie będzie musiał się w końcu przeprosić z przerwaniami.

Zgadzam się, ale z regoly jest tak że używamy tego co nam jest aktualnie potrzebne, a tutaj przerwanie nie jest niezbędne...nie można też tak do końca zakładać że muszę użyć przerwania bo być może w przyszłości będę chciał to i to dorobić...bo wtedy nawet miganie LED by pasowało robić na timer'ach, rejestrach etc, tak na wszelki wypadek 😉

Link do komentarza
Share on other sites

7 minut temu, ethanak napisał:

@farmaceuta to jest esp32 i do migania ledami robisz sobie task z delayami w środku. Dużo prostsze niż millisy i timery.

Nawet się wziąłem za tego rtos'a, i nawet trochę ogarnąłem te mutexy,schedulery,taski etc...no ale po dwóch miesiącach jestem znów w czarnej d...bo zapomniałem 😢 przekleństwo z tą pamięcią mam...😢

Link do komentarza
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...

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.