Вопрос по энкодеру
- Войдите на сайт для отправки комментариев
Пт, 23/11/2018 - 12:31
Всем привет! Подскажите пожалуйста как сделать так чтобы когда вращаешь ручку энкодера данные прибавлялись не по 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 ); // генерация прямоугольного импульса
}
надо просто ручку вращять в 10 или 100 раз быстрее. Можно даже зажать её в дрель.
а можно просто дать немношко денег автору программы, и он поменяет.
Ну понятно.. но что делать если автор не отвечает )).
просто ты ему денег не предлагал. Конечно, мошт тут нахаляву чужой скетч поправят.
https://www.youtube.com/watch?v=rEIGhbit72w
Спасибо.. вот оно оказывается
а если в 103 строке
Спасибо.. вот оно оказывается
спорим, что про 100 сам не догадаешься?
не?
Зачем так жестоко? Я про frequency? Не проще ли полезть в библиотеку и RotaryEncoder там +1 на +100500 поменять?
ok)