w3456

   Здесь я хочу вам рассказать как управлять громкостью и музыкой при помощи Поворотного энкодера (иначе - датчик угла поворота), это устройство, преобразующее угол поворота вращающегося объекта (вала) в электрические сигналы, позволяющие определить этот угол. Будет работать и на Windows и на Android
 
 

w3456

 Здесь я хочу вам рассказать как управлять громкостью и музыкой при помощи Поворотного энкодера (иначе - датчик угла поворота), это устройство, преобразующее угол поворота вращающегося объекта (вала) в электрические сигналы, позволяющие определить этот угол. Сейчас вам я не буду объяснять принцип действия энкодера, благо в интернете огромное количество информации и если интересен прнцип действия можете прочтать. Перейдём напрямую к поставленной задаче. А именно управлять мультимедиа функциями компьютера или планшета. 

Как и в прошлом уроке про рулевое управлерие планшетом, для начала нам необходимо приобрести плату Arduino Leonadro или ArduinoMicro, главное отличие этих контроллеров в том что на них установлены микропроцессоры Atmega32u4 которая имеет на борту встроенную поддержку USB-соединения, благодаря чему не требуется вспомогательный процессор. Это позволяет устройствам на Atmega32u4 появляться на подключенном планшете (с поддержкой OTG) или компьютере в качестве мыши или клавиатуры в дополнение к виртуальному (CDC) последовательному порту (COM). В общем подойдет любой arduino совместимый контроллер который построен на Atmega32u4. + нам ещё потребуется сам повортный энкодер его можете приобрести на алиэкспресс.

Вторым шагом после того как приобрели необходимый вам контроллер необходимо скачать ArduinoIDE и установить для того чтобы установились драйвера, затем чтобы работали все функции скачайте подготовленную мной портативную версию ArduinoIDE вот ЗДЕСЬ, в этот архив уже добавлены все необходимые библиотеки и изменены файлы для работы в качестве медиа клавиатуры.

Подключение максимально простое, потребуется всего 5 проводков, и необходимо их соеденить следующим образом.

Видео версия, медиа энкодер на Arduino Micro

энкодер GND - GND arduino Micro
энкодер 5v - 5v arduino Micro
энкодер SW - D8 arduino Micro
энкодер DT - D10 arduino Micro
энкодер SLK - D9 arduino Micro
Выводы SW, DT, SLK можете поменять на свои какие угодно в скетче. 
5678

 Далее расписаны команды для управления мультимедиа функциями.

Remote.next();             //следующая песня
Remote.previous();       //предыдущая песня
Remote.play_pause();   //плей и паузу
Remote.increase();       //громкость прибавить
Remote.decrease();      //громкость убавить
Remote.mute();            //Убрать звук
Remote.play();             // Воспроизвести
Remote.stop();             //Остановить воспроизведение
Remote.forward();        //Ускорить воспроизведение
Remote.rewind();         //Обратное воспроизведение
и конечно же скетч для arduino
//GENMC.ru управление мультимедиа при помощи энкодера
#include <SPI.h&gt//
#include <EEPROM2.h&gt
#include <EEPROM.h&gt

#define BTN_pin  8             // pin 8 кнопка энкодера SW
const int pin_A = 10;          // pin 10 нога энкодера CLK
const int pin_B = 9;           // pin 9 нога энкодера DT
unsigned char encoder_A;        //переменная
unsigned char encoder_B;        //переменная
unsigned char encoder_A_prev=0; //переменная

void setup()  {
  digitalWrite(BTN_pin, 1);     //подтяжка кнопки энкодера
  pinMode(pin_A, INPUT);        //пины энкодера объявляем входами
  pinMode(pin_B, INPUT);        //пины энкодера объявляем входами
              } 
 void loop()  
{
   
  { encoder_A = digitalRead(pin_A);          // считываем состояние выхода А энкодера 
    encoder_B = digitalRead(pin_B);          // считываем состояние выхода B энкодера    
    if((!encoder_A) && (encoder_A_prev)){    // если состояние изменилось с положительного к нулю
      if(encoder_B) 
           {
            Remote.increase(); //отправляем команду громкость выше
            Remote.clear();    //очищаем команду
            }
              else  {
                     Remote.decrease(); //отправляем команду громкость ниже
                     Remote.clear();    //очищаем команду              
                     }   
                                      } 
       encoder_A_prev = encoder_A;     // сохраняем значение А для следующего цикла 
   } 
    if(digitalRead(BTN_pin)==LOW) //Если кнопка нажата то делаем то что ниже.
   {
    Remote.play_pause(); //отправляем команду плей пауза
    Remote.clear();      //очищаем команд   
    delay(500);          //Делаем небольшую задержку чтоб не засыпало командами.
   }
}

Далее рассмотрим как отправить комбинации нажатых клавиш на примере ALT+TAB для быстрого переключеня между активными приложениями (работает как на Windows так и на android) в таблице прведены команды которая понимает arduino. 

keymodifier
KEY_A KEY_B KEY_C KEY_D KEY_CTRL
KEY_E KEY_F KEY_G KEY_H KEY_SHIFT
KEY_I KEY_J KEY_K KEY_L KEY_ALT
KEY_M KEY_N KEY_O KEY_P KEY_GUI
KEY_Q KEY_R KEY_S KEY_T KEY_LEFT_CTRL
KEY_U KEY_V KEY_W KEY_X KEY_LEFT_SHIFT
KEY_Y KEY_Z KEY_1 KEY_2 KEY_LEFT_ALT
KEY_3 KEY_4 KEY_5 KEY_6 KEY_LEFT_GUI
KEY_7 KEY_8 KEY_9 KEY_0 KEY_RIGHT_CTRL
KEY_ENTER KEY_ESC KEY_BACKSPACE KEY_TAB KEY_RIGHT_SHIFT
KEY_SPACE KEY_MINUS KEY_EQUAL KEY_LEFT_BRACE KEY_RIGHT_ALT
KEY_RIGHT_BRACE KEY_BACKSLASH KEY_NUMBER KEY_SEMICOLON KEY_RIGHT_GUI
KEY_QUOTE KEY_TILDE KEY_COMMA KEY_PERIOD  
KEY_SLASH KEY_CAPS_LOCK KEY_F1 KEY_F2  
KEY_F3 KEY_F4 KEY_F5 KEY_F6  
KEY_F7 KEY_F8 KEY_F9 KEY_F10  
KEY_F11 KEY_F12 KEY_PRINTSCREEN KEY_SCROLL_LOCK  
KEY_PAUSE KEY_INSERT KEY_HOME KEY_PAGE_UP  
KEY_DELETE KEY_END KEY_PAGE_DOWN KEY_RIGHT  
KEY_LEFT KEY_DOWN KEY_UP KEY_NUM_LOCK  
KEYPAD_SLASH KEYPAD_ASTERIX KEYPAD_MINUS KEYPAD_PLUS  
KEYPAD_ENTER KEYPAD_1 KEYPAD_2 KEYPAD_3  
KEYPAD_4 KEYPAD_5 KEYPAD_6 KEYPAD_7  
KEYPAD_8 KEYPAD_9 KEYPAD_0 KEYPAD_PERIOD  

Скетч который ниже выполняет следующее: При вовороте энкодера на право прибавляет громкость при повороте на лево уменьшает, нажатие на кнопку энкодера включает режим переключения между приложениями (ALT+TAB) если в течении 1 секунды нажимать кнопку произойдёт переключение между программами, при истечении 1 секунды автоматический выберется выбранная программа.

////GENMC.ru управление мультимедиа при помощи энкодера
#define BTN_pin  8             // pin 8 кнопка энкодера SW
const int pin_A = 10;          // pin 10 нога энкодера CLK
const int pin_B = 9;           // pin 9 нога энкодера DT
unsigned char encoder_A;        //переменная
unsigned char encoder_B;        //переменная
unsigned char encoder_A_prev=0; //переменная
uint32_t vibor = 0;             //Здесь будем хранть время
int perek = 0;                  //переменная переключатель
 
void setup()  {
  digitalWrite(BTN_pin, 1);     //подтяжка кнопки энкодера
  pinMode(pin_A, INPUT);        //пины энкодера объявляем входами
  pinMode(pin_B, INPUT);        //пины энкодера объявляем входами
  Keyboard.begin();             //подключим как клава  
               } 
 void loop()  
{
    
  { encoder_A = digitalRead(pin_A);          // считываем состояние выхода А энкодера 
    encoder_B = digitalRead(pin_B);          // считываем состояние выхода B энкодера    
    if((!encoder_A) && (encoder_A_prev)){    // если состояние изменилось с положительного к нулю
      if(encoder_B) 
           {
            Remote.increase(); //отправляем команду громкость выше
            Remote.clear();    //очищаем команду
            }
              else  {
                     Remote.decrease(); //отправляем команду громкость ниже
                     Remote.clear();    //очищаем команду              
                     }   
                                      } 
       encoder_A_prev = encoder_A;     // сохраняем значение А для следующего цикла 
   } 
    if(digitalRead(BTN_pin)==LOW)      //Если кнопка нажата то делаем то что ниже.
         {
          Keyboard.press(KEY_LEFT_ALT);   //нажмем кнопку ALT
          Keyboard.press(KEY_TAB);        //нажмем кнопку TAB      
          Keyboard.release(KEY_TAB);      //отпустим кнопку TAB    
          delay(150);                     //ждем 150мс чтоб не скакало по окошкам
          vibor = millis();               //запускаем отсчет времени
          perek=1;                        //переменной переключателя присваиваем 1
     }
     if((vibor && millis()-vibor > 1000) && perek==1) //если прошло больше 1 секунды и перемменая переключателя = 1
       {
       Keyboard.releaseAll(); //отпускаем все кнопки
       perek = 0;             //переменной переключателя присваиваем 0 чтоб сюда больше не заходил
        }
   }

2 энкодера Android и Arduino Micro

//GENMC.ru управление мультимедиа при помощи энкодера
#define BTN_pin  8             // pin 8 кнопка энкодера SW
const int pin_A = 10;          // pin 10 нога энкодера CLK
const int pin_B = 9;           // pin 9 нога энкодера DT
unsigned char encoder_A;        //переменная
unsigned char encoder_B;        //переменная
unsigned char encoder_A_prev=0; //переменная
#define BTN_pin1  5             // pin 5 кнопка энкодера SW1
const int pin_A1 = 7;           // pin 7 нога энкодера CLK1
const int pin_B1 = 6;           // pin 6 нога энкодера DT1
unsigned char encoder_A1;        //переменная1
unsigned char encoder_B1;        //переменная1
unsigned char encoder_A_prev1=0; //переменная1

uint32_t vibor = 0;             //Здесь будем хранть время
int perek = 0;                  //переменная переключатель
 
void setup()  {
  digitalWrite(BTN_pin, 1);     //подтяжка кнопки энкодера
  pinMode(pin_A, INPUT);        //пины энкодера объявляем входами
  pinMode(pin_B, INPUT);        //пины энкодера объявляем входами
  digitalWrite(BTN_pin1, 1);     //подтяжка кнопки энкодера1
  pinMode(pin_A1, INPUT);        //пины энкодера объявляем входами1
  pinMode(pin_B1, INPUT);        //пины энкодера объявляем входами1
  Keyboard.begin();             //подключим как клава  
               } 
 void loop()  
{
    //////////////ЭНКОДЕР 1///////////
  { encoder_A = digitalRead(pin_A);          // считываем состояние выхода А энкодера 
    encoder_B = digitalRead(pin_B);          // считываем состояние выхода B энкодера    
    if((!encoder_A) && (encoder_A_prev)){    // если состояние изменилось с положительного к нулю
      if(encoder_B) 
           {
            Remote.increase(); //отправляем команду громкость выше
            Remote.clear();    //очищаем команду
            }
              else  {
                     Remote.decrease(); //отправляем команду громкость ниже
                     Remote.clear();    //очищаем команду              
                     }   
                                      } 
       encoder_A_prev = encoder_A;     // сохраняем значение А для следующего цикла 
   } 
       
   if(digitalRead(BTN_pin)==LOW) //Если кнопка нажата то делаем то что ниже.
   {
    Remote.mute();   //отправляем команду убрать звук
    Remote.clear();      //очищаем команд   
    delay(500);          //Делаем небольшую задержку чтоб не засыпало командами.
   }
   
   //////////ЭНКОДЕР 2//////////////
   
 { encoder_A1 = digitalRead(pin_A1);          // считываем состояние выхода А энкодера 
    encoder_B1 = digitalRead(pin_B1);          // считываем состояние выхода B энкодера    
    if((!encoder_A1) && (encoder_A_prev1)){    // если состояние изменилось с положительного к нулю
      if(encoder_B1) 
           {
           Remote.next(); //отправляем команду слудующая песня
            Remote.clear();    //очищаем команду
            }
              else  {
                     Remote.previous(); //отправляем команду предыдущая песня
                     Remote.clear();    //очищаем команду              
                     }   
                                      } 
       encoder_A_prev1 = encoder_A1;     // сохраняем значение А для следующего цикла 
   } 
    if(digitalRead(BTN_pin1)==LOW)      //Если кнопка нажата то делаем то что ниже.
         {
          Keyboard.press(KEY_LEFT_ALT);   //нажмем кнопку ALT
          Keyboard.press(KEY_TAB);        //нажмем кнопку TAB      
          Keyboard.release(KEY_TAB);      //отпустим кнопку TAB    
          delay(150);                     //ждем 150мс чтоб не скакало по окошкам
          vibor = millis();               //запускаем отсчет времени
          perek=1;                        //переменной переключателя присваиваем 1
     }
     if((vibor && millis()-vibor > 1000) && perek==1) //если прошло больше 1 секунды и перемменая переключателя = 1
       {
       Keyboard.releaseAll(); //отпускаем все кнопки
       perek = 0;             //переменной переключателя присваиваем 0 чтоб сюда больше не заходил
        }
  
 }