Вопрос по энкодеру

dengeneral
Offline
Зарегистрирован: 04.05.2018

Всем привет! Подскажите пожалуйста как сделать так чтобы когда вращаешь ручку энкодера данные прибавлялись не по 1 а по например 10 или по 100 за один тик.

 

Вот сам скетч

 

/*  Стенд для продувки форсунок
 *   построен на генераторе прямоугольных импульсов
 *   Частота 80 Гц (ограничена специально для стенда)
 *   Детали: Ардуино УНО, энкодер
 *   Оцените труд программиста! Вознаграждения приветствуются!
 *   Посетите мой youTube канал
 *   "Ардуино&Я Программирование микроконтроллеров"!
 *   *********************************************************
 */
//  Библиотеки 
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <RotaryEncoder.h>
#include <TimerOne.h>
#include <Bounce2.h>
//  Создание пользовательских символов
//  Создаём свой символ
byte customChar[8] = {
  0b00000,
  0b00000,
  0b11100,
  0b01110,
  0b00111,
  0b00111,
  0b01110,
  0b11100
};
//  Макросы 
#define drivePin      13
#define BUTTON_PIN    12
#define TIMEOUT       10000
#define xTIME         2000
#define highLevel     800
#define lowLevel      0
#define del           5
//  Объекты 
LiquidCrystal_I2C lcd(0x27, 16, 2);                                     //  установить адрес индикатора
RotaryEncoder encoder(A2, A3);                                          //  выводы к которым подключён энкодер
Bounce bouncer = Bounce();                                              //  создаем экземпляр класса Bounce
//  Переменные 
int frequency;
unsigned long previousTime, pressTime;
bool flagReady, flagLight, flagPress, flagPause;

void setup()
{
  pinMode(drivePin, OUTPUT);                                            //  настроить вывод drivePin на выход
  digitalWrite(drivePin, LOW);                                          //  установить низкий уровень
  PCICR |= (1 << PCIE1);                                                //  разрешение прерывания при изменении уровня на входах PCINT14-PCINT8 (смотри datasheet).
  PCMSK1 |= (1 << PCINT10) | (1 << PCINT11);                            //  разрешение прерывания по входу PC2, PC3 Atmega328 (Ардуино УНО А2, А3)
  pinMode(BUTTON_PIN, INPUT);                                           //  вывод, к которому подключена кнопка настраиваем на вход
  digitalWrite(BUTTON_PIN, HIGH);                                       //  включаем подтяжку
  bouncer.attach(BUTTON_PIN);                                           //  устанавливаем кнопку
  bouncer.interval(5);                                                  //  устанавливаем параметр stable interval = 5 мс
  Timer1.initialize();                                                  //  настройка таймера Т1
  lcd.init();                                                          //  настройка дисплея
  lcd.createChar(1, customChar);                                        //  регистрация собственного символа
  lcd.backlight();                                                      //  включение подсветки
  flagLight = true;                                                     //  взвод флага подсветки
  previousTime = millis();                                              //  запомнить время включения подсветки
  lcd.clear();                                                          //  очистка индикатора
  lcd.print(" Hello, Master!");                                         //  ПРИВЕТСТВИЕ!!
  delay(3000);                                                          //  пауза 3 секунды
  lcd.clear();                                                          //  очистка индикатора
  lcd.print("Set encoder");                                          //  ПРИВЕТСТВИЕ!!
}

void loop()
{
//  Получение данных с энкодера
  frequency = getDataEncoder();

//  Опрос кнопки энкодера
  askKeyEncode(); 

//  Генерация сигнала и визуализация
 if(flagReady)
 {
  driveTimer (frequency);
  visualShow(frequency);
  flagReady = false;
 }

//  Управление подсветкой
 if(flagLight)
 {
  if(millis() - previousTime > TIMEOUT)
  {
   lcd.noBacklight();
   flagLight = false; 
  }
 }
}

/*  ПОДПРОГРАММЫ  */
//  Опрос энкодера
int getDataEncoder(void)
{
static int pos = 0;  
  int newPos = encoder.getPosition();                                   //  опрос энкодера
  if(pos != newPos)                                                     //  если состояние энкодера изменилось
  {
   pos = newPos;                                                        //  запоминаем новое состояние
   if(pos > highLevel)                                                  //  если значение выше верхней границы
   {
    pos = highLevel;                                                    //  вводим ограничение 
    encoder.setPosition(pos);                                           //  передача энкодеру нового состояния
   }
   else if(pos < lowLevel)                                              //  если показания энкодера ниже нижней границы
        {
         pos = lowLevel;                                                //  вводим ограничение 
         encoder.setPosition(lowLevel);                                 //  передача энкодеру нового состояния
        }
  flagReady = true;                                                     //  установить флаг готовности
  lcd.backlight();                                                      //  включение подсветки
  flagLight = true;                                                     //  взвод флага подсветки
  previousTime = millis();                                              //  запомнили время
  }
  return pos;                                                           //  возврат значения
}

//  Опрос кнопки, принятие решения
void askKeyEncode(void)
{
 if(bouncer.update())                                                   //  если произошло событие (нажали или отпустили кнопку)
 {
  if(bouncer.read() == LOW)                                             //  если кнопка нажата
  { 
   lcd.backlight();                                                     //  включение подсветки
   flagLight = true;                                                    //  взвод флага подсветки
   previousTime = millis();                                             //  запоминаем время включения подсветки
   pressTime = previousTime;                                            //  запоминаем время нажатия кнопки
   flagPress = true;                                                    //  взвод флага нажатия
  }
  else if(flagPress)                                                    //  если кнопку отпустили сразу (до time-out), то 
       {
        if(frequency != 0)                                              //  при ненулевых значениях частоты
        {
          if(flagPause) flagPause = false;                              //  возобновляем работу, если была пауза
           else flagPause = true;                                       //  ставим на паузу, если была работа
        }
        flagPress = false;                                              //  сбросили флаг нажатия
        flagReady = true;                                               //  и, естественно, взводим флаг готовности  
       }
 } 
 else if(flagPress && (millis() - pressTime > xTIME))                   //  если нажатую (см флаг нажатия)кнопку удерживали долго
       {
        frequency = 0;                                                  //  останавливаем машину
        encoder.setPosition(0);                                         //  передача энкодеру нового состояния
        flagPress = false;                                              //  сбросили флаг нажатия
        flagPause = false;                                              //  сбросили флаг паузы
        flagReady = true;                                               //  и, естественно, взводим флаг готовности  
       }
}

//  Управление таймером Т1
void driveTimer (int freq)
{
unsigned long period;
  if(freq == 0 || flagPause == true)                                    //  если частота = 0 или взведён флаг паузы
  {
    Timer1.detachInterrupt();                                           //  отключение прерывания 
    digitalWrite(drivePin, LOW);                                        //  установить низкий уровень
  }
  else
    {
      period = 500000 / freq;                                           //  определяем период в мксек
      Timer1.attachInterrupt(drive, period);                            //  настройка прерывания по истечению заданного периода
    }
}

//  Вывод данных на дисплей
void visualShow(int freq)
{
  lcd.clear();                                                          //  очистка индикатора
  if(freq > 0)                                                          //  если частота больше нуля (генератор работает)
  {
   if(flagPause) lcd.print(" PAUSE");                                   //  если взведён флаг паузы - вывод на экран слово PAUSE
    else lcd.print("  GEN");                                            //  иначе выводим надпись ГЕНЕРАЦИЯ
   lcd.setCursor(10, 0);                                                //  указываем знакоместоместо
   lcd.print(freq);                                                     //  выводим значение частоты
   lcd.print("Hz");                                                     //  знак "Гц"
   byte k = freq / del + 1;                                             //  этот блок
   byte i = 0;
   while(i < k/16)                                                         //  нужен
   {
    lcd.setCursor(i, 1);                                                //  для  
    lcd.print("\1");                                                    //  отображения >>>>>>>...
    i++; 
   }
  }
  else lcd.print("     STOP");                                             //  если частота = 0, то выводим надпись СТОП
}

//  Обработчик внешних прерываний
ISR(PCINT1_vect)
{
 encoder.tick();                                                        //  вызов функции tick()
}

void drive()
{
 digitalWrite(drivePin, digitalRead(drivePin) ^ 1 );                    //  генерация прямоугольного импульса
}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

надо просто ручку вращять в 10 или 100 раз быстрее.  Можно даже зажать её в дрель. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

а можно просто дать немношко денег автору программы, и он поменяет.  

dengeneral
Offline
Зарегистрирован: 04.05.2018

Ну понятно.. но что делать если автор не отвечает )). 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

просто ты ему денег не предлагал.  Конечно, мошт тут нахаляву чужой скетч поправят. 

dengeneral
Offline
Зарегистрирован: 04.05.2018
dengeneral
Offline
Зарегистрирован: 04.05.2018

Спасибо.. вот оно оказывается 

 

  int x;
  x = getDataEncoder();
  frequency = x*10;

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

а если в 103 строке

  pos = newPos+10;               

 

b707
Offline
Зарегистрирован: 26.05.2017

dengeneral пишет:

Спасибо.. вот оно оказывается

спорим, что про 100 сам не догадаешься?

dengeneral
Offline
Зарегистрирован: 04.05.2018
frequency = x*100;

не? 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Зачем так жестоко? Я про frequency? Не проще ли полезть в библиотеку и RotaryEncoder там +1 на +100500 поменять?

dengeneral
Offline
Зарегистрирован: 04.05.2018

ok)