Если сломалась клавиша Fn…

Елена Бадло, Сергей Бадло (г. Запорожье)

<img src=»picture1.jpg» width=»400″ height=»258″ border=»0″ align=»right» hspace=»10″ alt=»»><i>Сломалась и сломалась, и что? В каких случаях эта клавиша может понадобиться? К примеру, ваш ребенок оторвал пару клавиш на ноутбучной клавиатуре и/или вы для удобства решили использовать внешнюю USB клавиатуру, на которой не предусмотрено клавиши Fn. Да что ж это вообще за клавиша такая?

Fn – это функциональная клавиша вкупе с другими обычными клавишами, позволяющая активировать и дезактивировать различные устройства в вашем ПК (ноутбуке или нетбуке), а это ни много ни мало: мышь и клавиатура (об этом чуть позже), тачпад, WLAN и Bluetooth-модули, встроенная WEB-камера в конце-концов и многое другое. Теперь прочувствовали возможные неудобства при вероятной неработоспособности столь «магической» клавиши? «Что делать, если вдруг… ?», – сегодня мы расскажем как можно обойти эту проблему.</i>

Немножко предыстории, или отвлечемся…

На самом деле вышеупомянутый вопрос тесно связан с другим вопросом, продолжающим непрестанно будоражить умы начинающих гаджетостроителей (создающих сотни однотипных тем на разного рода форумах), впервые столкнувшихся с электроникой и компьютерной техникой: «Как включить-выключить питание на USB-порту? Хочу управлять лампочкой (ракетницей, чайником, жалюзи, унитазом, …далее подставить по желанию) через USB, уже подключил два провода». Сразу осадим и спустим на землю таких фантазеров, без контроллера – никак (подробнее см. <a href=»http://usb.org»>http://usb.org</a>) и задача не так уж тривиальна, как может показаться на первый взгляд. Обусловлено это простой причиной – <i>управление питанием внутреннего USB концентратора (хаба) на материнской плате допускают единичные экземпляры, и уж тем более питанием отдельного порта. В большинстве случаев, даже при дезактивации той же флэшки, питание на нее через хаб продолжает поступать напрямую от блока питания (через защитную перемычку в виде SMD резистора нулевого сопротивления, своего рода предохранитель) и погасший индикатор (светодиод) на флэшке совсем не означает ее обесточивания. Потому как сам светодиод подключен к одному из портов контроллера флэшки и служит лишь индиктором обмена данными (чтения-записи), в очень редких случаях светодиод подключен к USB шине питания напрямую.</i> Вот так вот.

Впрочем, в таких случаях можно посоветовать следующие варианты:

Вариант 1.

Берете обычную, да-да, самую обычную б/у USB клаву:

Пациент для разборки

На рисунке: Распиновка контактов оптрона TLP621; Габариты оптрона

и используете ее LED индикаторы (CAPS, NUM, SCROLL), для удобства дальнейшей работы платку контроллера из клавиатуры можно выковырять. При желании, а даже желательно при работе на внешние нагрузки, обеспечить гальваническую развязку сигналов с помощью обычных оптронов, скажем тех же копеечных TLP621 [1] или его аналогов PC817:

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

А что, если понадобится управление более мощными силовыми цепями? Тогда рекомендуем использовать твердотельные оптореле [2] на основе оптосимосторов или силовых МОП:

Типовые схемы коммутации нагрузки с помощью оптосимистора и силовых МОП Fairchild Semiconductors [3]

Вы можете спросить: «Почему бы не использовать обычные электромагнитные  реле?». К сожалению, они имеют  множество  недостатков, как то: значительная инерционность, ограничивающая их применение в импульсных  схемах,  искрение и дребезг  контактов, относительно  малый  ресурс, да и стоимость малогабаритных реле, способных коммутировать большие токи на порядки выше современных твердотельных реле.

Программное управление самими светодиодами индикаторов можно осуществить средствами WinAPI через эмуляцию нажатий клавиш или используя прямой доступ через DeviceIOControl() после получения хэндла устройства по CreateFile() (последний способ позволит управлять свечением без эмуляции нажатий соответствующих клавиш на клавиатуре). Покажем на примере как управлять зажиганием светодиодов через эмуляцию клавиш, как наиболее простую в реализации и работающую в любых Win- системах. Прежде всего, заглянем в MSDN. Нам понадобятся следующие WinAPI функции:  keybd_event (для посылки нажатий и управления состоянием индикатора на клавиатуре),  MapVirtualKey (получение виртуальных скан-кодов клавиш),  GetKeyState (получение состояния клавиш),  CreateFile (для доступа к устройствам, файлам),  DeviceIoControl (для обмена с устройствами).

Синтаксис перечисленных нами функций выглядит следующим образом…

Keybd_event Function [4]

VOID WINAPI keybd_event(

  __in  BYTE bVk,

  __in  BYTE bScan,

  __in  DWORD dwFlags,

  __in  ULONG_PTR dwExtraInfo

);

Пример вызова: procedure keybd_event; external user32 name ‘keybd_event’;

MapVirtualKey Function [5]

UINT WINAPI MapVirtualKey(

  __in  UINT uCode,

  __in  UINT uMapType

);

function MapVirtualKey; external user32 name ‘MapVirtualKeyA’;</pre>

GetKeyState Function [6]

SHORT WINAPI GetKeyState(

  __in  int nVirtKey

);

Пример вызова: function GetKeyState; external user32 name ‘GetKeyState’;

CreateFile Function [7]

HANDLE WINAPI CreateFile(

  __in      LPCTSTR lpFileName,

  __in      DWORD dwDesiredAccess,

  __in      DWORD dwShareMode,

  __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,

  __in      DWORD dwCreationDisposition,

  __in      DWORD dwFlagsAndAttributes,

  __in_opt  HANDLE hTemplateFile

);

Пример вызова: CreateFile(‘\.PhysicalDrive0’,0,0,0,OPEN_EXISTING, 0, 0);

DeviceIoControl Function [8]

BOOL WINAPI DeviceIoControl(

  __in         HANDLE hDevice,

  __in         DWORD dwIoControlCode,

  __in_opt     LPVOID lpInBuffer,

  __in         DWORD nInBufferSize,

  __out_opt    LPVOID lpOutBuffer,

  __in         DWORD nOutBufferSize,

  __out_opt    LPDWORD lpBytesReturned,

  __inout_opt  LPOVERLAPPED lpOverlapped

);

Пример вызова: DeviceIoControl(handle, IOCTL_DISK_PERFORMANCE, 0, 0, @dp, SizeOf(DISK_PERFORMANCE),   lBytesReturned, 0).

В общем, ближе к телу…

Набросаем немножко кода?

Итак, для работы нам понадобится следующее:

  • <li>бесплатная IDE-среда разработки TurboDelphi-Lite портабле (флешечная версия) [9];
  • <li>любая клавиатура с индикаторами для измывательств :).

Прежде всего, запустите IDE среду TDL и создайте пустой проект. Реализуем управление на примере индикатора  ScrollLock. Для того, чтобы однозначно управлять состоянием индикатора, ведь его состояние заранее нам неизвестно (он может «гореть», а может и нет), нужно считывать его состояние. Это легко осуществить функцией GetKeyState(). А управление состоянием индикатора будем выполнять эмуляцией нажатий на клавишу &ltScrollLock&gt, так как будто вы это делаете сами. Для этого используем функцию Keybd_event(). Реализация подобного подхода представлена ниже:

{ проверка горит ли индикатор ScrollLock и управление }

procedure scroll(p: boolean);

begin

 if ((GetKeyState(145) = 1) and (not p)) or // включен и погасить

    ((GetKeyState(145) &lt&gt 1) and (p))         // выключен и зажечь

  then begin

   // нажать и отпустить ScrollLock

   keybd_event(145, MapVirtualKey(145, 0) , 0, 0);

   keybd_event(145, MapVirtualKey(145, 0), 38, 0)

 end

end;

Теперь жмакаете кнопку &ltF9&gt для компиляции проекта и получаете возможность управлять состоянием  индикатора ScrollLock, а значит и внешним гаджетом.

Вариант 2.

Можно использовать готовый аппаратный конвертор USB/UART типа FTDI <a href=»http://www.ftdichip.com или CP2102″>http://www.ftdichip.com или CP2102</a> <a href=»http://www.silabs.com/products/interface/usbtouart/Pages/default.aspx»>http://www.silabs.com/products/interface/usbtouart/Pages/default.aspx</a> (последние дешевле раза в три) и задействовать следующие пины из UART-интерфейса для управления светодиодами: CTS/DTR. Причем, тут вы получаете возможность даже приема дискретных сигналов через RTS/DSR без задействования какого-либо протокола, как если бы использовали линию RX/TX:

Схема подключения USB/UART конвертора CP2102

Вариант 3.

Собрать свое HID устройство на 8-каналов (тут ограничений по сути нет), эмулирующее протокол USB1.0 на микроконтроллере (см. рисунок 7):

USB.HID-гаджет для управления 8-ю дискретными выходами

Подобный вариант вы можете почерпнуть из статьи автора «Управление программой (устройствами) через браузер» в 18-м выпуске журнала «ПРОграммист» <a href=»http://raxp.radioliga.com/cnt/s.php?p=pro18m.pdf»>http://raxp.radioliga.com/cnt/s.php?p=pro18m.pdf</a> (раздел «Описание API библиотеки HIDOUT.dll»). Наглядно увидеть работу гаджета можно в следующем видеоролике http://www.youtube.com/watch?v=UJy170pAXGw.

Вариант 4.

Использовать готовое покупное электронное USB-реле с выходом(ами) типа «сухой контакт». В частности, Мастер-Кит выпускает подобное:

USB-реле

Ссылки специально не даем, дабы не считали рекламой :).

Так как же клавиша Fn? Даешь управление!

Впрочем, мы действительно отвлеклись. Какая же связь с управлением нашими устройствами, клавишей Fn и рассмотреными выше вариантами контроля по шине USB? Самая прямая. Все упомянутые в начале статьи устройства висят на шине USB, которая в свою очередь висит на шине PCI. Доступ к устройствам на PCI шине можно осуществить через использование методов SetupAPI. Стоп, не пугайтесь, мы не будем сегодня больше программировать, а воспользуемся не столь может быть известной широкому кругу обычных пользователей, но не менее полезной утилитой от Microsoft – Devcon* <a href=»http://support.microsoft.com/kb/311272/ru»>http://support.microsoft.com/kb/311272/ru</a>  (нет, это не название ежегодной конференции по разработке и тестированию ПО :)). DevCon (Device Console) – это утилита (включает 32- и 64-разрядную версии) с интерфейсом командной строки, которая используется в качестве альтернативы диспетчеру устройств, и реализующая эту самую обертку через SetupAPI. С ее помощью можно включать, выключать, перезапускать, обновлять, удалять и опрашивать отдельные устройства или группы устройств. А это не только камера, WLAN или Bluetooth-адаптер, тачпад или клавиатура, это и кардридер, Ethernet-карта, USB-хабы на материнской плате и т.д. Отсюда следует, что если прямое управление питанием на USB-порту не такая простая задача (как вы уже убедились выше), то активация-дезактивация устройств вполне по силам рядовому пользователю.

Так вот, основная идея реализации управления и замены функционала клавиши Fn состоит в использовании утилиты Devcon через параметры командной строки в ярлыках, созданных на рабочем столе и назначенными на них «горячими клавишами».

Использование утилиты DevCon

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

devcon32 help

Oтвет будет в формате:

devcon32 [-r] [-m:\<machine>] <command> [<arg>…]

Где:

-r – перезагрузить компьютер после выполнения команды, если это необходимо;

<machine> – имя компьютера назначения;

<command> – подлежащая выполнению команда (более подробно см. таблицу ниже);

<арг>… – один или несколько аргументов.

Таблица. Расшифровки команд DevCon

Практика. Управляем устройствами

Вот вам наглядные иллюстрации работы утилиты:

Вариант 1. Управляем внутренним USB хабом

Вызовите диспетчер устройств и раскройте ветку «Контроллеры универсальной последовательной шины USB»:

Теперь вызовите DevCon в командной строке и выберите поиск всех устройств на шине:

devcon32 findall @usb*

А теперь отключим один из двух корневых хабов через ‘disable’ . Обратите внимание на обязательное написание пути в двойных кавычках, если это касается корневых устройств:

devcon disable «@USBROOT_HUBнужный идентификатор»

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

Для того, чтобы обратно включить нужное устройство, просто введите команду ‘enable’:

devcon enable «@USBROOT_HUBнужный идентификатор»

Вариант 2. Управляем флэшкой

Как дезактивировать-активировать конкретное USB устройство, к примеру, флешку? Очень просто, по ее идентификаторам VID и PID. Воспользуемся уже знакомыми командами ‘disable’ и ‘enable’, однако вместо пути подставим идентификаторы устройства:

devcon32 disable USBVID_0930* @PID_653D

devcon32 enable USBVID_0930* @PID_653D

Текущее состояние устройства можно узнать, если ввести следующую команду (см. таблиу выше):

devcon32 status usb*

Вариант 3. Управляем блютуз-адаптером без использования клавиши Fn

Итак, мы подошли к заключительному этапу нашей работы – альтернативе комбинаций клавиш с клавишей Fn для управления устройствами. Выполним следующие шаги:

1. Создаем командные ярлыки

Переходим на рабочий стол и жмакаем правую кнопку мыши, в контекстном меню выбираем пункты «Ярлык/Создать»:

Создаем ярлыки на рабочем столе.

Далее в мaстере создания указываем командную строку для управления адаптером через утилиту DevCON.

Прописываем команду ‘disable’ в ярлыке.

На втором ярлыке прописываем команду ‘enable’ для активации.

2. Прописываем команды и назначаем «горячие клавиши» управления

На вкладке «Ярлык» в свойствах ярлыка уточняем путь к рабочему каталогу и выбираем любые свободную клавишу(ы) в качестве «глобальных», например мы выбрали <Alt>+<F11> для дезактивации блютуз-адаптера, а <Alt>+<F12> для активации:

Назначаем свободные «горячие клавиши» управления.

3. Собственно, проверяем управление

Перейдем к нашему диспетчеру устройств для наглядной визуализации состояния адаптера и последовательно нажмем комбинации клавиш <Alt>+<F11> и <Alt>+<F12>. Вуа-ля! Результатом станет дезактивация-активация адаптера, сопровождаемая системным звуком:

Посткриптум

По той же методике можно реализовать включение-отключение WEB-камеры, тачпада, мышки и клавиатуры (см. ресурсы к статье). Хотим предупредить, что во время тестов, скрипты (команды) дезактивации лучше создавать вместе со скриптами активации устройств, иначе при выключении той же клавиатуры с мышкой вы рискуете потерять возможность что-либо написать и даже нажать для их активации.Пусть это будет вашим домашним заданием. Ждем отзывов.

Ресурсы

  1. DATASHEET. Спецификация на оптрон TLP-621 http://www.datasheetcatalog.org/datasheet/toshiba/2236.pdf
  2. Николайчук. Схемы управления нагрузкой на переменном токе. – М.: Схемотехника, 2003, №4, с.25-26 http://www.twirpx.com/file/447673/
  3. Каталог оптореле Fairchild Semiconductors http://ru.farnell.com/jsp/search/browse.jsp?N=2026+203644&Ntk=PLS_MAN_BRAND_NAME&Ntt=fairchild+semiconductor&Ntх=
  4. MSDN. Keybd_event Function http://msdn.microsoft.com/en-us/library/ms646304(v=vs.85).aspx
  5. MSDN. MapVirtualKey Function http://msdn.microsoft.com/en-us/library/ms646306(v=vs.85).aspx
  6. MSDN. GetKeyState Function http://msdn.microsoft.com/en-us/library/ms646301(v=vs.85).aspx
  7. MSDN. CreateFile Function http://msdn.microsoft.com/en-us/library/aa363858(v=vs.85).aspx
  8. MSDN. DeviceIoControl Function http://msdn.microsoft.com/en-us/library/aa363216(v=vs.85).aspx
  9. Бесплатная IDE среда разработки TurboDelphi-Lite портабле http://www.andyaska.com/?act=download&mode=detail&id=34
  10. Загрузить пакет DevCon http://download.microsoft.com/download/1/1/f/11f7dd10-272d-4cd2-896f-9ce67f3e0240/devcon.exe
  11. Тестовый набор пакетных (batch) файлов для управления мышкой, флэшкой, концентратором http://raxp.radioliga.com/cnt/s.php?p=dev.zip

 

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *