вопрос по библиотеке RotaryEncoder

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

здравствуйте дорогие форумчане

нашел библиотеку RotaryEncoder для работы с энкодером библиотека понравилась работой без "тормозов"

да и аналоговые выхода заняты вместо цифровых

на библиотеку сылка  https://yadi.sk/d/vtDkM8DJn6YkR

пример с библиотеки ниже

// -----
// InterruptRotator.ino - Пример для библиотеки RotaryEncoder.
// Этот класс реализован для использования с самой среде программирования.
// Copyright (C) Маттиас Хертелем http://www.mathertel.de
// Эта работа лицензируется в соответствии с лицензией BSD в стиле. См http://www.mathertel.de/License.aspx
// Дополнительная информация о: http://www.mathertel.de/Arduino
// -----
// 18.01.2014 созданный Маттиасом Хертел
// -----

// Этот пример проверяет состояние датчика вращения в функции частоты ().
// Текущая позиция печатается на выходе при изменении.

// Установка оборудования:
// Присоединить энкодер с выходными контактами на A2 и A3.
// Общая контакт должен быть подключен к земле.

#include <RotaryEncoder.h>

// Настроить RoraryEncoder для штырей A2 и A3:
RotaryEncoder кодер (А2, А3);

недействительными установки ()
{
  Serial.begin (57600);
  Serial.println ("пример SimplePollRotator для библиотеки RotaryEncoder.");

  // Вы, возможно, придется изменить следующие 2 строки при использовании других выводов, чем А2 и А3
  PCICR | = (1 << PCIE1); // Это позволяет Pin прерывания по изменению 1, который охватывает контакты аналоговый вход или порт C.
  PCMSK1 | = (1 << PCINT10) | (1 << PCINT11); // Это позволяет прерывание для штифта 2 и 3 порта С
} // настроить()



// Обработчик прерываний служба по Изменить PIN прерывания 1
// Эта процедура будет вызываться только о любом изменении сигнала на A2 и A3: именно там, где нам нужно проверить.
ISR (PCINT1_vect) {
  encoder.tick (); // Просто позвонить галочку (), чтобы проверить состояние.
}


// Прочитать текущую позицию кодера и распечатать при изменении.
недействительными цикл ()
{
  статическая INT пос = 0;

  INT newPos = encoder.getPosition ();
  если (поз! = newPos) {
    Serial.print (newPos);
    Serial.println ();
    пос = newPos;

    // Просто чтобы показать, что длительные процедуры долго не сломать энкодер:
    // Когда newPos 66 выводе будет заморозить, но наработанные позиции будут признаны даже когда не опрошено.
    // Прерывание по-прежнему работает.
    // Выход правильно 6.6 секунд.
    если (== newPos 66)
      задержка (6600);
  } // если
} // Цикл ()

// Конец

 

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

0259 пишет:

здравствуйте дорогие форумчане

нашел библиотеку RotaryEncoder для работы с энкодером библиотека понравилась работой без "тормозов"

да и аналоговые выхода заняты вместо цифровых

Поздравляем с находкой!

Только непонятно, что делает в названии топика слово "вопрос". В самом топике никакого вопроса нет :(

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

оёёё извините случайно создал 2 темы вот онаже ну уже провереная и с вопросом!

http://arduino.ru/forum/programmirovanie/vopros-po-biblioteke-rotaryencoder-0

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

Здравствуйте дорогие форумчане!

Нашел библиотеку RotaryEncoder для работы с энкодером, библиотека понравилась работой "без тормозов".

И еще, аналоговые выхода заняты вместо цифровых.

Вот ссылка на библиотеку  https://yadi.sk/d/vtDkM8DJn6YkR

Пример с библиотеки ниже:

// -----
// InterruptRotator.ino - Пример для библиотеки RotaryEncoder.
// Этот класс реализован для использования с самой среде программирования.
// Copyright (C) Маттиас Хертелем http://www.mathertel.de
// Эта работа лицензируется в соответствии с лицензией BSD в стиле. См http://www.mathertel.de/License.aspx
// Дополнительная информация о: http://www.mathertel.de/Arduino
// -----
// 18.01.2014 созданный Маттиасом Хертел
// -----

// Этот пример проверяет состояние датчика вращения в функции частоты ().
// Текущая позиция печатается на выходе при изменении.

// Установка оборудования:
// Присоединить энкодер с выходными контактами на A2 и A3.
// Общая контакт должен быть подключен к земле.

#include <RotaryEncoder.h>

// Настроить RoraryEncoder для штырей A2 и A3:
RotaryEncoder кодер (А2, А3);

недействительными установки ()
{
  Serial.begin (57600);
  Serial.println ("пример SimplePollRotator для библиотеки RotaryEncoder.");

  // Вы, возможно, придется изменить следующие 2 строки при использовании других выводов, чем А2 и А3
  PCICR | = (1 << PCIE1); // Это позволяет Pin прерывания по изменению 1, который охватывает контакты аналоговый вход или порт C.
  PCMSK1 | = (1 << PCINT10) | (1 << PCINT11); // Это позволяет прерывание для штифта 2 и 3 порта С
} // настроить()



// Обработчик прерываний служба по Изменить PIN прерывания 1
// Эта процедура будет вызываться только о любом изменении сигнала на A2 и A3: именно там, где нам нужно проверить.
ISR (PCINT1_vect) {
  encoder.tick (); // Просто позвонить галочку (), чтобы проверить состояние.
}


// Прочитать текущую позицию кодера и распечатать при изменении.
недействительными цикл ()
{
  статическая INT пос = 0;

  INT newPos = encoder.getPosition ();
  если (поз! = newPos) {
    Serial.print (newPos);
    Serial.println ();
    пос = newPos;

    // Просто чтобы показать, что длительные процедуры долго не сломать энкодер:
    // Когда newPos 66 выводе будет заморозить, но наработанные позиции будут признаны даже когда не опрошено.
    // Прерывание по-прежнему работает.
    // Выход правильно 6.6 секунд.
    если (== newPos 66)
      задержка (6600);
  } // если
} // Цикл ()

// Конец

проблема в том что я не могу обнулить переменную храняшую в себе позицию энкодера

пытался переписать библиотеку у меня не вышло

 

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

0259 пишет:

проблема в том что я не могу обнулить переменную храняшую в себе позицию энкодера

А что setPosition(0) не работает?

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

[/quote]

А что setPosition(0) не работает?

[/quote]

нет не помогает 

вот ответ от компилятора

enkoder_master_button_generation2.ino: In function 'void BUTTON_00_bounce_down()':
enkoder_master_button_generation2.ino:162:53: error: 'setPosition' was not declared in this scope

 

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

0259 пишет:
вот ответ от компилятора

Ответ - это прекрасно, только хотелось бы и вопрос (код) видеть. Судя по "ответу" - у Вас просто в коде ошибка.

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

ЕвгенийП пишет:

Ответ - это прекрасно, только хотелось бы и вопрос (код) видеть. Судя по "ответу" - у Вас просто в коде ошибка.

немного стесьняусь но всеже с удовольствием он только пронктируется это будит (звуковой генератор)



#include <RotaryEncoder.h>//инклюдим библиотеку
RotaryEncoder encoder(A2, A0);//переменная устанавливает ножки енкодера

//+++++++++++++++++++++++++++++++++++++
byte pb_00 = A1;
//-----------------------------------------------------------------------------
  int val = 0;  // значение частоты
  int val1 = 0;  // пуск - стоп
  int pwr = 0;
  int tim = 0;
  //////////////
  int klik = 0;
  int klik2 = 0;
  
  //////////////
  int gen = 10;

  
//-----------------------------------------------------------------------------

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);  // Set the LCD I2C address

void setup()
{
  Serial.begin(9600);
  PCICR |= (1 << PCIE1);    
  PCMSK1 |= (1 << PCINT10) | (1 << PCINT8);  
 
  ///++++++++++++++++++++++++++++++++++++++
  pinMode(pb_00, INPUT); // конфигурируется пин для кнопки BUTTON_00.
  digitalWrite(pb_00, HIGH);
  //+++++++++++++++++++++++++++++++++++++++
  lcd.begin(16,2);
  
  //+++++++++++++++++++++++++++++++++++++++
  } 

ISR(PCINT1_vect) {encoder.tick(); }

void GEN(){Serial.println("Tone:");Serial.print(val);tone (gen,val,tim);}

void loop()
{
  BUTTON_00();
  //==============
    static int pos = 0;
    int newPos = encoder.getPosition();
    if (pos != newPos) {
    Serial.print(newPos);
    Serial.println();
    pos = newPos;}
  //==============
   if(klik2==0){
   if(klik==0){val = newPos;}
   if(klik==1){val = newPos; val*10;Serial.println(+10);}
   if(klik==2){val = newPos; val*100;Serial.println(+100);}}
   if(klik2==1){
   if(klik2==0){tim = newPos;}
   if(klik2==1){tim = newPos; tim*10;Serial.println(+10);}
   if(klik2==2){tim = newPos; tim*100;Serial.println(+100);}}
   if(klik2==1){
   if(klik==0){tim = newPos;}
   if(klik==1){tim = newPos; tim*10;Serial.println(+10);}
   if(klik==2){tim = newPos; tim*100;Serial.println(+100);}}
   if(klik2==2){
   if(klik==0){pwr = newPos;}
   if(klik==1){pwr = newPos; Serial.println(+10);}
   if(klik==2){pwr = newPos; Serial.println(+100);}}
   if(klik>=3){klik=0;}
   if(klik2>=3){klik2=0;}
   
//+=+=+=+==========================================================
 
 BUTTON1();
//+=+=+=+==========================================================
}

void BUTTON1(){// кнопки генератора
 lcd.home();
 //lcd.clear();
 lcd.print(val);
 lcd.setCursor(5, 0);
 lcd.print(":Hz");
 lcd.setCursor(8, 0);
 lcd.print(char(255));
 lcd.setCursor(8, 1);
 lcd.print(char(255));
 lcd.setCursor(9, 0);
 lcd.print(tim);
 lcd.setCursor(13, 0);
 lcd.print(":Ms");
 lcd.setCursor(0, 1);
 lcd.print("Pwr:");
 lcd.setCursor(4, 1);
 lcd.print(pwr);
 lcd.setCursor(7, 1);
 lcd.print("%");
 if(val1==0){noTone(gen); lcd.setCursor(10, 1); lcd.print("STOP");}else{GEN(); lcd.setCursor(10, 1); lcd.print("START");}
 
 Serial.println(klik);
 Serial.println(klik2);

 
 }

void BUTTON_00() {///обработчик кнопок
//=======================================================
static unsigned long  m =           millis();
       unsigned long nm =           millis();
static boolean        p = digitalRead(pb_00);
       boolean       np = digitalRead(pb_00);
//=================
if (np != p) {p = np; m = nm;}
//=======================================================
static byte         bounce      =   20; // длительность дребезга.
static boolean      b           =    0;
       boolean     nb;
//=================
static unsigned int doubleclick =  200; // длительность двойного клика.
static boolean      dc          =    0;
       boolean     ndc;
static byte          c          =    0;
//=================
if (nm - m > bounce) {nb = 1;} else {nb = 0;}

if (nm - m > doubleclick) {ndc = 1;} else {ndc = 0;}
if (ndc != dc) {dc = ndc; if (dc == 1) {c = 0;}}

if (nb != b) {b = nb;
if (p == 0 && b == 0) {BUTTON_00_bounce_down();// нажатие кнопки.
++c;      if (c == 2) {BUTTON_00_doubleclick_down();} // двойной клик.
}
if (p == 1 && b == 1) {BUTTON_00_bounce_up();} // отпускание кнопки.
}
//=======================================================
static unsigned long timer = 10000; // длительность таймера, запускаемого одиночным кликом.
static boolean       t     =     0;
       boolean      nt;
//=================
if (nm - m > timer) {nt = 1;} else {nt = 0;}
if (nt != t) {t = nt;
if (p == 1 && t == 1) {BUTTON_00_timer_up();} // срабатывание таймера, запускаемого одиночным кликом.
}
//=======================================================
static unsigned int retention = 2000; // длительность удержания кнопки до срабатывания таймера.
static boolean      r         =    0;
       boolean     nr;
//=================
if (nm - m > retention) {nr = 1;} else {nr = 0;}
if (nr != r) {r = nr;
if (p == 0 && r == 1) {BUTTON_00_retention_down();} // срабатывание таймера, запускаемого удержанием кнопки.
}
//=======================================================
}

void BUTTON_00_bounce_down() {klik++;setPosition(0);} // подпрограмма, содержащая всё, что должно происходить при нажатии кнопки.
void BUTTON_00_bounce_up() {lcd.clear();Serial.println("9");} // подпрограмма, содержащая всё, что должно происходить при отпускании кнопки.
void BUTTON_00_doubleclick_down() {klik =0; klik2++;} // подпрограмма, содержащая всё, что должно происходить при двойном клике.
void BUTTON_00_timer_up() {Serial.println("3");} // подпрограмма, содержащая всё, что должно происходить при срабатывании таймера, запущенного одиночным кликом кнопки.
void BUTTON_00_retention_down() {static int fi = 0;  fi++; if(fi==1){val1=1;}else{val1=0;fi = 0;} klik =0;} // подпрограмма, содержащая всё, что должно происходить при после срабатывания таймера, запущенного нажатием и удержанием кнопки.

 

 

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

Дык правильно ругается.  setPosition - метод класса RotaryEncoder, а Вы его зачем-то как самостоятельную функцию используете. У Вас же есть переменная encoder.  Вот и пишите encoder.setPosition(0)

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

спасибо вам огромное урок понят получается если переменная обявлена в библиотеке то просто из кода она не поменяется а менять надо с упоминанием того что она с библиотеки!

СПАСИБО!!!!! +++++

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

подскажите еще немного по моему коду как переменую val разлажить на еденицы,десятки,сотни,тысячи

для отображения на экране но сома переменая должна быть не тронута для функции Tone(val)

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

0259 пишет:

подскажите еще немного по моему коду как переменую val разлажить на еденицы,десятки,сотни,тысячи

для отображения на экране но сома переменая должна быть не тронута для функции Tone(val)

Берёте переменную и вытаскиваете из неё:

единицы - это остаток от деления оригинальной  переменной на 10

десятки - это остаток от деления на 10 оригинальной переменной, предварительно поделённой на 10

сотни - это остаток от деления на 10 оригинальной переменной, предварительно поделённой на 100

тысямч - это остаток от деления на 10 оригинальной переменной, предварительно поделённой на 100

и т.д.

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

Решил вернуться к эксперементам над энкодером

подключено так

 

 

при компиляции ругается на строку RotaryEncoder encoder(A4, A5);

C:\Users\m\Documents\Only_Me\arduino-0022\hardware\arduino\cores\arduino/Arduino.h:206:1: warning: this is the location of the previous definition
sketch_feb17a:11: error: 'A4' was not declared in this scope
sketch_feb17a:11: error: 'A5' was not declared in this scope

знаний хватает на то, что понимаю видимо как в примере так нельзя указывать чтение из аналоговых пинов, возможно потому что плата duemilanova

нужна подсказка как разрешить проблему...

З.Ы. примеры и библиотека - тут

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

а в коде поменяли 

//Pinos de ligacao do encoder
RotaryEncoder encoder(A2, A3);

на свой

//Pinos de ligacao do encoder
RotaryEncoder encoder(A4, A5);

 

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

0259 пишет:

а в коде поменяли 

//Pinos de ligacao do encoder
RotaryEncoder encoder(A2, A3);

на свой

//Pinos de ligacao do encoder
RotaryEncoder encoder(A4, A5);

 

ну конечно поменял...

такое чувство, что бибилиотеке "не нравится" мой ардуино

ну или что-то не так с библиотекой...посмотрел код инициализации вроде бы все логично и понятно

// ----- Initialization and Default Values -----

RotaryEncoder::RotaryEncoder(int pin1, int pin2) {
  
  // Remember Hardware Setup
  _pin1 = pin1;
  _pin2 = pin2;
  
  // Setup the input pins
  pinMode(pin1, INPUT);
  digitalWrite(pin1, HIGH);   // turn on pullup resistor

  pinMode(pin2, INPUT);
  digitalWrite(pin2, HIGH);   // turn on pullup resistor

  // when not started in motion, the current state of the encoder should be 3
  _oldState = 3;

  // start with position 0;
  _position = 0;
  _positionExt = 0;
} // RotaryEncoder()

 

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

отпишусь по результату...видимо конфликт библиотек был...установил новую среду 1.6.7 и все заработало как надо

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

уважаемый коллективный разум может быть подскажете по коду

//Programa : Teste basico encoder Arduino
//Autor : Arduino e Cia

//Carrega a biblioteca do encoder
#include <RotaryEncoder.h>

//Pinos de ligacao do encoder
RotaryEncoder encoder(A4, A5);

//Variavel para o botao do encoder
int valor = 0;
int newPos = 0;

void setup()
{
  pinMode(2, INPUT);
  Serial.begin(9600);
  Serial.println("Gire o encoder....");
}

void loop()
{
  //Verifica se o botao do encoder foi pressionado
  valor = digitalRead(2);
  if (valor != 1)
  {
    Serial.println("Botao pressionado");
    while (digitalRead(2) == 0)
      delay(10);
  }

  //Le as informacoes do encoder
  static int pos = 0;
  encoder.tick();
  int newPos = encoder.getPosition();
  //Se a posicao foi alterada, mostra o valor
  //no Serial Monitor
  if (pos != newPos) {
    Serial.print(newPos);
    Serial.println();
    pos = newPos;
  }
}

все работает, но принцип не такой как мне нужно, мне требуется, чтобы значения не уходили в отрицательные значения, то не ниже 0