Skocz do zawartości

ESP32 - licznik do rowerka treningowego


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

(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

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

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

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.

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 😉

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

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