Вложений: 3
Управление Android при помощи Arduino Leonardo и подрулевого джойстика от Reno
Доброе время суток вам всем!
Пытаясь осуществить CarPc из Nexus 7 2013 у себя в машине наткнулся на одну интересную вещь - Leonardo с возможностью HID keyboard.
До этого думал ставить просто контроллер для управлением включения-отключения планшета и переферии. Было просто.
Но я задумал облегчить управление планшетом в движении и для этого купил подрулевой джойстик от ам Renault.
Вложение 18097
Вот его схема
Вложение 18098
То, что я находил из скетчей под Ардуино, были либо под UNO либо на резистивное управление магнитолой.
PHP код:
/////////////////////////////////////////////////////////////////
// alpine
#define alpinePin 13
#define cmdPower 0x09
#define cmdSource 0x0A
#define cmdBand 0x0D
#define cmdVolumeDown 0x15
#define cmdVolumeUp 0x14
#define cmdUp 0x0E
#define cmdDown 0x0F
#define cmdLeft 0x13
#define cmdRight 0x12
#define cmdPlay 0x07
#define cmdAProc 0x06
#define cmdMute 0x16
#define cmdAngleUp 0x4C
#define cmdAngleDown 0x4B
#define cmdCDChange 0x03
/////////////////////////////////////////////////////////////////
// джойстик
#define rows 3
#define cols 2
// номера кнопок в соответствии со схемой
const byte keys[rows][cols] =
{
{1,4},
{2,5},
{6,3}
};
// состояния направлений енкодера
const byte encoderdirection[3][3] = // 0 - на месте, 1 - вниз, 2 - вверх
{
{0, 1, 2}, // 0
{2, 0, 1}, // 1
{1, 2, 0} // 2
};
// номера пинов
const byte rowPins[rows] = {8, 6, 9}; // строки (желтый, зеленый, голубой)
const byte colPins[cols] = {1, 0}; // столбцы (черный, красный)
#define encoderPin 2 // пин енкодера (коричневый)
byte encodervalue;
// маски для клавиш
#define MaskMediaButton 1
#define MaskRadioButton 2
#define MaskVolumeUpButton 4
#define MaskVolumeDownButton 8
#define MaskOkButton 16
#define MaskMuteButton 32
#define MaskScrollDown 64
#define MaskScrollUp 128
/////////////////////////////////////////////////////////////////
void setup()
{
int i;
// строки - на выход
for (i = 0; i < rows; ++i)
{
pinMode(rowPins[i], OUTPUT);
}
// столбцы - на вход
for (i = 0; i < cols; ++i)
{
pinMode(colPins[i], INPUT);
digitalWrite(colPins[i], HIGH); // включаем подтягивающий резистор
}
// столбец для енкодера
pinMode(encoderPin, INPUT);
digitalWrite(encoderPin, HIGH); // включаем подтягивающий резистор
encodervalue = 0;
Serial.begin(9600);
// initialize mouse control:
Mouse.begin();
Keyboard.begin();
}
// сканирование джойстика
byte scan(void)
{
int i, j;
byte code = 0;
for (i = 0; i < rows; ++i)
{
digitalWrite(rowPins[i], LOW);
// кнопки
for (j = 0; j < cols; ++j)
{
if(digitalRead(colPins[j]) == false)
{
code |= 1 << (keys[i][j] - 1);
}
}
// енкодер
if (digitalRead(encoderPin) == false)
{
int oldencodervalue = encodervalue;
encodervalue = i;
switch (encoderdirection[oldencodervalue][encodervalue])
{
case 1: // вниз
code |= 64;
break;
case 2: // вверх
code |= 128;
break;
}
}
digitalWrite(rowPins[i], HIGH);
}
return code;
}
// отправка байта
void SendByte(byte data)
{
for (int i = 0; i < 8; ++i)
{
digitalWrite(alpinePin, HIGH);
delayMicroseconds(560);
digitalWrite(alpinePin, LOW);
if (data & 1)
{ // 1
delayMicroseconds(1680);
}
else
{ // 0
delayMicroseconds(560);
}
data >>= 1;
}
}
// отправка команды
void Send(byte command)
{
digitalWrite(alpinePin, HIGH);
delayMicroseconds(9000);
digitalWrite(alpinePin, LOW);
delayMicroseconds(4500);
SendByte(0x86);
SendByte(0x72);
SendByte(command);
SendByte(~command);
digitalWrite(alpinePin, HIGH);
delayMicroseconds(560);
digitalWrite(alpinePin, LOW);
}
// цикл программы
void loop(void)
{
byte code;
code = scan();
if (code & MaskMediaButton)
Keyboard.write('u');
if (code & MaskRadioButton)
Send(cmdUp);
if (code & MaskVolumeUpButton)
Send(cmdRight);
if (code & MaskVolumeDownButton)
Send(cmdLeft);
if (code & MaskOkButton)
Send(cmdPlay);
if (code & MaskMuteButton)
Send(cmdMute);
if (code & MaskScrollDown)
Send(cmdVolumeDown);
if (code & MaskScrollUp)
Send(cmdVolumeUp);
}
Протестировав этот скетч на нажатия кнопок я попытался написать скетч под свои нужды.
С управлением питания планшета и переферии я разобрался, а с джойстиком, увы нет.
По этому проблема сейчас встала в управлении андроид планшетом с этого подрулевого джойстика как с HID клавиатуры с короткими и длинными нажатиями на кнопки + энкодер.
Так как я в програмирование залез только сейчас, прошу вашей помощи в реализации проекта. В долгу не останусь, т.е. Ваш труд будет оплачен по договорености.
Жду ваших предложений, можно в личку.
С уважением,
D. K.
Re: Управление Android при помощи Arduino Leonardo и подрулевого джойстика от Reno
Для чтения резистивных кнопок используйте функцию analogRead()
Re: Управление Android при помощи Arduino Leonardo и подрулевого джойстика от Reno
В том то и дело, что это не резистивные кнопки. Посмотрите на схему устройства.
Re: Управление Android при помощи Arduino Leonardo и подрулевого джойстика от Reno
Так у Вас скетч тоже не под резистивные кнопки
Re: Управление Android при помощи Arduino Leonardo и подрулевого джойстика от Reno
Я проверял работу (отклик) кнопок на том скетче, а далее цитирую самого себя:
Цитата:
По этому проблема сейчас встала в управлении андроид планшетом с этого подрулевого джойстика как с HID клавиатуры с короткими и длинными нажатиями на кнопки + энкодер.
так как знаний у меня явно не хватает для реализации этой приблуды как HID keyboard, прошу помощи у знающих.
Re: Управление Android при помощи Arduino Leonardo и подрулевого джойстика от Reno
Stray
Здесь есть готовое решение, но естественно требующее дороботки под Ваши задачи.
Re: Управление Android при помощи Arduino Leonardo и подрулевого джойстика от Reno
Спасибо за ответ, но опять же, это не то. это не резистивный пульт, да и делать его таким у меня нет желания. Главная из задач, оставить энкодер в рабочем состоянии
Re: Управление Android при помощи Arduino Leonardo и подрулевого джойстика от Reno
Stray
Понятно что это не резистивный пульт, ответ в основном был на эти Ваши вопросы:
Цитата:
Сообщение от
Stray
По этому проблема сейчас встала в управлении андроид планшетом с этого подрулевого джойстика как с HID клавиатуры с короткими и длинными нажатиями на кнопки + энкодер.
Цитата:
Сообщение от
Stray
так как знаний у меня явно не хватает для реализации этой приблуды как HID keyboard, прошу помощи у знающих.
Из ссылки которую я давал, можно получить решение по работе Leonardo как HID клавиатуры (даже с медиа кнопками) и возможности назначения действий на короткие и длинные нажатия на кнопки. А остальное уже сами...
Re: Управление Android при помощи Arduino Leonardo и подрулевого джойстика от Reno
Stray
Попробуйте, этот скетч у Вас работает. Не забудьте поменять USBAPI.h, HID.cpp как описано здесь.
Код:
// джойстик
#define rows 3
#define cols 2
// номера кнопок в соответствии со схемой
const byte keys[rows][cols] =
{
{1,4},
{2,5},
{6,3}
};
// состояния направлений енкодера
const byte encoderdirection[3][3] = // 0 - на месте, 1 - вниз, 2 - вверх
{
{0, 1, 2}, // 0
{2, 0, 1}, // 1
{1, 2, 0} // 2
};
// номера пинов
const byte rowPins[rows] = {8, 6, 9}; // строки (желтый, зеленый, голубой)
const byte colPins[cols] = {1, 0}; // столбцы (черный, красный)
#define encoderPin 2 // пин енкодера (коричневый)
byte encodervalue;
// маски для клавиш
#define MaskMediaButton 1
#define MaskRadioButton 2
#define MaskVolumeUpButton 4
#define MaskVolumeDownButton 8
#define MaskOkButton 16
#define MaskMuteButton 32
#define MaskScrollDown 64
#define MaskScrollUp 128
/////////////////////////////////////////////////////////////////
void setup()
{
int i;
// строки - на выход
for (i = 0; i < rows; ++i)
{
pinMode(rowPins[i], OUTPUT);
}
// столбцы - на вход
for (i = 0; i < cols; ++i)
{
pinMode(colPins[i], INPUT);
digitalWrite(colPins[i], HIGH); // включаем подтягивающий резистор
}
// столбец для енкодера
pinMode(encoderPin, INPUT);
digitalWrite(encoderPin, HIGH); // включаем подтягивающий резистор
encodervalue = 0;
Keyboard.begin();
}
// сканирование джойстика
byte scan(void)
{
int i, j;
byte code = 0;
for (i = 0; i < rows; ++i)
{
digitalWrite(rowPins[i], LOW);
// кнопки
for (j = 0; j < cols; ++j)
{
if(digitalRead(colPins[j]) == false)
{
code |= 1 << (keys[i][j] - 1);
}
}
// енкодер
if (digitalRead(encoderPin) == false)
{
int oldencodervalue = encodervalue;
encodervalue = i;
switch (encoderdirection[oldencodervalue][encodervalue])
{
case 1: // вниз
code |= 64;
break;
case 2: // вверх
code |= 128;
break;
}
}
digitalWrite(rowPins[i], HIGH);
}
return code;
}
// цикл программы
void loop(void)
{
byte code;
code = scan();
if (code & MaskRadioButton)
{
Keyboard.press(KEY_LEFT_ALT);
Keyboard.press(KEY_TAB);
Keyboard.release(KEY_TAB);
Keyboard.press(KEY_TAB);
Keyboard.release(KEY_TAB);
}
if (code & MaskVolumeUpButton)
Remote.next();
if (code & MaskVolumeDownButton)
Remote.forward();
if (code & MaskOkButton)
Remote.play_pause();
if (code & MaskMuteButton)
Remote.mute();
if (code & MaskScrollDown)
Remote.decrease();
if (code & MaskScrollUp)
Remote.increase();
else
Remote.clear();
Keyboard.releaseAll();
}
Re: Управление Android при помощи Arduino Leonardo и подрулевого джойстика от Reno
Спасибо, Уважаемый lti1!
Сейчас осталось только переназначить кнопки и добавить короткое и длинное нажатие + вернуть экранную клаву на место.
Будет не легко, но гранит науки всегда крепок! ))