Официальный сайт компании Arduino по адресу arduino.cc
Совместное использование клавиатуры для компа и ардуино
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Каждый раз, подсоединяя к ардуино какие нибудь кнопки или энкодер смотрел на лежащую рядом клавиатуру компа, и думал, что хорошо бы её как-то использовать. Расшарить для ардуины так сказать. А сегодня попалась статья на амперке про клавиатурный шпион. И тут осенило -вот то, что нужно. Вставить в клавиатуру М.К., он будет отлавливать нажатие нужных клавиш на USB-клавиатуре, и дёргать нужные ноги своего порта. Выводы вывести на гребёнку, и использовать на ардуине вместо кнопок. И никакого дребезга :) Дело сразу пошло лёгко, спаял из ненужной меги8 ардуину, вывел 10 контактный разъём наружу, вот вид уже вставленного контроллера в клавиатуру. Питается он от юсб. Можно взять любую 16-мгц ардуину.
Вот так выглядит в собранном виде.
Скетч для примера. Тут перехватываю нажатия кнопок F9..F12 и дёргаю соответсвующие ноги порта. Библиотека V-USB адаптированная для ардуины качается по ссылке с амперки, в ней я ничего не менял.
// библа и идея отсюда: http://wiki.amperka.ru/projects:keylogger #include <usbdrv.h> uint8_t usbRxBuf[USB_BUFSIZE]; uint8_t FIFOBuf[(IN_SIZE+USB_BUFSIZE)*FIFO_BUF_SIZE]; uint8_t CurWritePos=0,CurReadPos=0; uint8_t KeyData[8]; void setup(){ pinMode(2,INPUT); //USB d- (зелёный) pinMode(4,INPUT);// USB d+ (белый) pinMode(8,OUTPUT); //выход для кнопки F12 pinMode(9,OUTPUT); //выход для кнопки F11 pinMode(10,OUTPUT); //выход для кнопки F10 pinMode(11,OUTPUT); //выход для кнопки F9 Serial.begin(9600); usbInit(); } void loop() { if(CurWritePos!=CurReadPos){ for (uint8_t n=0; n < 8; n++) { KeyData[n] = FIFOBuf[CurReadPos*14+4+n]; // Serial.print (KeyData[n],HEX); // Serial.print (" "); } // Serial.println (); CurReadPos++; if (CurReadPos>=FIFO_BUF_SIZE) CurReadPos = 0; } if (KeyData[2]==0x45 && (KeyData[0]|KeyData[1]|KeyData[3]|KeyData[4]|KeyData[5]|KeyData[6]|KeyData[7]==0) ) { PORTB|=1<<0 ; } else PORTB&=~(1<<0); // если была нажата клавиша F12 if (KeyData[2]==0x44 && (KeyData[0]|KeyData[1]|KeyData[3]|KeyData[4]|KeyData[5]|KeyData[6]|KeyData[7]==0) ) { PORTB|=1<<1 ; } else PORTB&=~(1<<1); // если была нажата клавиша F11 if (KeyData[2]==0x43 && (KeyData[0]|KeyData[1]|KeyData[3]|KeyData[4]|KeyData[5]|KeyData[6]|KeyData[7]==0) ) { PORTB|=1<<2 ; } else PORTB&=~(1<<2); // если была нажата клавиша F10 if (KeyData[2]==0x42 && (KeyData[0]|KeyData[1]|KeyData[3]|KeyData[4]|KeyData[5]|KeyData[6]|KeyData[7]==0) ) { PORTB|=1<<3 ; } else PORTB&=~(1<<3); // если была нажата клавиша F9 }
Если убрать ремарки с сериалпринтов, то можно посмотреть коды других кнопок, и настроить другие варианты. Потом допишу эмулятор энкодера, переключать типы эмуляции (кнопки/энкодер) можно опять таки с клавиатуры.
Здравствуйте! Уже не первый день ковыряю этот вопрос. Прошу вашей помощи.
Использую ваш код в качестве эталона. Задача на данном этапе - перехватить нажатие "Scroll lock". При этом столкнулся с рядом проблем, не получив даже простых нажатий:
1) Для теста я решил добиться стабильного захвата нажатия той или иной клавиши. Для этого изменил ваш участок кода:
на
чтобы мониторить срабатывание перехвата.
По итогу перехват не работает ни в какую, а по вашему совету раскомментировав
получаю(не нажимая клавиш, только ее служебные процессы) в монитор порта поток значений типа:
"778FFFFFFFFFFFF1F7FF2FFFFFFFFFFF571F87FE17FFC51FBFFB2FFE93FFFFCBFFFFFFFFFFFFFF778A3FFE"
------------------
2) Хочу заметить, вдруг это важно, при каждой компиляции ошибка:
При этом скетч компилируется и загружается. Видимо причина ее возникновения в том, что в библиотеке размер определен значением "[2*USB_BUFSIZE]" а в вашем примере и в скетче амперки "[USB_BUFSIZE]".
От проблемы избавлялся двумя методами: удваивая значения в коде; удалением "2*" из определения в библиотеке. Результат не поменялся от данных перестановок.
Подскажите может ли это влиять на результат перехвата нажатых клавиш?
Работая со скетчем приведенным на сайте амперки, получаю абсолютно идентичные проблемы (п.1 и п.2)
-----------------
3)Частота кварцевого резонатора на моей Arduino UNO 12MHz, а вы указываете следующее: "Можно взять любую 16-мгц ардуину". Подскажите могут ли мои проблемы с некорректным захватом заключаться в частоте? Либо я ошибаюсь и это не влияет на частотные хар-ки чипа?
Я использую:
*Arduino UNO 328P
*Среда arduino: 1.8.5
*Библиотека V-USB такая же как и у вас - zip с сайта амперки
*USB приемник + беспроводная клавиатура
*Подключен "всквозную", как у амперки на сайте. Клавиатура подключена к ПК и функционирует, при этом между ними я перехватываю сигнал.
К pin2 подключен D+
К pin4 подключен D-
В отчаянии пробовал даже обратное включение, конечно же, это не дало результата :)
Заранее благодарен за ответ!
selen_UNO, по поводу ошибок компиляции -учтите что это написано в 2015 году, возможно в новых версиях Arduino IDE корректно не будет компилироваться, лучше поставить старую, какую-нибудь 1.0.5 например. По поводу кварца -для кого я писал про 16 МГц ? В библиотеке половина кода на ассемблере, и всё жёстко привязано к таймингам.
"По поводу кварца -для кого я писал про 16 МГц ?"
да вот на этой же странице в вашем описании это указано в первом блоке текста. Все ясно, спасибо, буду пробовать воспроизводить условия. И попутный вопрос, лежит у меня парочка Arduino Nano, номиналы их резонаторов не разобрать из-за размера, есть ли способ, помимо осциллографа, определить их частоту?
selen_UNO, керамические резонаторы менее желательны из-за низкой точности. Частоту можно узнать разными способами, самый простой тут. По идее библу можно и на 12 МГц перенастроить, для этого необходимо поменять все упоминания о частоте в её дефайнах F_CPU, USB_CFG_CLOCK_KHZ может и ещё где-то что-то подправить.
Спасибо! Очень помогли. Буду последовательно исключать возможные несостыковки.
Установки частоты в библиотеке просто делают ее неработоспособной, никакие нажатия не отслеживаются, устанавливал 12МГц. При чем в самой библиотеке указано, что это оптимальнейшая частота для ее работы. Опробовано на 12-ти и 16-ти МГц Arduino UNO
В конечном итоге хоть что-то дала смена клавиатуры на проводную, причем одинаково работает на устройствах с разными частотами резонатора, но только с установленными в библиотеке 16МГц. Исходные настройки библиотеки от Амперки, дают возможность захвата кода клавиши, только срабатывания нестабильны и в 20% нажатий код клавиши отличается от ожидаемого у некоторых клавиш, либо нажатие никак не регистрируется вовсе(такая проблема у всех клавиш и довольно часто).
У вас так же работало с ньюансами по стабильности захвата или вопросов не было? Нет ли у вас соображений с чем связана такая нестабильность работы?
Но по большому счету это уже придирки. Главный вопрос теперь - как быть с универсальностью.
А именно вопрос подключения беспроводной клавиатуры, при ее подключении ни о каком захвате не может идти и речи, просто несется поток данных. Но я так понимаю этих моментов вы не касались во время сборки?
Думаю истина около документации по протоколам HID USB приемников, видимо пакеты устроены немного наче, но пока не могу найти ничего близкого к этой теме. Может библиотеку можно настроить под это дело? Там много опций около этой темы, но ни одна из них не дала результата на данный момент.
У вас так же работало с ньюансами по стабильности захвата или вопросов не было? Нет ли у вас соображений с чем связана такая нестабильность работы?
У меня совершенно никаких проблем. Качество перехвата зависит в первую очередь от точности частоты кварца, ну и качество монтажа тоже не последнюю роль играет. По поводу перенастройки на 12 МГц помимо дефайнов как я говорил может быть ещё что-то.
А именно вопрос подключения беспроводной клавиатуры, при ее подключении ни о каком захвате не может идти и речи, просто несется поток данных. Но я так понимаю этих моментов вы не касались во время сборки?
Как это не может идти речи? Никакой разницы. Программа перехватывает пакеты USB, ей безразразлично какими путями они туда попали -по воздуху или по проводу. На этом же принципе работают usb-шные KVM-свитчи. Соответссно никаких специальных настроек в программе делать не нужно.
Использование вашего скетча значительно снижает процент ошибок при перехвате, в сравнении со скетчем Амперки.
По поводу беспроводной - как есть.
Если со стабильностью еще можно поиграть меняя аппаратуру, то в случае с USB приемником байты сигналов клавиш, просто не на своем месте, их нет в обрабатываемом буфере. При чем проблема повторяется так же с переходником ps/2 - usb, который я использую для ps/2 клавиатуры.
Если вывести "незнакомое" нажатие, чтобы определить его шеснадцатиричный код, то в случае с проводной клавиатурой монитор порта чист и по нажатию, выдает код клавиши из KeyData[2]. Тот же код начинает сыпать значениями даже без нажатий клавиш при использовании беспроводной или ps/2 переходника. Прерывания срабатывают на служебную информацию.
Видимо из-за того, что это устройство клавиатура+мышь. Вот тут прошу вашего содействия, хотя бы идеями.
Вот интересный проект, как раз то, что я задумал в конечном итоге. Реализован конечно на другом чипе, но библиотека и настройки очень интересные и схожие. Так вот тут именно комбинированное USB устройство клав+мышь работает изначально. Правда автор указывает, что работа устройства ограничена USB 1.1 Low Speed
http://obruboff.ru/mini-kvm-for-usb-keyboard/
Я уже подвыдохся копать немного, но решение уже так близко :)
В итоге последняя проблема с USB приемником и ps/2 переходником. Есть ли у вас мысли по этому поводу?
selen_UNO, для начала добейтесь что-б стандартная проводная клавиатура перехватывалась без ошибок. Если с беспроводной после этого всё равно нет перехвата -возможно она работает в стандарте USB2, тогда нужно будет делать перехватчик на меге с аппаратным USB (подойдт ардуины леонардо и её вариации) . На гигтаймсе был пример.
PS: у Обрубова -та же библиотека, только более старая версия.
Leonardo обнаруживается ПК как HID-устройство. Она изначально без USB-host shield, не может работать как хост. В итоге перехват с Leonardo сведется к тому же подключению к портам 2 и 4 либо покупке USB-host shield, что можно сделать и с UNO
Или вы имели в виду другую схему?
selen_UNO, причём тут хост вообще? Хост -это инициатор обмена данных. Наш перехватчик ничего не инициирует, он сидит молча, на запросы хоста не отзывается, только слушает о чём другие говорят. Для МК с аппаратным USB есть хорошая библа -LUFA. Но примера перехватчика там нет, его придётся переделать из клавиатурного драйвера. Для начинающего это скорее всего неподъёмная задача, так что не знаю что вам посоветовать.