Проблемы с модификатором static

Тема в разделе "Arduino & Shields", создана пользователем WhiteFox, 24 фев 2021.

  1. WhiteFox

    WhiteFox Нуб

    Функция encControl() не видит приватные переменные. Перепробовал всякое, но безуспешно.

    Весь код:
    Код (C++):
    #pragma once
    #include <Arduino.h>

    #define minTimeKey 100;

    class Control_Enc {

      public:
        Control_Enc(byte pinS1, byte pinS2, byte pinKey);

      private:
        byte _pinS1, _pinS2, _pinKey;
        byte bePos, beResult;
        bool beKey = 1;
        unsigned long beKeyTime;
        static void encControl();
    };

    Control_Enc::Control_Enc(byte pinS1, byte pinS2, byte pinKey) {
      _pinS1 = pinS1;
      _pinS2 = pinS2;
      _pinKey = pinKey;
      pinMode(digitalPinToInterrupt(_pinS1), INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(_pinS1), encControl, FALLING);
      pinMode(digitalPinToInterrupt(_pinS2), INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(_pinS2), encControl, FALLING);
      pinMode(digitalPinToInterrupt(_pinKey), INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(_pinKey), encControl, CHANGE);
    }


    static void Control_Enc::encControl() {
      //достаем переменные ручки и кнопки
      bool s1, s2, key;
      s1 = digitalRead(_pinS1); //нач. полож. = 1
      s2 = digitalRead(_pinS2); //нач. полож. = 1
      key = digitalRead(_pinKey); //нач. полож. = 1

      //вычисляем положение ручки и кнопки
      bool pressKey;
      byte pos, result;
      pressKey = key && !beKey; //1(кнопка отжата), 0(ост. варианты)
      pos = !s1 && !s2 ? 3 : !s1 ? 1 : !s2 ? 2 : 0; //0(1:1), 1(0:1), 2(1:0), 3(0:0)

      //вычисление результата
      result = pos != 3 ? 0 : bePos == 1 ? 1 : bePos == 2 ? 3 : 0;
      result += !key && result != 0;
      if (pressKey && ((millis() - beKeyTime) >= 100)) {
        result = (beResult == 2) || (beResult == 4) ? 5 : 6;
        beKeyTime = millis();
      }
      beResult = result != 0 ? result : beResult;
      bePos = pos;
      beKey = key;

      if (result != 0) Serial.println(result);
    }
     
  2. AlexU

    AlexU Гуру

    Потому что она статичная -- static
     
  3. WhiteFox

    WhiteFox Нуб

    attachInterrupt() требует статичную функцию, я не могу убрать static от encControl().
    Код (C++):
    attachInterrupt(digitalPinToInterrupt(_pinS1), encControl, FALLING);
     
  4. AlexU

    AlexU Гуру

    В этом случае можно сделать дружественную функцию (friend) с параметром, который будет принимать экземпляр класса. И эту дружественную функцию использовать в прерывании.
    Но это не самый хороший способ.
    Лучше сделать глобальный синглетон, который будет доступен в обработчике прерывания. В этом случае функция 'encControl()' должна быть публичной и не статичной. Она будет вызываться из обработчика прерывания.
     
  5. AlexU

    AlexU Гуру

    Хотя может делать синглетон -- лишнее.
    Но в любом случае должен быть экземпляр класса с публичным методом, который будет доступен из обработчика прерывания.
     
  6. parovoZZ

    parovoZZ Гуру

    А к чему это всё, если можно сделать через ISR() и разрешать/запрещать прерывания напрямую через регистры? Если хочется вызывать разные функции из прерывания, то или флаги, или указатели на функции (callback).