Keresés

Hirdetés

Új hozzászólás Aktív témák

  • ecaddsell

    aktív tag

    válasz Vladi #9925 üzenetére

    Na akkor rotary encoder prell mentesítés még egyszer.
    Az alapötlet innen:
    https://www.best-microcontroller-projects.com/rotary-encoder.html
    Én KY-040-el használom (sokat), hibázni még nem láttam. A logika megszakításban megy, a lekérdezés poll.
    A speed control arról szól, hogy ha gyorsabban tekered akkor nagy ugrásokkal megy. Frekvencia beállításnál igen hasznos, máshol ahol fontos, hogy az elmozdulással legyen arányos az érték meg nem kell (ki kell kapcsolni).
    Mivel ez is olyan téma, hogy jó megoldást még nem láttam (ezért voltam kénytelen egyet írni), hibásat annál többet, érdemes eltenni a linket.
    Kommentelni akkor szoktam kódot, ha nagyon kell. Sorry.

    /*
    This code is free software; you can redistribute it and/or
    modify it under the terms of the CC BY-NC-SA 3.0 license.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND...
    */

    #define ROTE_CLK GPIO_NUM_xx
    #define ROTE_DT GPIO_NUM_xx

    #define ROTE_SPCTM 50000 // speed control time limit, not defined no speedctrl

    volatile int32_t rotval = 0;
    void IRAM_ATTR isrrot() {
    volatile static uint8_t pinsta = 0x3, cwi = 0, ccwi = 0;
    volatile static uint8_t cwexp[] = {0xD, 0x4, 0x2, 0xB};
    volatile static uint8_t ccwexp[] = {0xE, 0x8, 0x1, 0x7};
    int32_t rvchg;
    #ifdef ROTE_SPCTM
    volatile static uint32_t tc = 0, tm = 0;
    uint32_t ctm, td;
    #endif

    pinsta = (pinsta << 2) & 0xf;
    if (digitalRead(ROTE_DT)) pinsta |= 0x2;
    if (digitalRead(ROTE_CLK)) pinsta |= 0x1;

    if (pinsta == cwexp[cwi]) cwi++;
    else if (pinsta == ccwexp[ccwi]) ccwi++;
    if (cwi == 0x4 || ccwi == 0x4)
    {
    if (cwi == 4) rvchg = 1;
    else rvchg = -1;
    pinsta = 0x3; cwi = 0; ccwi = 0;
    #ifdef ROTE_SPCTM
    ctm = micros();
    td = ctm - tm;
    tm = ctm;
    if (td < ROTE_SPCTM / 2) rvchg *= 7;
    else if (td < (ROTE_SPCTM * 2) / 3) rvchg *= 4;
    else if (td < ROTE_SPCTM) rvchg *= 2;
    #endif
    rotval += rvchg;
    }
    } // isrrot

    int16_t getrotv() {
    static int32_t lval = 0;
    int32_t cval = rotval;
    int16_t rotc = 0;
    if (lval != cval) {
    rotc = cval - lval;
    lval = cval;
    }
    return (rotc);
    } // getrotv

    void inirotein(gpio_num_t clk, gpio_num_t dt) {
    pinMode(clk, INPUT);
    pinMode(dt, INPUT);
    attachInterrupt(digitalPinToInterrupt(clk), isrrot, CHANGE);
    attachInterrupt(digitalPinToInterrupt(dt), isrrot, CHANGE);
    } // inirotein

    ...
    inirotein(ROTE_CLK, ROTE_DT);
    ...

Új hozzászólás Aktív témák