usb hid jostik

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

Доброго  времени суток уважаемые форумчане. 
задался целью сделать USB Hid jostik (чтоб устанавливался в ОС Windows без драйверов)
сложность что надо сделать на 28 кнопок.

перечитал море информации, но не доконца понятно что и как делать. 

мои попытки привели к тому я сvог на базе arduino micro и/или подобной ей  плате teensy сделать usb клавиатуру. 
 

// для Arduino leonardo раскоменитировать и закоментировать teensy
int rows[] = {4,5,6,7,8,9,10}; //указываем пины строк
int cols[] = {A3,A4,A5,A6};   //и столбцов

/*
// для teensy раскоментировать и закоментировать Arduino
int rows[] = {3,4,5,6,7,8,9};  //указываем пины строк
int cols[] = {A3,A4,A5,A6};    //и столбцов
*/
char keys[] = {
  'q', // 1
  'w', // 2
  'e', // 3
  'r', // 4   
  '2', // 5
  'y', // 6
  'u', // 7
  'i', // 8
  'o', // 9
  'p', // 10
  'a', // 11
  's', // 12
  'd', // 13
  'f', // 14
  'g', // 15
  'h', // 16
  'j', // 17
  'k', // 18
  'l', // 19
  'z', // 20
  'x', // 21
  'c', // 22
  'v', // 23
  'b', // 24
  'n', // 25
  'm', // 26
  '1', // 27
  't', // 28
};
int keyStates[] = {
  0,//0
  0,//1
  0,//2
  0,//3
  0,//4
  0,//5
  0,//6
  0,//7
  0,//8
  0,//9
  0,//10
  0,//11
  0,//12
  0,//13
  0,//14
  0,//15
  0,//16
  0,//17
  0,//18
  0,//19
  0,//20
  0,//21
  0,//22
  0,//23
  0,//24
  0,//25
  0,//26
  0,//27
  };
#define COLS 4 // количество столбцов
#define ROWS 7 // количество строк
//===============================   #define LED 13 
void setup() {
  Keyboard.begin();
//==============================    pinMode(LED, OUTPUT);
  int i=0;
    for(i=0;i<COLS;i++) {
    pinMode(cols[i], INPUT_PULLUP);}
    
    for(i=0;i<ROWS;i++) {
    pinMode(rows[i], INPUT);}
}

void loop() {
  int i;
  int j;
//============================  digitalWrite(LED, HIGH); 
    for(i=0;i<COLS;i++) {
    for(j=0;j<ROWS;j++) {
      pinMode(rows[j], OUTPUT);
      digitalWrite(rows[j], LOW);
      int sensorValue = analogRead(cols[i]);
      pinMode(rows[j], INPUT);
      int index = i*ROWS+j;
      if(sensorValue < 512) {keyStates[index] = 1; }
      else {keyStates[index] = 0; }
    }
  }  
    for(i=0;i<COLS*ROWS;i++) {
    char key = keys[i];
    if(keyStates[i] == 1) {Keyboard.press(key); }
    else {Keyboard.release(key); }
  }
  //========================== digitalWrite(LED, LOW); 
  delay(1);
}

 

как видно из кода клавиатура основана на матрице 7*4 
код полностью работчий и опробован,  Все бы ничего если бы не одно НО.
при одновременном нажатии более 3 кнопок игра начинает вылетать и происходят разные лаги.
 

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

немного поразмыслив понял что желательно бы сделать что то типо геймпада где предусмотренно одновременное нажатие нескольких клавиш сразу. 
стало быть (подумал я ) можно использовать стандарный скетч от teensy в этом варианте на каждую кнопку выделен свой пин. 
Залил скетч в teensy 2.0 проверил-  да то что надо, в игровых устройсвах виден джойстик одновременно можно нажимать все кнопки. 
Все бы хорошо если бы не одно но , на teensy 2.0 можно подключиться к 23 пинам а мне нужно 28. (по сути это будет один контролер на 2 джостика).
смотрел в сторону teensy ++, там пинов хватило бы вот только цена на них неразумная, в китая  порядка 35$
 

/* Buttons to USB Joystick Example

   You must select Joystick from the "Tools > USB Type" menu

   This example code is in the public domain.
*/

#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 = 10 ms debounce time
Bounce button2 = Bounce(2, 10);  // which is appropriate for
Bounce button3 = Bounce(3, 10);  // most mechanical pushbuttons
Bounce button4 = Bounce(4, 10);
Bounce button5 = Bounce(5, 10);
Bounce button6 = Bounce(6, 10);
Bounce button7 = Bounce(7, 10);
Bounce button8 = Bounce(8, 10);
Bounce button9 = Bounce(9, 10);
Bounce button10 = Bounce(10,10);
Bounce button11 = Bounce(11, 10);
Bounce button12 = Bounce(12, 10);
Bounce button13 = Bounce(13, 10);
Bounce button14 = Bounce(14, 10);
Bounce button15 = Bounce(15, 10);
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.  LOW for "on", and HIGH for "off" may seem
  // backwards, but using the on-chip pullup resistors is very
  // convenient.  The scheme is called "active low", and it's
  // very commonly used in electronics... so much that the chip
  // has built-in pullup resistors!
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);  // Teensy++ LED, may need 1k resistor pullup
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);  // Teensy++ LED, may need 1k resistor pullup
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
  pinMode(15, 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();
  button6.update();
  button7.update();
  button8.update();
  button9.update();
  button10.update();
  button11.update();
  button12.update();
  button13.update();
  button14.update();
  button15.update();
  // Check each button for "falling" edge.
  // Update the Joystick buttons only upon changes.
  // falling = high (not pressed - voltage from pullup resistor)
  //           to low (pressed - button connects pin to ground)
  if (button0.fallingEdge()) {
    Joystick.button(1, 1);
  }
  if (button1.fallingEdge()) {
    Joystick.button(2, 1);
  }
  if (button2.fallingEdge()) {
    Joystick.button(3, 1);
  }
  if (button3.fallingEdge()) {
    Joystick.button(4, 1);
  }
  if (button4.fallingEdge()) {
    Joystick.button(5, 1);
  }
  if (button5.fallingEdge()) {
    Joystick.button(6, 1);
  }
  if (button6.fallingEdge()) {
    Joystick.button(7, 1);
  }
  if (button7.fallingEdge()) {
    Joystick.button(8, 1);
  }
  if (button8.fallingEdge()) {
    Joystick.button(9, 1);
  }
  if (button9.fallingEdge()) {
    Joystick.button(10, 1);
  }
  if (button10.fallingEdge()) {
    Joystick.button(11, 1);
  }
  if (button11.fallingEdge()) {
    Joystick.button(12, 1);
  }
  if (button12.fallingEdge()) {
    Joystick.button(13, 1);
  }
  if (button13.fallingEdge()) {
    Joystick.button(14, 1);
  }
  if (button14.fallingEdge()) {
    Joystick.button(15, 1);
  }
  if (button15.fallingEdge()) {
    Joystick.button(16, 1);
  }

  // Check each button for "rising" edge
  // Update the Joystick buttons only upon changes.
  // rising = low (pressed - button connects pin to ground)
  //          to high (not pressed - voltage from pullup resistor)
  if (button0.risingEdge()) {
    Joystick.button(1, 0);
  }
  if (button1.risingEdge()) {
    Joystick.button(2, 0);
  }
  if (button2.risingEdge()) {
    Joystick.button(3, 0);
  }
  if (button3.risingEdge()) {
    Joystick.button(4, 0);
  }
  if (button4.risingEdge()) {
    Joystick.button(5, 0);
  }
  if (button5.risingEdge()) {
    Joystick.button(6, 0);
  }
  if (button6.risingEdge()) {
    Joystick.button(7, 0);
  }
  if (button7.risingEdge()) {
    Joystick.button(8, 0);
  }
  if (button8.risingEdge()) {
    Joystick.button(9, 0);
  }
  if (button9.risingEdge()) {
    Joystick.button(10, 0);
  }
  if (button10.risingEdge()) {
    Joystick.button(11, 0);
  }
  if (button11.risingEdge()) {
    Joystick.button(12, 0);
  }
  if (button12.risingEdge()) {
    Joystick.button(13, 0);
  }
  if (button13.risingEdge()) {
    Joystick.button(14, 0);
  }
  if (button14.risingEdge()) {
    Joystick.button(15, 0);
  }
  if (button15.risingEdge()) {
    Joystick.button(16, 0);
  }
}

 сидел думал что к чему  , 
1 нужно сделать устройство типо usb hid
2  контроллеры в корпусе типа TPQF я не распаяю стало быть нужно в dip корпусе.
3 нужен загрузчик чтоб можно было контроллер прошивать.
4 usb реализация.

ну и собственно сам вопрос.  пока еще не успел потратить деньги. 
1) стоит ли делать на atmega 16? почему именно этот контроллер : много ног, корпус dip, програмная реализация USB 
2) если так посоветуйте где почитать реализацию USB для чайников чтоб по шагам было . а то перелопатил кучу инфы,
понял только то что нужно написать HID дескриптор и при компиляции подключить библиотеку V-USB.
а что,   как, зачем я так и не понял. 
в моей голове сейчас каша 

!) USB к atmega16 подпаяю без проблем. схем в нете полно.

2)дескриптор сгененерировал с помощью программы HID desckriptor сохранил в формате hid 

3)есть библиотека v-usb
и
есть скетч от teensy,
но как это все вместе увязать не понимаю.

(HELP, SOS) помогите  разобраться. 
натолкните что почитать, (USB org не предлогать - там и черт ногу сломит) 

вообще больше месяца ищу инфу подробной инструкции не нашел. 

P/S Всем откликнувшимся спасибо, 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а причем тут analogread если цифровой сигнал?

saftik
Offline
Зарегистрирован: 08.04.2015
 int sensorValue = digitalRead(cols[i]);
  pinMode(rows[j], INPUT);
  int index = i*ROWS+j;
  if(sensorValue == LOW) {keyStates[index] = 1; }
  else {keyStates[index] = 0; }

jeka_tm пишет:

а причем тут analogread если цифровой сигнал?

Спасибо за замечание.
ну да можно и читать как dijitalread .

но все равно сути это не меняет. 
 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а ты когда считываешь кнопки, сначала проведи сканирование всей клавиатуры, и если обнаружишь не одно нажатие то проводи повторно, либо расставь приоритет

а лучше 74hc165 поставь и сканируй все кнопки. если возможны одновременные нажатия, а у тебя скорее всего возможны так как ты скорее всего делаешь клавиатуру для игры, и сканироваться будут кнопки каждая отдельно, и даже одновременное нажатие можно передать, просто назначить последовательность. например массив заполнять . 1 это нажатая кнпока, а потом передавать по usb по порядку только те которые имеют 1. после передачи массив обнулить и снова сканировать

ну или без массива было срабатывание - отправили

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

jeka_tm пишет:

а ты когда считываешь кнопки, сначала проведи сканирование всей клавиатуры, и если обнаружишь не одно нажатие то проводи повторно, либо расставь приоритет

а лучше 74hc165 поставь и сканируй все кнопки. если возможны одновременные нажатия, а у тебя скорее всего возможны так как ты скорее всего делаешь клавиатуру для игры, и сканироваться будут кнопки каждая отдельно, и даже одновременное нажатие можно передать, просто назначить последовательность. например массив заполнять . 1 это нажатая кнпока, а потом передавать по usb по порядку только те которые имеют 1. после передачи массив обнулить и снова сканировать

ну или без массива было срабатывание - отправили

1 ) чесно сказать не приходит в голову как это поможет и как это сделать. (програмистом меня не назвать, я начинающий самоучка)
2) тоже думал в сторону сдвиговых регистров. 
но как принимать с них значения как их расшифровывать и отправлять в комп не знаю, 
(думаю стоит почитать)

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

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

класно бы было подключил и играем, причем клава ноутбука или компа не пострадает

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

да  и если быть чесным уже скачал образ emulatostantion на raspbery проверил на простых джостиках работает. 
но опять же в будующем хотелось бы иметь возможность добовлять "крутилки" потому и  хочу научиться делать свое устройство. 

планирую сделать платку на базе atmege 16 по следующей схеме 
как у же говорил схему соберу без проблем.

вот только какие дальнейшие мои действия?

1) залить в атмегу USBASPloader (планирую залить с помощью arduino Uno на крайняк имееться програматор minipro) 
2) нужен hid descriptor (думаю вытащить из примера для teensy )
3) нужен код (хотелось бы чтоб код был простой и понятный на подобие того что в моем втором посте , который от teensy ) 
4) подозреваю что нужно получить hex файл для прошивки контроллера, 
чтоб получить этот самый заветный файл нужно (поправте если ошибаюсь) atmel studio скомпелировать файл дескриптора и прошивки (никогда этого не делал- ток поставил на скачку студию)

собственно какие шаги я еще не учел ?

простите за глупые вопросы

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

ну вот по моему использовать USBASPloader когда есть arduino micro смысла нет

а гуглить слабо?

http://robocraft.ru/blog/arduino/520.html

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

jeka_tm пишет:

ну вот по моему использовать USBASPloader когда есть arduino micro смысла нет

а гуглить слабо?

http://robocraft.ru/blog/arduino/520.html

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

хочу повесить 28 кнопок на 28 пинов. 
для того чтобы играя к примеру в "мортал комбат" можно было одновременно нажать 6 кнопок. 

нет не слабо. я как раз читал эту статью http://robocraft.ru/blog/arduino/618.html

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

saftik пишет:

вот только какие дальнейшие мои действия?

собственно какие шаги я еще не учел ?

собираешь оригинальный джойстик MJoy16 

8 осей, 64 кнопки, тумблеры, энкодеры, автокалибровка

http://www.joysticks.ru/joysticks/handmade/mjoy16.shtml

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

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

Клапауций 070 пишет:

saftik пишет:

вот только какие дальнейшие мои действия?

собственно какие шаги я еще не учел ?

собираешь оригинальный джойстик MJoy16 

8 осей, 64 кнопки, тумблеры, энкодеры, автокалибровка

http://www.joysticks.ru/joysticks/handmade/mjoy16.shtml

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


Спасибо за наводку буду пробовать.
Правда на этом сайте уже готовый hex файл, просто залив его в контроллер, Я не научусь делать usb устройство под себя. Ну допустим со своим именем устройства. Или например мне не нужно 8 осей. Хотелось бы во всем этом разобраться. Ну и на том спасибо начну с малого а там видно будет .

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

saftik пишет:

Правда на этом сайте уже готовый hex файл, просто залив его в контроллер, Я не научусь делать usb устройство под себя. Ну допустим со своим именем устройства. Или например мне не нужно 8 осей. Хотелось бы во всем этом разобраться.

ок. учись делать своё устройство - через пять лет покажешь результат.

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

Клапауций 070 пишет:

saftik пишет:

Правда на этом сайте уже готовый hex файл, просто залив его в контроллер, Я не научусь делать usb устройство под себя. Ну допустим со своим именем устройства. Или например мне не нужно 8 осей. Хотелось бы во всем этом разобраться.

ок. учись делать своё устройство - через пять лет покажешь результат.


Специально для песимистов сообщаю. Есть проэкт mmjoy . Програмка такая. подключаем свою плату выбираем необходимое количество кнопок осей тумблеров, название устройства и т.д.
Проффесор калапауций простите что разочаровал вас и не заставил ждать 5 лет.