USB HID мультимедиа клавиатура под андроид

ali_vlad
Offline
Зарегистрирован: 20.02.2015

Есть Ардуино про микро (Mega32U4).

Хочу сделать на её основе USB HID клавиатуру под андроид для регулировки громкости по средствам энкодера и запуск нескольких программ типа Navitel, MX Player, какой нибудь музыкальный плеер и кнопки следующая, предыдущая, пауза, воспроизведение.

Может есть у кого готовое решение (или его части). Буду очень признателен, а то я в этом практически не разбираюсь.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Ищите в инете ардуиноподобную плату с названием "Digispark" . Это типа ардуино на Attiny85. Там есть примеры клавиатуры и мыши. 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

brokly,  хмм .. а зачем Т.С. искать диджиспарк, если в ардуине для микры есть готовая встроенная библа? http://www.arduino.cc/en/Reference/MouseKeyboard

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Ну пусть тогда  не ищет :)

saftik
Offline
Зарегистрирован: 08.04.2015

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

правда делал не с знкодером , а просто на кнопках. 

частично помогла инфа с этого сайта 
http://ivan.bmstu.ru/avia_site/r_main/HWR/ADDS/JCUSB/jcusb.htm

а вот и сайт с бесценным кодом который был взят за основу
http://arduino-ua.com/art3-Podkluchenie_matrichnoi_klaviatyri_k_Arduin

ali_vlad
Offline
Зарегистрирован: 20.02.2015

А как пропихнуть команду, например, квеличить громкость. Где вообще можно почитать про команды клавиатуры?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ali_vlad, вы удивитесь, но всё на том-же сайте ардуино http://www.arduino.cc/en/Reference/KeyboardModifiers

ali_vlad
Offline
Зарегистрирован: 20.02.2015

dimax пишет:

ali_vlad, вы удивитесь, но всё на том-же сайте ардуино http://www.arduino.cc/en/Reference/KeyboardModifiers

Смотрел, то, что мне нужно не нашел.

Мне надо следующее:

- громкость+

- громкость-

- mute

- play

- pause

- следующая композиция

- предыдущая композиция

- стоп

А еще очень интересувет как запустить андроид-приложение, например Navitel.

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013
ali_vlad
Offline
Зарегистрирован: 20.02.2015

,

ali_vlad
Offline
Зарегистрирован: 20.02.2015

После изменения файлов при любой компиляции вылазиют ошибки

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ali_vlad, я брал упомянутые в статье файлы из их архива

ali_vlad
Offline
Зарегистрирован: 20.02.2015
void setup() {
  pinMode(7, INPUT_PULLUP);
  Keyboard.begin();
}
 
void loop() {
 if(digitalRead(7)==LOW){
  Keyboard.press(xxx);//какой здесь должен быть код для уменьшения громкости
  delay(500);
  Keyboard.releaseAll();
  }
}
 
dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Там-же в статье где-то всё перечислено. Мой рабочий скетч для регулировки громкости энкодером. Кнопка на энкодере -"MUTE".

//Скетч регулятора громкости на энкодере для Arduino MICRO
// энкодер на 10 и 11 пинах  выводы подтянуты к питанию, 
// конденсаторы на землю желательно.
//кнопка энкодера на 7 ноге, притянута к + программно. конденсатор желательно.
void setup() {             
PCICR=1<<PCIE0;
PCMSK0=(1<<PCINT7)|(1<<PCINT6);
pinMode (7,INPUT_PULLUP);
pinMode (10,INPUT);
pinMode (11,INPUT);
attachInterrupt(4, key_mute, FALLING);
Remote.begin();
}
void loop() { }

ISR (PCINT0_vect){
static byte old_n=PINB&B11000000; 
byte new_n=PINB&B11000000;
if (old_n==128&&new_n==192||old_n==64&&new_n==0) {Remote.increase();}
if (old_n==64&&new_n==192||old_n==128&&new_n==0) {Remote.decrease();}
old_n= new_n;
}

void key_mute() {Remote.mute();}


 

ali_vlad
Offline
Зарегистрирован: 20.02.2015

Я же писал в самом начале, что я в этом 0. Это слишком сложно для меня. Неуже ли нер решения по-проще?. Да и ругается на отсутствие чего-то при компиляции...

На сколько я понял есть Keyboard.press(). Он может эмулировать нажатие клавиш. Только информации по нему, кроме примеров, взятых с сайта нет.

Keyboard.press(ГРОМКОСТЬ_УВЕЛИЧИТЬ);

Как это должно правильно выглядеть?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ali_vlad, проще уже некуда. Я не пойму, что тут может быть непонятным. По ссылке на канадский сайт есть полная исчерпывающая информация. К тому же я дал вам свой рабочий скетч, неужели вам не видно какой командой в нём увеличивается громкость?

ali_vlad
Offline
Зарегистрирован: 20.02.2015
In file included from C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:224:0,
                 from sketch_apr21a.ino:5:
C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/USBAPI.h:31:2: error: 'ring_buffer' does not name a type
  ring_buffer *_cdc_rx_buffer;
  ^
sketch_apr21a.ino: In function 'void setup()':
sketch_apr21a.ino:30:6: error: redefinition of 'void setup()'
sketch_apr21a.ino:5:6: error: 'void setup()' previously defined here
sketch_apr21a.ino: In function 'void loop()':
sketch_apr21a.ino:39:6: error: redefinition of 'void loop()'
sketch_apr21a.ino:14:6: error: 'void loop()' previously defined here
In file included from C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:30:0,
                 from sketch_apr21a.ino:5:
sketch_apr21a.ino: In function 'void __vector_9()':
sketch_apr21a.ino:41:6: error: redefinition of 'void __vector_9()'
sketch_apr21a.ino:16:6: error: 'void __vector_9()' previously defined here
sketch_apr21a.ino: In function 'void key_mute()':
sketch_apr21a.ino:49:6: error: redefinition of 'void key_mute()'
sketch_apr21a.ino:24:6: error: 'void key_mute()' previously defined here
Ошибка компиляции.
 
 
ali_vlad
Offline
Зарегистрирован: 20.02.2015


#ifndef __USBAPI__
#define __USBAPI__

#if defined(USBCON)

//================================================================================
//================================================================================
//	USB

class USBDevice_
{
public:
	USBDevice_();
	bool configured();

	void attach();
	void detach();	// Serial port goes down too...
	void poll();
};
extern USBDevice_ USBDevice;

//================================================================================
//================================================================================
//	Serial over CDC (Serial1 is the physical port)

class Serial_ : public Stream
{
private:
	ring_buffer *_cdc_rx_buffer;
public:
	void begin(uint16_t baud_count);
	void end(void);

	virtual int available(void);
	virtual void accept(void);
	virtual int peek(void);
	virtual int read(void);
	virtual void flush(void);
	virtual size_t write(uint8_t);
	using Print::write; // pull in write(str) and write(buf, size) from Print
	operator bool();
};
extern Serial_ Serial;

//================================================================================
//================================================================================
//	Mouse

#define MOUSE_LEFT 1
#define MOUSE_RIGHT 2
#define MOUSE_MIDDLE 4
#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)

class Mouse_
{
private:
	uint8_t _buttons;
	void buttons(uint8_t b);
public:
	Mouse_(void);
	void begin(void);
	void end(void);
	void click(uint8_t b = MOUSE_LEFT);
	void move(signed char x, signed char y, signed char wheel = 0);	
	void press(uint8_t b = MOUSE_LEFT);		// press LEFT by default
	void release(uint8_t b = MOUSE_LEFT);	// release LEFT by default
	bool isPressed(uint8_t b = MOUSE_LEFT);	// check LEFT by default
};
extern Mouse_ Mouse;

//================================================================================
//================================================================================
//	Keyboard

#define KEY_LEFT_CTRL		0x80
#define KEY_LEFT_SHIFT		0x81
#define KEY_LEFT_ALT		0x82
#define KEY_LEFT_GUI		0x83
#define KEY_RIGHT_CTRL		0x84
#define KEY_RIGHT_SHIFT		0x85
#define KEY_RIGHT_ALT		0x86
#define KEY_RIGHT_GUI		0x87

#define KEY_UP_ARROW		0xDA
#define KEY_DOWN_ARROW		0xD9
#define KEY_LEFT_ARROW		0xD8
#define KEY_RIGHT_ARROW		0xD7
#define KEY_BACKSPACE		0xB2
#define KEY_TAB				0xB3
#define KEY_RETURN			0xB0
#define KEY_ESC				0xB1
#define KEY_INSERT			0xD1
#define KEY_DELETE			0xD4
#define KEY_PAGE_UP			0xD3
#define KEY_PAGE_DOWN		0xD6
#define KEY_HOME			0xD2
#define KEY_END				0xD5
#define KEY_CAPS_LOCK		0xC1
#define KEY_F1				0xC2
#define KEY_F2				0xC3
#define KEY_F3				0xC4
#define KEY_F4				0xC5
#define KEY_F5				0xC6
#define KEY_F6				0xC7
#define KEY_F7				0xC8
#define KEY_F8				0xC9
#define KEY_F9				0xCA
#define KEY_F10				0xCB
#define KEY_F11				0xCC
#define KEY_F12				0xCD

//	Low level key report: up to 6 keys and shift, ctrl etc at once
typedef struct
{
	uint8_t modifiers;
	uint8_t reserved;
	uint8_t keys[6];
} KeyReport;

class Keyboard_ : public Print
{
private:
	KeyReport _keyReport;
	void sendReport(KeyReport* keys);
public:
	Keyboard_(void);
	void begin(void);
	void end(void);
	virtual size_t write(uint8_t k);
	virtual size_t press(uint8_t k);
	virtual size_t release(uint8_t k);
	virtual void releaseAll(void);
};
extern Keyboard_ Keyboard;

//================================================================================
//================================================================================
//	Remote 
 
#define REMOTE_CLEAR 0
#define VOLUME_UP 1
#define VOLUME_DOWN 2
#define VOLUME_MUTE 4
#define REMOTE_PLAY 8
#define REMOTE_PAUSE 16
#define REMOTE_STOP 32
#define REMOTE_NEXT 64
#define REMOTE_PREVIOUS 128
#define REMOTE_FAST_FORWARD 256
#define REMOTE_REWIND 512
 
class Remote_
{
private:
public:
	Remote_(void);
	void begin(void);
	void end(void);
 
	// Volume
	void increase(void);
	void decrease(void);
	void mute(void);
 
	// Playback
	void play(void);
	void pause(void);
	void stop(void);
 
	// Track Controls
	void next(void);
	void previous(void);
	void forward(void);
	void rewind(void);
 
	// Send an empty report to prevent repeated actions
	void clear(void);
};
extern Remote_ Remote;
//================================================================================
//================================================================================
//	Low level API

typedef struct
{
	uint8_t bmRequestType;
	uint8_t bRequest;
	uint8_t wValueL;
	uint8_t wValueH;
	uint16_t wIndex;
	uint16_t wLength;
} Setup;

//================================================================================
//================================================================================
//	HID 'Driver'

int		HID_GetInterface(uint8_t* interfaceNum);
int		HID_GetDescriptor(int i);
bool	HID_Setup(Setup& setup);
void	HID_SendReport(uint8_t id, const void* data, int len);

//================================================================================
//================================================================================
//	MSC 'Driver'

int		MSC_GetInterface(uint8_t* interfaceNum);
int		MSC_GetDescriptor(int i);
bool	MSC_Setup(Setup& setup);
bool	MSC_Data(uint8_t rx,uint8_t tx);

//================================================================================
//================================================================================
//	CSC 'Driver'

int		CDC_GetInterface(uint8_t* interfaceNum);
int		CDC_GetDescriptor(int i);
bool	CDC_Setup(Setup& setup);

//================================================================================
//================================================================================

#define TRANSFER_PGM		0x80
#define TRANSFER_RELEASE	0x40
#define TRANSFER_ZERO		0x20

int USB_SendControl(uint8_t flags, const void* d, int len);
int USB_RecvControl(void* d, int len);

uint8_t	USB_Available(uint8_t ep);
int USB_Send(uint8_t ep, const void* data, int len);	// blocking
int USB_Recv(uint8_t ep, void* data, int len);		// non-blocking
int USB_Recv(uint8_t ep);							// non-blocking
void USB_Flush(uint8_t ep);

#endif

#endif /* if defined(USBCON) */

 

ali_vlad
Offline
Зарегистрирован: 20.02.2015
/*
  Arduino.h - Main include file for the Arduino SDK
  Copyright (c) 2005-2013 Arduino Team.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef Arduino_h
#define Arduino_h

#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>

#include <avr/pgmspace.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#include "binary.h"

#ifdef __cplusplus
extern "C"{
#endif

void yield(void);

#define HIGH 0x1
#define LOW  0x0

#define INPUT 0x0
#define OUTPUT 0x1
#define INPUT_PULLUP 0x2

#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define TWO_PI 6.283185307179586476925286766559
#define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105
#define EULER 2.718281828459045235360287471352

#define SERIAL  0x0
#define DISPLAY 0x1

#define LSBFIRST 0
#define MSBFIRST 1

#define CHANGE 1
#define FALLING 2
#define RISING 3

#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
#define DEFAULT 0
#define EXTERNAL 1
#define INTERNAL 2
#else  
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
#define INTERNAL1V1 2
#define INTERNAL2V56 3
#else
#define INTERNAL 3
#endif
#define DEFAULT 1
#define EXTERNAL 0
#endif

// undefine stdlib's abs if encountered
#ifdef abs
#undef abs
#endif

#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
#define round(x)     ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x))

#define interrupts() sei()
#define noInterrupts() cli()

#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )

#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))

#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))

// avr-libc defines _NOP() since 1.6.2
#ifndef _NOP
#define _NOP() do { __asm__ volatile ("nop"); } while (0)
#endif

typedef unsigned int word;

#define bit(b) (1UL << (b))

typedef bool boolean;
typedef uint8_t byte;

void init(void);
void initVariant(void);

int atexit(void (*func)()) __attribute__((weak));

void pinMode(uint8_t, uint8_t);
void digitalWrite(uint8_t, uint8_t);
int digitalRead(uint8_t);
int analogRead(uint8_t);
void analogReference(uint8_t mode);
void analogWrite(uint8_t, int);

unsigned long millis(void);
unsigned long micros(void);
void delay(unsigned long);
void delayMicroseconds(unsigned int us);
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);

void attachInterrupt(uint8_t, void (*)(void), int mode);
void detachInterrupt(uint8_t);

void setup(void);
void loop(void);

// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.

#define analogInPinToBit(P) (P)

// On the ATmega1280, the addresses of some of the port registers are
// greater than 255, so we can't store them in uint8_t's.
extern const uint16_t PROGMEM port_to_mode_PGM[];
extern const uint16_t PROGMEM port_to_input_PGM[];
extern const uint16_t PROGMEM port_to_output_PGM[];

extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];

// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.
// 
// These perform slightly better as macros compared to inline functions
//
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
#define analogInPinToBit(P) (P)
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )

#define NOT_A_PIN 0
#define NOT_A_PORT 0

#define NOT_AN_INTERRUPT -1

#ifdef ARDUINO_MAIN
#define PA 1
#define PB 2
#define PC 3
#define PD 4
#define PE 5
#define PF 6
#define PG 7
#define PH 8
#define PJ 10
#define PK 11
#define PL 12
#endif

#define NOT_ON_TIMER 0
#define TIMER0A 1
#define TIMER0B 2
#define TIMER1A 3
#define TIMER1B 4
#define TIMER1C 5
#define TIMER2  6
#define TIMER2A 7
#define TIMER2B 8

#define TIMER3A 9
#define TIMER3B 10
#define TIMER3C 11
#define TIMER4A 12
#define TIMER4B 13
#define TIMER4C 14
#define TIMER4D 15
#define TIMER5A 16
#define TIMER5B 17
#define TIMER5C 18

#ifdef __cplusplus
} // extern "C"
#endif

#ifdef __cplusplus
#include "WCharacter.h"
#include "WString.h"
#include "HardwareSerial.h"
#include "USBAPI.h"
#if defined(HAVE_HWSERIAL0) && defined(HAVE_CDCSERIAL)
#error "Targets with both UART0 and CDC serial not supported"
#endif

uint16_t makeWord(uint16_t w);
uint16_t makeWord(byte h, byte l);

#define word(...) makeWord(__VA_ARGS__)

unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);

void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
void noTone(uint8_t _pin);

// WMath prototypes
long random(long);
long random(long, long);
void randomSeed(unsigned int);
long map(long, long, long, long, long);

#endif

#include "pins_arduino.h"

#endif

 

ali_vlad
Offline
Зарегистрирован: 20.02.2015

Вот это всё для меня непонятно.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ali_vlad, если вы использовали именно те 2 файла из архива, и мой скетч, то наиболее вероятной причиной ошибок может быть конфликт версий arduino ide. У меня версия 1.05-r2 с ней проблем нет.

ps: кстати когда вставляете длинный код, то в меню "дополнительно"  выбирайте сворачивать код по-умолчанию.

ali_vlad
Offline
Зарегистрирован: 20.02.2015

У меня последняя версия 1.6.хх

ali_vlad
Offline
Зарегистрирован: 20.02.2015

Залил 1,05. Залил скетч. Громкость стермится к максимуму постоянно. Кнопка муте соответственно не работает.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ali_vlad, . Энкодер с подтяжкой к питанию? Конденсаторы ставили от выводов энкодера на общий?. Емкость.. где-то от 1...до 10 nF. Кнопка у меня работала и без конденсатора, но в принципе тоже нужен 10..100nF .

ali_vlad
Offline
Зарегистрирован: 20.02.2015


Как убрать эту ...
ali_vlad
Offline
Зарегистрирован: 20.02.2015

Я же писал, что я начинающий, всё это для меня пока сложно, а тут такое...

ali_vlad
Offline
Зарегистрирован: 20.02.2015

То ли контроллер глючный, то ли лыжи не едут. После заливки скетча через разные промежутки времени контроллер зависал и одновременно отваливалась родная клава с мышкой. Потом он вообще перестал прошиваться.

Скетч заливал такой

//PCICR=1<<PCIE0;
//PCMSK0=(1<<PCINT7)|(1<<PCINT6);
pinMode (7,INPUT_PULLUP);
//pinMode (10,INPUT);
//pinMode (11,INPUT);
attachInterrupt(4, key_mute, FALLING);
Remote.begin();
}
void loop() { }

//ISR (PCINT0_vect){
//static byte old_n=PINB&B11000000; 
//byte new_n=PINB&B11000000;
//if (old_n==128&&new_n==192||old_n==64&&new_n==0) {Remote.increase();}
//if (old_n==64&&new_n==192||old_n==128&&new_n==0) {Remote.decrease();}
//old_n= new_n;
}

void key_mute() {Remote.mute();}

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ali_vlad, да, похоже какие-то проблемы с аппаратной частью. Я честно говоря долго не гонял этот регулятор, побаловался минут 10 и разобрал. Но за это время ничего не висло..

saftik
Offline
Зарегистрирован: 08.04.2015
не знаю актуально ли но вот нашел еще такой скечи от тинси
​
#include <Bounce.h>

// Create Bounce objects for each button.  The Bounce object
// automatically deals with contact chatter or "bounce", and
// it makes detecting changes very simple.
Bounce button0 = Bounce(0, 10);
Bounce button1 = Bounce(1, 10);  // 10 ms debounce time is appropriate
Bounce button2 = Bounce(2, 10);  // for most mechanical pushbuttons
Bounce button3 = Bounce(3, 10);
Bounce button4 = Bounce(4, 10);  // if a button is too "sensitive" 
Bounce button5 = Bounce(5, 10);  // you can increase this time.

void setup() {
  // Configure the pins for input mode with pullup resistors.
  // The pushbuttons connect from each pin to ground.  When
  // the button is pressed, the pin reads LOW because the button
  // shorts it to ground.  When released, the pin reads HIGH
  // because the pullup resistor connects to +5 volts inside
  // the chip.
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
}

void loop() {
  // Update all the buttons.  There should not be any long
  // delays in loop(), so this runs repetitively at a rate
  // faster than the buttons could be pressed and released.
  button0.update();
  button1.update();
  button2.update();
  button3.update();
  button4.update();
  button5.update();

  // Check each button for "falling" edge.
  // falling = high (not pressed - voltage from pullup resistor)
  //           to low (pressed - button connects pin to ground)
  if (button0.fallingEdge()) {
    Keyboard.set_media(KEY_MEDIA_PREV_TRACK);
    Keyboard.send_now();	// send the button press
    Keyboard.set_media(0);
    Keyboard.send_now();	// send the button release
  }
  if (button1.fallingEdge()) {
    Keyboard.set_media(KEY_MEDIA_PLAY_PAUSE);
    Keyboard.send_now();
    Keyboard.set_media(0);
    Keyboard.send_now();
  }
  if (button2.fallingEdge()) {
    Keyboard.set_media(KEY_MEDIA_NEXT_TRACK);
    Keyboard.send_now();
    Keyboard.set_media(0);
    Keyboard.send_now();
  }
  if (button3.fallingEdge()) {
    Keyboard.set_media(KEY_MEDIA_VOLUME_DEC);
    Keyboard.send_now();
    Keyboard.set_media(0);
    Keyboard.send_now();
  }
  if (button4.fallingEdge()) {
    Keyboard.set_media(KEY_MEDIA_VOLUME_INC);
    Keyboard.send_now();
    Keyboard.set_media(0);
    Keyboard.send_now();
  }
  if (button5.fallingEdge()) {
    Keyboard.set_media(KEY_MEDIA_EJECT);
    Keyboard.send_now();
    delay(300);  // Mac OS-X will not recognize a very short eject press
    Keyboard.set_media(0);
    Keyboard.send_now();
  }

}
ali_vlad
Offline
Зарегистрирован: 20.02.2015

Приедет новый контроллер - обязательно попробую. А разница в версии arduino ide есть?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ali_vlad, этот скетч стандартный, лежит в комплекте с примерами софта от тинси. Ардуино микро собрана на таком же чипе что и тинси 2.0, но совместимы ли они  программно для среды IDE -я лично не уверен. Как минимум нужно поставить полный пакет софта тинси, и попробывать прошить, выбрав плату тинси2.0. разумеется нет гарантии, что бутлоадер ардуино микро тотчас не убъётся :-)

saftik
Offline
Зарегистрирован: 08.04.2015

dimax пишет:

ali_vlad, этот скетч стандартный, лежит в комплекте с примерами софта от тинси. Ардуино микро собрана на таком же чипе что и тинси 2.0, но совместимы ли они  программно для среды IDE -я лично не уверен. Как минимум нужно поставить полный пакет софта тинси, и попробывать прошить, выбрав плату тинси2.0. разумеется нет гарантии, что бутлоадер ардуино микро тотчас не убъётся :-)


поделюсь опытом может кому поможет.
работал в arduino ide 1.6.3  сверху утановлено teensy duino. 

проверял на arduino pro mikro и teensy 2.0
практически все скетчи которые подходят на ардуино подходят и на тинси. единственное это нужно выбрать правильный режим работы тинси (в инструментах)
также большинство скетчей от тинси подходят и ардуине.
кстати ничего не убиваеться и не горит. если в настройках вы не указали правильную плату, IDE либо отказываеться прошивать плату либо зависает.
так что - открываете скетч выставляете в настройках свою плату . если компилируеться значит и зальеться и в большинстве случаев работает

ali_vlad
Offline
Зарегистрирован: 20.02.2015

saftik пишет:

dimax пишет:

ali_vlad, этот скетч стандартный, лежит в комплекте с примерами софта от тинси. Ардуино микро собрана на таком же чипе что и тинси 2.0, но совместимы ли они  программно для среды IDE -я лично не уверен. Как минимум нужно поставить полный пакет софта тинси, и попробывать прошить, выбрав плату тинси2.0. разумеется нет гарантии, что бутлоадер ардуино микро тотчас не убъётся :-)


поделюсь опытом может кому поможет.
работал в arduino ide 1.6.3  сверху утановлено teensy duino. 

проверял на arduino pro mikro и teensy 2.0
практически все скетчи которые подходят на ардуино подходят и на тинси. единственное это нужно выбрать правильный режим работы тинси (в инструментах)
также большинство скетчей от тинси подходят и ардуине.
кстати ничего не убиваеться и не горит. если в настройках вы не указали правильную плату, IDE либо отказываеться прошивать плату либо зависает.
так что - открываете скетч выставляете в настройках свою плату . если компилируеться значит и зальеться и в большинстве случаев работает

Пытался накатить тенсидуино. Застрял на выборе папки с ардуино

по справке вылезло:

Directory: C:/Program Files (x86)/Arduino/
  Checking Arduino 1.0.5:
    file: "arduino.exe"  present
    file: "rxtxSerial.dll"  missing
    Does not match Arduino 1.0.5
  Checking Arduino 1.0.6:
    file: "arduino.exe"  present
    file: "rxtxSerial.dll"  missing

 

    Does not match Arduino 1.0.6
и всё.
TransF
Offline
Зарегистрирован: 17.06.2015

Слежу за темой, но так и не увидел ни где готвого решения, помогите пожалйуста подключить к ардуине просто энкодер, что бы она определялась как ЮСБ клава и просто регулировала VOL_UP  и  VOL_DOWN

есть же что-то типа такого

pinMode (10,INPUT);
pinMode (11,INPUT);

void setup()  
{  

Keyboard.begin();  
}  

void loop()  
{  
data=pinRead(PinMode 10);

{  Keyboard.press(VOL_UP);  

{data=pinRead(PinMode 11);

Keyboard.press(VOL_DOWN);  

saftik
Offline
Зарегистрирован: 08.04.2015

обновите оболочку ардуино и потом установите тинсидуино поверх.

оболочки тинси и ардуино должны быть совместимы. 

ali_vlad
Offline
Зарегистрирован: 20.02.2015

dimax, выложите, пожалуйста,"исправленную" версию редактора arduino (я про remote), а то у меня чего-то не получается.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

TransF, что значит нет готового решения? Сообщения #8, #11, #13   готовое решение для Arduino Micro / Leonardo. Есть ещё для дижиспарка готовые библиотеки с примером. Для прочих ардуин эмуляторы именно мультимедийных клавиш пока не попадались.

ali_vlad, если вы про вариант с софтом от тинси - то я этот вариант не проверял. Если про патч обычной ардуины -то нужно скачать проверенную версию 1.05, и поменять 2 файла, о чём тут уже писал ранее. Готового набора пропатченной ардуины у меня уже нет, стёр во время экспериментов.

ali_vlad
Offline
Зарегистрирован: 20.02.2015

Немного модифицировал чужой код. Медленно вращаю - всё нормально регулируется правильно. Быстро вращаю - бардак творится.

unsigned long currentTime; 
unsigned long loopTime; 
const int pin_enc_A = 2;        
const int pin_enc_B = 3;     
const int pin_pause = 4;     
unsigned char encoder_A; 
unsigned char encoder_B; 
unsigned char encoder_A_prev=0; 
unsigned char pause; 

void setup() { 
  pinMode(pin_enc_A, INPUT_PULLUP); // encoder 1 
  pinMode(pin_enc_B, INPUT_PULLUP); // encoder 2 
  pinMode(pin_pause, INPUT_PULLUP); // encoder pause 
  currentTime = millis(); 
  loopTime = currentTime;  
  Remote.begin();
} 

void loop() { 
  currentTime = millis(); 
  if(currentTime >= (loopTime + 5)){
    encoder_A = digitalRead(pin_enc_A);
    encoder_B = digitalRead(pin_enc_B);
    if((!encoder_A) && (encoder_A_prev)){
      if(encoder_B)  
      { 
        Remote.increase();
        delay(50);    
        Remote.clear();
        delay(50);    
      }    
      else { 
        Remote.decrease();
        delay(50);    
        Remote.clear();
        delay(50);    
      }    
    }    
    encoder_A_prev = encoder_A;

    if ( !digitalRead(pin_pause) )   { 
      pause=1;            
    } 
    else { 
      if ( pause ) {           
        delay(50);
        Remote.mute();
        delay(50);
        Remote.clear();
        delay(50); 
        pause=0; 
      }           
    } 

    loopTime = currentTime; 
  }                          
}  

 

ali_vlad
Offline
Зарегистрирован: 20.02.2015
//Скетч регулятора громкости на энкодере для Arduino MICRO
// энкодер на 10 и 11 пинах  выводы подтянуты к питанию, 
// конденсаторы на землю желательно.
//кнопка энкодера на 7 ноге, притянута к + программно. конденсатор желательно.
void setup() {             
PCICR=1<<PCIE0;
PCMSK0=(1<<PCINT7)|(1<<PCINT6);
pinMode (7,INPUT_PULLUP);
pinMode (10,INPUT);
pinMode (16,INPUT);
attachInterrupt(4, key_mute, FALLING);
Remote.begin();
}
void loop() { }

ISR (PCINT0_vect){
static byte old_n=PINB&B11000000; 
byte new_n=PINB&B11000000;
if (old_n==128&&new_n==192||old_n==64&&new_n==0) {Remote.increase();}
if (old_n==64&&new_n==192||old_n==128&&new_n==0) {Remote.decrease();}
old_n= new_n;
}

void key_mute() {Remote.mute();}

 

ali_vlad
Offline
Зарегистрирован: 20.02.2015

11го вывода у меня нет есть 2-10 и 14-16. Громкость регулирует только в одну сторону. При нажатии на кнопку не обрабатывается дребезг контактов

TransF
Offline
Зарегистрирован: 17.06.2015

dimax пишет:

TransF, что значит нет готового решения? Сообщения #8, #11, #13   готовое решение для Arduino Micro / Leonardo. Есть ещё для дижиспарка готовые библиотеки с примером. Для прочих ардуин эмуляторы именно мультимедийных клавиш пока не попадались.


Готовые примеры из перечисленных сообщееий почему то у меня так и не заработали, хотя у меня именно Леонардо микро.
Несколько раз пробовал 13 сообщение, может я что-то не так подключил, уточните пожалуйста подключение.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ali_vlad, что значит нет вывода 11 ? Я распиновку давал для стандартной платы. Это порты контроллера mega32u4  PB6, PB7

TransF, а что может быть непонятным с подключением? Схема стандартная, примерно как тут:

Выводы ардуины микро /леонардо  d10, d11. Конденсаторы (для варианта с внешними резисторами, распаянными на энкодере) я применял 0,1мкф. Проблем никаких не было.

 

ali_vlad
Offline
Зарегистрирован: 20.02.2015

Видимо у меня китайская ардуина

http://www.ebay.com/itm/New-Pro-Micro-ATmega32U4-5V-16MHz-Replace-ATmega328-Arduino-Pro-Mini-/140972980117?hash=item20d2a4f795

там нет 11го вывода

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

ali_vlad пишет:

Видимо у меня китайская ардуина

http://www.ebay.com/itm/New-Pro-Micro-ATmega32U4-5V-16MHz-Replace-ATmega328-Arduino-Pro-Mini-/140972980117?hash=item20d2a4f795

там нет 11го вывода


Ну не шмогла :)

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ali_vlad, мой скетч нетрудно переделать под любые  PCINT выводы. Для контроллера 32u4 это выводы порта "B"   PB0-PB7. ( соответвующие им ардуиновские ноги будут: D14, D15, D16, D17, D8, D9, D10, D11)  Там простое математическое сложение "веса" битов. Либо используйте универсальные обработчики энкодеров, но результат будет хуже. Т.к. мой скетч работает через прерывание, и считывает одновременно оба бита данных с энкодера, чем собственно и повышается качество и скорость обработки.

ali_vlad
Offline
Зарегистрирован: 20.02.2015

Что-то туплю с утра. Ткните меня носом.

А лучше поясните в коде, что к какой ноге относится, а то я чувствую, что не въеду. Не могу найти в loop{}, считывание состояний 10 и 11 ног.

Уточните, пожалуйста емкости конденсаторов, а то в соседней ветке читаю, несколько разных утверждений и каждый доказывает, что он прав.

Так же хотелось бы уточнить еще одинмомент. Делитель из резисторов и кондер. Одни советуют кондер в середину делителя полключать (http://arduino.ru/forum/apparatnye-voprosy/ispolzuem-enkoder?page=2#comment-121532), другие "к ноге" ардуины (http://arduino.ru/forum/apparatnye-voprosy/ispolzuem-enkoder?page=2#comment-121571). Как лучше

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ali_vlad, если хотите во всём разобраться, то почитайте про то, как работает энкодер. Потом почитайте про прерывания PCINT, потом в даташите на контроллер (страница3) посмотрите на каких ногах есть PCINT. Потом по схеме вашей ардуины выберите нужные ноги. Потом по аналогии  переделать скетч на другие выводы. Ну или напишите на какие ноги из перечисленных мною в #44 хотите повесить, я помогу.

По поводу резисторов и конденсаторов - все варианты должны по идее работать, но схема по второй ссылке на мой взгляд более правильная. Какую функцию выполняют резисторы в  схеме из первой ссылки я тоже не могу объяснить.  Лично я всегда подключаю по схеме из #41, ёмкости использовал 0,01..0,1 мкф.

ali_vlad
Offline
Зарегистрирован: 20.02.2015

8, 9 энкодер. 7 Так и останется "mute".

И еще небольшая просьба. Как сделать, чтобы после первого нажатия на кнопку (вывод 7) она не опрашивалась заданное время (0,5 - 1 сек). А то при нажатии идет включение и выключение звука со страшной скоростью. Deley не хотелось бы использовать.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ali_vlad, вот поправил на ноги 8 и 9. Не проверял конечно, но вроде проблем быть не должно.

//Скетч регулятора громкости на энкодере для Arduino PRO MICRO
// энкодер на 8 и 9 пинах  выводы подтянуты к питанию, 
// конденсаторы на землю желательно.
//кнопка энкодера на 7 ноге, притянута к + программно. конденсатор желательно.
void setup() {             
PCICR=1<<PCIE0;
PCMSK0=(1<<PCINT5)|(1<<PCINT4);
pinMode (7,INPUT_PULLUP);
pinMode (8,INPUT);
pinMode (9,INPUT);
attachInterrupt(4, key_mute, FALLING);
Remote.begin();
}
void loop() { }

ISR (PCINT0_vect){
static byte old_n=PINB&B00110000; 
byte new_n=PINB&B00110000;
if (old_n==32&&new_n==48||old_n==16&&new_n==0) {Remote.increase();}
if (old_n==16&&new_n==48||old_n==32&&new_n==0) {Remote.decrease();}
old_n= new_n;
}

void key_mute() {Remote.mute();}


По поводу кнопки MUTE -на неё тоже нужно конденсатор, лучше не менее 0,1мкф. У меня никаких проблем не было.

ali_vlad
Offline
Зарегистрирован: 20.02.2015

Странно как-то. Если вращать ручку, не важно в какую сторону, то первым щелчком громкость изменяется как-бы на 1 шаг, потом на двойной шаг. Сильно замено на ведроиде. Родными кнопками от одного крайнего до другого  - 15 нажатий, энкодером - 8 щелчков. На компе то же самое, одного крайнего до другого  - 50 нажатий, энкодером - 25 щелчков. Может кондеры не той емкости или резисторы не того сопротивления? Читал про триггеры. Отечественныех микросхем с готовыми триггерами, по моему нет. Нужно схему мутить. Импотрные наверняка есть. Типа так: 1 - вход, 2 - выход, и т.д. но не знаю их названий. Может есть готовые микросхеды - интидребезг?

Резисторы 10к на {+}. Кондеры 0,1 мкФ на {-}. 

 

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

ali_vlad пишет:

Странно как-то. Если вращать ручку, не важно в какую сторону, то первым щелчком громкость изменяется как-бы на 1 шаг, потом на двойной шаг. Сильно замено на ведроиде. Родными кнопками от одного крайнего до другого  - 15 нажатий, энкодером - 8 щелчков. На компе то же самое, одного крайнего до другого  - 50 нажатий, энкодером - 25 щелчков. Может кондеры не той емкости или резисторы не того сопротивления? Читал про триггеры. Отечественныех микросхем с готовыми триггерами, по моему нет. Нужно схему мутить. Импотрные наверняка есть. Типа так: 1 - вход, 2 - выход, и т.д. но не знаю их названий. Может есть готовые микросхеды - интидребезг?

Резисторы 10к на {+}. Кондеры 0,1 мкФ на {-}. 

энкодер конструктивно может давать один механический щелчок на два сигнала.

у меня вообще энкодеры дают четыре сигнала на один механический щелчок.

попробуй поставить программный счётчик сигналов на экнодер, что бы проверить, так это или нет.