Вопросы по библиотеке GyverEncoder

vit12

✩✩✩✩✩✩✩
11 Янв 2020
1
0
Добрый день!
Сразу скажу что в программировании ничего не понимаю.
Попробовал пример из библиотеки, все работает но результат не тот.
Подскажите что изменить в скетче чтобы значения не передавались в ком порт, а выводились в переменную. Пусть переменная называется как слово в кавычках.
 

Вложения

adminecro

✩✩✩✩✩✩✩
2 Апр 2020
5
0
Есть задача переделать кнопки на энкодер на одном устройстве.
На устройстве есть три кнопки + - и включение/переключение настроек

Набросал такой скетч
C++:
#define CLK 9
#define DT 7
#define SW 8
#define right 3
#define swich 4
#define left 5
#include "GyverEncoder.h"
Encoder enc1(CLK, DT, SW);
int value = 0;
void setup() {
  Serial.begin(9600);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  digitalWrite(right, 1);
  digitalWrite(left, 1);
  digitalWrite(swich, 1);
  enc1.setType(TYPE1);
}
void loop() {

  enc1.tick();
  if (enc1.isFastR())
  {value++;}
  int i = 0;
    while (i<value){
    digitalWrite(right, 0);
    delay (10);
    digitalWrite(right, 1);
    i++;}
    value = 0;
  
  if (enc1.isRight()){
    digitalWrite(right, 0);
    delay (10);
    digitalWrite(right, 1);
    }
     if (enc1.isLeft()){
    digitalWrite(left, 0);
    delay (10);
    digitalWrite(left, 1);
    }

  if (enc1.isPress()) {
    digitalWrite(swich, 0);
    delay (10);
    digitalWrite(swich, 1);
  }
  if (enc1.isHold ()) {
    digitalWrite(swich, 0);
  }
  else {
    digitalWrite(swich, 1);
  }
}
Повороты на одно деление отрабатывают нормально. Но не могу побороть быстрый поворот. может кто подскажет как правильно сделать? ( в устройстве есть функция быстрого увлечения при зажатии кнопки)
 

kostyamat

★★★★★★✩
29 Окт 2019
1,097
630
@adminecro, не совсем понятно, вы пробуете некое устройство оснастить энкодером, с помощью внешней ардуины? Или вам нужно внести эти изменения в код самого устройства?

По сути: подозреваю, что ваше устройство десять нажатий в цикле, с периодом 10мс воспринимает как дребезг контактов, и отрабатывает один раз. Я бы на вашем месте убрал бы delay. А программировал действия по millis() для следующих прохождений loop.
И вот вы ещё говорите, что у устройства есть функция быстрого увеличения при зажатой кнопке. Конкретнее, как она работает? Вы зажимаете кнопку, и некие значения начинаю увеличиваться с повышением скорости?

Ок, если ещё актуально, отпишитесь, попробую исправить ваш код.
 
Изменено:

adminecro

✩✩✩✩✩✩✩
2 Апр 2020
5
0
@kostyamat, да есть устройство https://aliexpress.ru/item/32870325073.html хочу заменить на нем кнопки на энкодер. Изначально хотел использовать для этого atiny13a, но пока она едет решил код написать, потом поправить под атини.

Пытался делать через milis() пока не очень получилось(
Да в устройстве есть быстрый прирост значений при зажатии и удержании кнопки.
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,185
1,280
Москва
Вот кусочек кода, который я делал для одного товарища для регулировки яркости табло. Работает одной кнопкой так: нажал кнопку отпустил - яркость изменилась на , скажем +1, нажал отпустил еще +1, нажал держишь - быстрое увеличение. после отпускания кнопки изменение будет в обратную сторону. Т.е. при удержании будет быстрое уменьешение, при однократном нажатии-отпускании уменьшение на 1. Может скетч чем то поможет

C++:
void loop() {
  BRI_REG();
}

int Click_Br_Btn() {
  //static int CN=5;
  const uint32_t Delta_T = 150;
  const uint32_t Debouns_T = 30;
  static int direct_br = 1;
  static bool first_press = false;
  static int old_bri_btn = HIGH;
  static uint32_t Press_br_bt_time = 0;

  if (digitalRead(BRI_BUTTON) == LOW)
  {
    if (Press_br_bt_time == 0)
    {
      Press_br_bt_time = millis();
      first_press = true;
    }
    else
    {
      if ((millis() - Press_br_bt_time) > (Delta_T + 100 * first_press))
      {
        Press_br_bt_time = millis();
        first_press = false;
        return direct_br;
      }
    }
  }
  else
  {
    if (Press_br_bt_time == 0) return 0;
    else
    {
      if ((millis() - Press_br_bt_time) < Debouns_T) return 0;

      Press_br_bt_time = 0;
      if (first_press) return direct_br;
      else
      {
        direct_br = -direct_br;
        return 0;
      }
    }
  };
  return 0;
}

void BRI_REG() {
  switch (Click_Br_Btn())
  {
    case 0: return;
    case 1: {
        if (Britness < max_bright) Britness++;
        break;
      };
    case -1: {
        if (Britness > min_bright) Britness--;
        break;
      };
  }
}
 

kostyamat

★★★★★★✩
29 Окт 2019
1,097
630
@adminecro, пробуйте. Сразу говорю - в железе не проверял. Будут баги или вопросы по коду - обращайтесь.
C++:
#include "GyverEncoder.h"

#define CLK 9
#define DT 7
#define SW 8
#define right 3
#define swich 4
#define left 5

#define PERIOD 100U    // период, в миллисекундах, на который "нажимаются" кнопки left\right, то-есть состояния выводов поддерживается в состоянии LOW.
                       // Желательно подобрать минимально возможный, но так, чтобы целевой прибор четко фиксировал одно "нажатие" кнопки, каждый щелчек энкодера.
#define FAST 8U        // множитель для периода, удлинняющий период "нажатия" кнопок в N раз. Для режима быстрого вращения энкодераНужно подбирать опытным путем,
                       // так, чтобы целевое устройство четко фиксировало "зажатие" кнопки. (ИМХО, это в принципе глупо, и в результате пользователю не понравится
                       //этим пользоваться, потому как будет серьезный лаг управления - пока устройство поймет, что кнопка зажата, пока начнет наращивать показания,
                       // лаг в секунду-две обеспечен. Но другого способа попросту нет).

Encoder enc1(CLK, DT, SW);

unsigned long thisTime;


void setup() {
  Serial.begin(9600);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  digitalWrite(right, 1);
  digitalWrite(left, 1);
  digitalWrite(swich, 1);
  enc1.setType(TYPE1);
}



void loop() {
  static bool fast = false;

  enc1.tick();

  if (millis() - thisTime >= PERID * (fast ? FAST : 1)) {   // если быстро крутили энкодер, то кнопки left\right "нажимаются" на время PERIOD умноженный на FAST, иначе на 1.
                                                          // Значение множителя нужно подбирать, в зависимости от реакции целевого прибора.
    digitalWrite(left, 1);
    digitalWrite(right, 1);
    fast = false;
  }

  if (enc1.isTurn()) {               //если крутили энкодер, сбрасываем все состояния кнопок и снова взводим таймер. Это принудительно отменяет предыдущие действие.
    thisTime = millis();
    digitalWrite(left, 1);
    digitalWrite(right, 1);
    fast = false;
  }

  if (enc1.isRight()) {            // теперь проверяем куда крутили, и как быстро, "нажимаем" кнопки. Они будут в "нажатом" состоянии, пока не отработает таймер выше, или команда не будет принудительно отменена новой командой.
    digitalWrite(right, 0);
    fast = false;
  } else if (enc1.isLeft()) {
    digitalWrite(left, 0);
    fast = false;
  } else if (enc1.isFastR()) {
    digitalWrite(right, 0);
    fast = true;
  } else if (enc1.isFastL()) {
    digitalWrite(left, 0);
    fast = true;
  }

  if (enc1.isPress()) {           // Если кнопку нажали.
    digitalWrite(swich, 0);
  }
  if (enc1.isRelease()) {         // Если кнопку отпустили. Таким способом хоть зажимай кнопку, хоть кликай, это будет повторять действия пользователя.
    digitalWrite(swich, 1);
  }

}
 

adminecro

✩✩✩✩✩✩✩
2 Апр 2020
5
0
@kostyamat, спасибо огромное. Проверил вроде работает. На девайсе смогу уже завтра посмотреть. Единственное заметил один глюк, когда зажимаешь кнопку а потом отпускаешь она не отключается пока не нажмешь еще раз.
 

kostyamat

★★★★★★✩
29 Окт 2019
1,097
630
Единственное заметил один глюк, когда зажимаешь кнопку а потом отпускаешь она не отключается пока не нажмешь еще раз.
Странно. А если просто кликать, а не зажимать, отрабатывает ли клики правильно? Библиотеку где брали, обновлена ли до последней версии?
И вообще, не лучше ли вообще кнопку энкодера прямо на прибор завести, а не через ардуину. Так и ног меньше займет (вы же на аттини хотите делать в результате), и от глюков обезопасит. Один фиг зажатый энкодер в коде нигде не обрабатывается.
 

adminecro

✩✩✩✩✩✩✩
2 Апр 2020
5
0
Странно. А если просто кликать, а не зажимать, отрабатывает ли клики правильно? Библиотеку где брали, обновлена ли до последней версии?
И вообще, не лучше ли вообще кнопку энкодера прямо на прибор завести, а не через ардуину. Так и ног меньше займет (вы же на аттини хотите делать в результате), и от глюков обезопасит. Один фиг зажатый энкодер в коде нигде не обрабатывается.
Если кликать, то отрабатывает нормально. Брал вроде последнюю с гита.
 

kostyamat

★★★★★★✩
29 Окт 2019
1,097
630
Если кликать, то отрабатывает нормально.
О как! Значит глюк библиотеки. Похоже если кнопка зажата, флаг isHolded становится истинным, а isPress и isRelease не отрабатывают должным образом.
ОК. Можно обойти, но... я выше спрашивал - стоит ли кнопку энкодера вообще обрабатывать на внешнем контроллере? Правильнее ведь ее прямо на прибор завести. Это съекономит ноги контроллера, и избавит от возможных глюков. Зажатый энкодер мы один фиг не обрабатываем.

но, если вам так важно обрабатывать кнопку на внешнем контроллере попробдуйте строки
C++:
  if (enc1.isPress()) {           // Если кнопку нажали.
    digitalWrite(swich, 0);
  }
  if (enc1.isRelease()) {         // Если кнопку отпустили. Таким способом хоть зажимай кнопку, хоть кликай, это будет повторять действия пользователя.
    digitalWrite(swich, 1);
  }
заменить на
C++:
digitalWrite(swich, !enc1.isHold);
(не уверен, я этот метод из библиотеки еще не юзал, но по описанию вроде подходит)
 
Изменено:

adminecro

✩✩✩✩✩✩✩
2 Апр 2020
5
0
О как! Значит глюк библиотеки. Похоже если кнопка зажата, флаг isHolded становится истинным, а isPress и isRelease не отрабатывают должным образом.
ОК. Можно обойти, но... я выше спрашивал - стоит ли кнопку энкодера вообще обрабатывать на внешнем контроллере? Правильнее ведь ее прямо на прибор завести. Это съекономит ноги контроллера, и избавит от возможных глюков. Зажатый энкодер мы один фиг не обрабатываем.

но, если вам так важно обрабатывать кнопку на внешнем контроллере попробдуйте строки
C++:
  if (enc1.isPress()) {           // Если кнопку нажали.
    digitalWrite(swich, 0);
  }
  if (enc1.isRelease()) {         // Если кнопку отпустили. Таким способом хоть зажимай кнопку, хоть кликай, это будет повторять действия пользователя.
    digitalWrite(swich, 1);
  }
заменить на
C++:
digitalWrite(swich, !enc1.isHold);
(не уверен, я этот метод из библиотеки еще не юзал, но по описанию вроде подходит)
Ок попробую, спасибо. У меня по быстрым поворотам была идея записывать количество тактов поворота в переменную и потом вызывать digitalwrite на то количество которое он насчитал.
 

kostyamat

★★★★★★✩
29 Окт 2019
1,097
630
@adminecro, можно и так сделать. Вопрос в том, захочет ли целевой прибор обрабатывать такой спам по кнопке. Вы для начала так попробуйте. Потом посмотрим.
 

Dorfman

✩✩✩✩✩✩✩
29 Мар 2020
17
1
Ukraine
johnnsoft.space
Работает, но не правильно. При прокручивании ручки в одну сторону отображает, что ручка крутится то в одну сторону то в другую пепеременно. Типы в коде менял, не помогает. Скетч лью на Arduino UNO, энкодер вот такой модели A22 1pcs/lot Rotary Encoder Module Brick Sensor Development ky-040. До этого брал другие проэкты с сайта, всё работало отлично.

Пробовал другую библиотеку. Там всё ОК. Энкодер делает 4 тика за 1 деление.
У меня такая же каша. В одну сторону кручу - показывает +1 через произвольное количество тиков, причём по непонятным причинам ещё и -1 прописывает (декремент). Самопроизвольно пишет, что я нажимал кнопку (хотя я даже не прикасался к ней). Другая либа через прерывания работает как часики. Грешу на несовместимость с камнем (у меня Due), хотя компиллятор ошибок (даже нотисов) не даёт.
Перепробовал 4 энкодера, обвязал чем только можно (в последней попытке даже через 2 инверсных триггера Шмидта пропускал, ТЛ2 / 7414) - результат тот же.
Есть ещё пострадавшие?
 
Изменено:

kostyamat

★★★★★★✩
29 Окт 2019
1,097
630
@Dorfman, делал я один проект, в нем использовал эту библиотеку и энкодер от компьютерной мышки.
Энкодер использовал вообще без обвязки. Сигнальные выводы кинул прямо на контроллер, а тактовый на массу (повторил схему подключения как в мышке). Библиотеку настроил на внутреннюю подтяжку сигнальных входов энкодера к плюсу питания (HIGH_PULLUP). Работает просто отлично, и без прерываний.
Единственная библа, которая захотела работать с мышиным энкодером и таким подключением.
Кстати, у нее масса настроек, попробуйте почитать внимательно.
 
Изменено:

Мистер Грин

✩✩✩✩✩✩✩
26 Апр 2020
2
0
Добрый день, подскажите как совместить обработку функций считывания значений с DHT22, DS3231 и Функции Энкодера, дело в том, что Если в основном цикле разместить все эти функции, то работают функции считывания значений с DHT22, DS3231, а функция Энкодера не работает , и наоборот. В общем Функция Энкодера не работает совместно с другими функциями. Пытался сделать запуск по таймерам в прерывании тоже не выходит. Подскажите кто знает .
C++:
//Функция обработки Энкодера

void ReadEncoder(){
  enc.tick();
  if (enc.isTurn()) { //1.если поворот
    Serial.println("Пововорот");
    if (enc.isRightH()) { //Если поворот вправо с нажатием, то переходим на следующий экран меню
      Serial.println("Поворот вправо, с нажатием");
      counter = 0;
      if (menu > 8) {
        menu = 0;
      }
      menu++;
      }
      else if (enc.isLeftH()) { //Если поворот влево с нажатием, то переходим на предыдущий экран меню
      Serial.println("Поворот влево, с нажатием");
      if (menu < 0) {
        menu = 8;
      }
      menu--;
      }
      //сохраним настройки
      if (menu == 8) {
        menu = 0;
        EEPROM.put(0, TempHeat_On);
        EEPROM.put(20, TempHeat_Off);
        EEPROM.put(40, HumVent_On);
        EEPROM.put(60, HumVent_Off);
        EEPROM.put(80, Uvlag_On);
        EEPROM.put(100, Uvlag_Off);
        EEPROM.put(200, Vent_Active);
        EEPROM.put(201, Uvlag_Active);
        //выведем сообщение об успешном сохранении настроек
        lcd.setCursor(0, 0);
        lcd.print(MakeString("Settings"));
        lcd.setCursor(0, 1);
        lcd.print(MakeString("Saved"));
        
      }
      DrawLCD();
    
  }
  
    //2.Если поворот вправо, увеличиваем значения на текущем экране
     if (enc.isRight()) {
      Serial.println("Поворот вправо, изменяем настройки ");
      counter = 0;
      switch (menu) {
        case 0:
          menu = 0;
          DrawLCD();
          break;
        case 1:
          menu = 1;
          TempHeat_On += 0.1;
          DrawLCD();
          break;
        case 2:
          menu = 2;
         TempHeat_Off += 0.1;
          DrawLCD();
          break;
        case 3:
          menu = 3;
          HumVent_On++;
          DrawLCD();
          break;
        case 4:
          menu = 4;
          HumVent_Off++;
          DrawLCD();
          break;
        case 5:
          menu = 5;
          Vent_Active = Vent_Active + 1;
          if (Vent_Active > 1) {
            Vent_Active = 0;
          }
          DrawLCD();
          break;
        case 6:
          menu = 6;
          Uvlag_On += 0.1;
          DrawLCD();
          break;
        case 7:
          menu = 7;
          Uvlag_Off += 0.1;
          DrawLCD();
          break;
        case 8:
          menu = 0;
          DrawLCD();
          break;

      }
    }
    //3.Если поворот влево уменьшаем значение на текущем экране
    else if (enc.isLeft()) {
      Serial.println("Поворот влево, изменяем настройки");
        
      counter = 0;
      switch (menu) {
        case 0:
          menu = 0;
          DrawLCD();
          break;
        case 1:
          menu = 1;
          TempHeat_On -= 0.1;
          DrawLCD();
          break;
        case 2:
          menu = 2;
          TempHeat_Off -= 0.1;
          DrawLCD();
          break;
        case 3:
          menu = 3;
          HumVent_On--;
          DrawLCD();
          break;
        case 4:
          menu = 4;
          HumVent_Off--;
          DrawLCD();
          break;
        case 5:
          menu = 5;
          Uvlag_Active = Uvlag_Active + 1;
          if (Uvlag_Active > 1) {
            Uvlag_Active = 0;
          }
          DrawLCD();
          break;
        case 6:
          menu = 6;
          Uvlag_On -= 0.1;
          DrawLCD();
          break;
        case 7:
          menu = 7;
          Uvlag_Off -= 0.1;
          DrawLCD();
          break;
        case 8:
          menu = 0;
          DrawLCD();
          break;

      }
    }

    //4.длинное нажатие кнопки - отключаем подсветку дисплея
    if (enc.isHolded())
    {
        lcd.setBacklight(false);
    }
    
    //5.длинное нажатие кнопки - включаем подсветку дисплея
    if (enc.isHold())
    {
        lcd.setBacklight(true);
        
    }

    //когда ничего не нажато
    else {
      HoldTime = 0;
      //если на экране настройки/информации ничего долго (в течение 20 сек) не нажимается то возвращаемся в режим отображения температуры и влажности
      if (menu != 0 && counter > 2000) {
        //если возврат производится с какого-либо экрана настройки, то сообщим о том, что настройки не были сохранены
        if (menu < 8) {
          
          lcd.setCursor(0, 0);
          lcd.print(MakeString("      Settings     "));
          lcd.setCursor(0, 1);
          lcd.print(MakeString("     NOT Saved      "));
        }
          menu = 0;
          counter = 0;
          DrawLCD;
        }
        
      }
    
    counter++; //увеличиваем значение счетчика циклов программы
 
 
}


Функция отображения времени:

void printTime() {
    uint32_t myTimer_tiktak;
  if (tiktak == " ") {
    tiktak = ":";
  }
  else {
    tiktak = " ";
  }
  if (millis() - myTimer_tiktak >= 10000) {
    myTimer_tiktak = millis(); // сбросить таймер
    
   }
  lcd.setCursor(1, 0);
  lcd.print(rtc.getHours());
  tiktak;
  lcd.setCursor(3, 0);
  lcd.print(tiktak);
  lcd.print(rtc.getMinutes());


  lcd.setCursor(12, 0);

  lcd.print(rtc.getDate());
  lcd.print(".");
  lcd.print(rtc.getMonth());

  lcd.setCursor(18, 0);
  lcd.print(rtc.getDay());
}

Функция получения значений с DHT22

void ReadData() {
  //читаем с датчика
  rh = dht.readHumidity();
  //  Serial.println(rh);
  rt = dht.readTemperature() - 0.5; //с поправкой на пол градуса, т.к. температура слегка завышается этим датчиком
  //  Serial.println(rt);
  //проверяем считанное значение, если пустое то выдаем ошибку, если не пустое то производим вычисления
  if (isnan(rh) || isnan(rt)) {
    //если не удалось считать данные
    lcd.setCursor(0, 1);
    strOut = MakeString("NO");
    lcd.print(strOut);
    lcd.setCursor(6, 1);
    strOut = MakeString("DATA");
    lcd.print(strOut);
  }
  else {
    measureCnt++; //увеличили количество проведенных измерений
    h = h + rh; //суммируем показания влажности
    t = t + rt; //суммируем показания температуры
    //если набрали нужное количество измерений
    if (measureCnt == measureCntMax) {
      //вычисляем средние значения
      h = h / measureCntMax;
      t = t / measureCntMax;
      //запомним последние значения температуры и влажности для вывода на экран
      out_h = String(h);
      out_t = String(t);
      //включаем/отключаем нагрузку
      if (t != 0 && h != 0) {
        //      DoAll(); //процедура, котоаря управляем нагрузкой в соответствии с правилами
      }
      //сбрасываем счетчик количества измерений
      measureCnt = 0;
      h = 0;
      t = 0;
    }
    DrawLCD();
  }
}
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,185
1,280
Москва
182-ая строка стоит DrawLCD; а везеде до этого DrawLCD(); - функция
а по огрызку кода ничего не понятно. на 1-ый взгляд косяков не видно. вопрос что происходит в функции DrawLCD. как часто вызываешь readdata и printTime.
А так ищи какая функция тормозит цикл loop
 

iSKM

✩✩✩✩✩✩✩
3 Июн 2020
1
0
Не реализованы конструкторы без параметров. Для работы "виртуального энкодера"!!!!
 

nik45ru

✩✩✩✩✩✩✩
7 Фев 2021
21
0
Почему вот так отлично работает:
void loop() {
enc1.tick();
if (enc1.isRight()) n++, A=(float)k*X/n, Serial.println(A);
}

и так работает
void loop() {
enc1.tick();
if (enc1.isRight()) {
n++;
A=(float)k*X/n;
Serial.println(A);
}
}

а вот так энкодер жутко глючит
void loop() {
enc1.tick();
if (enc1.isRight()) n++;
A=(float)k*X/n;
Serial.println(A);
}

Если в не условия, что то написать, то энкодер жутко глючит. Почему? Как избавиться от глюков энкодера.
 
Изменено:

poty

★★★★★★✩
19 Фев 2020
2,988
895
@nik45ru, это "глюк программиста", а не энкодера. В последнем случае на каждом цикле (несколько десятков тысяч раз в секунду) вычисляется A и выводится всё это в серийный порт. Вычисления с плавающей точкой сами по себе жутко тормозные, а если ещё и порт указан, допустим, 9600 кбит/сек, то вывод будет длится вечность.
 

nik45ru

✩✩✩✩✩✩✩
7 Фев 2021
21
0
А вот в таком случае, в чем дело? Здесь вычислений ни каких нет. Точно такой же глюк: либо на энкодер вообще не реагирует либо выскакивают какие то случайные числа.
Понятно, что туплю я, вот и пытаюсь разобраться, понять свою ошибку.

C++:
void loop() {
enc1.tick();
if (enc1.isRight()) n++;
Serial.println(n);
}
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,185
1,280
Москва
Сколько времени занимает функция вывода значения в монитор порта ?
Сколько времени занимает тик энкодера ?
Условием и инкрементом можно пренебречь
 

nik45ru

✩✩✩✩✩✩✩
7 Фев 2021
21
0
time = micros() - time; говорит что:
1. Не более 12 мкс
2. Не более 4 мкс.
Тогда задам вопрос по другому, как сделать чтоб что то подобное заработало корректно
C++:
void loop() {
enc1.tick();
if (enc1.isRight()) n++;
A=(float)k*X/n;
Serial.println(A);
}
С Ардуинкой играюсь вторую неделю, очень интересно, но есть очень много вопросов, связанных с особенностями работы.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,185
1,280
Москва
Даже при таком раскладе выходит, что 75% времени занимает вывод в монитор. и только 25% идет на обслуживание энкодера.

Приведенный ниже код крутиться в цикле loop всего 962 раза в секунду. Этого мало для приличной работы энкодера, надо от 5000,а лучше от 10.
Если убрать вывод в монитор порта, то скорость будет сразу 65 000 раз в секунду.

C++:
#define SW 4
#define DT 2
#define CLK 3

#include "GyverEncoder.h"
Encoder enc1(CLK, DT, SW, TYPE2);

void setup() {
   Serial.begin(9600);

}
int n=0;

void loop() {
enc1.tick();
if (enc1.isRight()) n++;
Serial.print(n);
ShowFPS();
}

void ShowFPS()
{
  static uint32_t tm_m = 0;
  static uint32_t cnt_m = 0;
  cnt_m++;
  if ((millis() - tm_m) > 1000)
  {
    Serial.println();
    Serial.print("loop per sec: "); Serial.println(cnt_m);
    cnt_m = 0;
    tm_m = millis();
  }
}
Почти никогда не надо выводить в монитор порта с такой частотой, если данные не принимает машина с другой стороны.
Если скорость порта сделать 115200 , то скорость без вывода не изменится, что логично, а с выводом возрастет до 11500.

Если ваш код
снабдить выводом по изменению значения, например так:
C++:
int n=0;
int old_n=0;

void loop() {
enc1.tick();
if (enc1.isRight()) n++;
if (n!=old_n)
  {
   old_n=n;
  Serial.print(n);
  }
ShowFPS();
}
То скорость будет около 63 000 циклов loop в секунду.
Однако самое правильное было выводить это все в условии там, где меняется n, как в 1-ом посте работающие примеры, скорость будет 66000 lps
 
  • Лойс +1
Реакции: nik45ru

nik45ru

✩✩✩✩✩✩✩
7 Фев 2021
21
0
Дело в том, что переменные, будут браться не только с энкодера и вывод будет на LCD, дисплей. С RotaryEncoder.h вроде получается как задумал, но не нравиться реакция энкодера, с GyverEncoder.h реакция отличная, но не получается.
Спасибо за разъяснение, в общем нужно отслеживать состояние переменных и только при их изменении выполнять расчёт и выводить результат, непрерывного расчёта и вывода не получится.