Виртуальная клавиатура своими руками

KeeBee. Изготовление с нуля собственной USB-клавиатуры

Несколько месяцев назад завершился мой проект по изготовлению USB-клавиатуры. Среди прочего, я выполнил дизайн электронных схем, спроектировал печатную плат, запрограммировал прошивку, сделал макет в CAD и произвёл сборку устройства. В результате получилась удобная клавиатура, которую я использую ежедневно и ласково называю KeeBee:


Клавиатура KeeBee в окончательном виде

Несколько целей проекта:

  1. Самостоятельное создание схемы.
  2. Написание прошивки клавиатуры.
  3. Узнать, как работает протокол USB.

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

Исследование и макет CAD

Мне очень нравятся минималистичные клавиатуры в стиле OLKB Planck и Preonic, которые за счёт ортолинейного расположения клавиш получаются очень компактными. Ещё я сразу знал, что хочу использовать переключатели Cherry MX Brown. Имея виду эти два компонента дизайна, я начал играть с ключевыми макетами в OpenSCAD. Это отличный инструмент с открытым исходным кодом, который работает скорее как язык программирования, чем WYSIWYG-интерфейс для мышки.

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

Дизайн верхней пластины:

После добавления клавиш:

Прототипирование платы и проектирование прошивки

В качестве основного микроконтроллера я выбрал STM32F042K6T6. Это около трёх долларов за чип, если брать от одной штуки. У него достаточно контактов для матрицы сканирования 69 клавиш (всего 32 контакта). Он работает на процессоре ARM Cortex M0 и содержит специальную USB-периферию для отправки USB-сигнала, не загружая этой задачей основной процессор. Я купил dev-плату Nucleo для прототипирования с этим чипом, прежде чем интегрировать его в дизайн своей печатной платы. Nucleo очень удобно легла на макетную плату и запиталась по USB.

Я разместил на макетной плате маленькую цепь на четыре клавиши, чтобы протестировать диодный контур, который я изучал. Игнорируя USB-сторону уравнения, на первом шаге требовалось заставить переключатели Cherry надёжно включать и выключать четыре соответствующих светодиода при нажатии кнопок.

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

Когда матрица удовлетворительно заработала, пришло время поработать над USB.

Встроенный цикл прошивки по сути такой:

  1. Просканировать все клавиши в матрице.
  2. Сопоставить расположение кнопок с соответствующими символами в выбранной раскладке (QWERTY, Dvorak и т. д.).
  3. Взять результат сопоставления, сгенерировать пакеты USB HID Report и отправить на периферийное устройство USB.
  4. Включить светодиод на клавиатуре, если клавиша нажата, выключить — если нет.

Из main.cc:

Компонент keyboard.SendReport фактически передаёт пакеты USB-хосту. Я упорно пытался заставить USB правильно работать. В этом протоколе много нетривиальных слоёв, которые требуют точного тайминга и правильной идентификации устройства. В итоге пришлось запустить Wireshark, чтобы прослушать все USB-пакеты, поступающие на мой ноутбук Linux и выяснить, где что потерялось. Поиск в интернете практически ничего не дал, на большинство вопросов отвечают примерно так: «Вероятно, ваше USB-устройство сломалось, нужно купить новое». Если вы на самом деле пытаетесь сконструировать USB-устройство, такие ответы не очень полезны. Мне оставалось только погрузиться в объёмные спецификации USB с большим количеством незнакомой терминологии.

Повозившись некоторое время, я всё-таки заставил клавиатуру с четырьмя клавишами корректно идентифицировать себя как USB HID (Human Interface Device) и все нажатия правильно передавались на ноутбук:

Регистрация в качестве USB-вендора и получение официального device id дорого стоит. Если у вас просто любительский проект, то придётся захватить идентификатор какого-нибудь похожего устройства. Я подумал, что “Gear Head” звучит круто, тем более они выпускают клавиатуры, поэтому выбрал их.

Читайте также:  Жар птица своими руками для начинающих

Схема и печатная плата

Получив более-менее работающую прошивку и рабочий прототип, пришло время составить схему и дизайн печатной платы в KiCAD и сделать реальную печатную плату. Когда я добился, что схема для 4 кнопок работает, осталась относительно простая задача соединить всё вместе:

После разработки схему и установки площадок для компонентов нужно произвести макет реальной печатной платы:

KiCAD умеет красиво рендерить будущую плату в 3D:

Есть много отличных учебников по KiCAD. Я начал с отличной видеосерии Getting to Blinkey 4.0 от Криса Гэммела, где он подробно разъясняет все этапы создания схемы светодиодного юлинкера в KiCAD от начала до конца.

Заказ печатной платы и компонентов

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

  1. Все компоненты из списка материалов: переключатели, светодиоды, диоды, микроконтроллеры и т. д. Я обычно заказываю такие штуки на DigiKey.
  2. Сама печатная плата. Довольно много сервисов готовы недорого изготовить вам прототип. У меня отличный опыт работы с OshPark и JLCPCB. Для этого проекта я выбрал JLCPCB из-за цены на такой размер, а ещё потому что они разрешили выбрать синее покрытие.
  3. Все остальные детали: крышки и прочее. Для этого проекта мой шурин помог лазером вырезать верхнюю и нижнюю клавиатурные пластины из 1/4” акриловых листов. Для остальных частей можно использовать онлайновые сервисы лазерной резки и 3D-печати, если нет доступа к оборудованию.

День, когда пришла посылка с платой, самый лучший:

JLCPCB очень доступный сервис. Этот дизайн с доставкой DHL из Китая обошёлся менее чем в $30, а весь процесс от загрузки файлов до прихода посылки занял чуть больше недели.

Шурин взял DXF-файлы из OpenSCAD и забросил их в лазерный резак:

Окончательная сборка

Получив все детали, я начал сборку. Первый шаг — сборка компонентов печатной платы: паяльник для больших электронных компонентов и паяльная станция для поверхностного монтажа маленьких компонентов, таких как микроконтроллер STM32.

Общее время сборки платы составило около трёх часов — большую часть заняла пайка 70 диодов и переключателей.

Я добавил хедер для JTAG-отладки, через который подключил JLINK Edu mini для прошивки микроконтроллера с помощью OpenOCD.

Затем пришло время окончательного тестирования и финальной сборки:

Сын решил, что это отличный поезд для его животных:

Итоги

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

Все файлы проекта опубликованы на GitHub, в том числе исходники прошивки, схемы печатных плат, список материалов и модели CAD.

Источник

64-клавишная матричная клавиатура для работы с Arduino

Мастер-самодельщик работает над проектом, который будет иметь встроенную клавиатуру и здесь есть проблема: как включить клавиатуру в прототип платы разработки? В проекте нельзя использовать USB-клавиатуру или существующую клавиатуру на базе Arduino, потому что клавиатура в реальном проекте подключена напрямую к микроконтроллеру, который обрабатывает все другие функции. Для решения проблемы мастер разработал 64-клавишную матрицу клавиатуры для прототипирования печатной платы.

Эта печатная плата не содержит никаких микросхем. Строки и столбцы матрицы клавиатуры подключаются непосредственно к разъемам контактов, так что клавиатуру можно подключить к Arduino или любому другому микроконтроллеру.

Мастер включил подробный код с комментариями. На клавиатуре 64 клавиши, включая модификаторы для shift, caps, ctrl, alt, fn и «special». Также есть шесть дополнительных клавиш, которые можно использовать для чего угодно. Функции каждой отдельной клавиши могут быть определены индивидуально.

Шаг первый: принцип работы матрицы клавиатуры
На этой клавиатуре 64 клавиши. Если бы мы подключили каждую из этих кнопок напрямую к плате разработки, нам потребовалось бы 64 контакта ввода-вывода. Это много выводов и больше, чем доступно на большинстве плат. Чтобы уменьшить количество разъемов до разумного числа, можно использовать матрицу клавиатуры, для которой требуется только количество выводов, равное квадратному корню (с округлением в большую сторону) из числа клавиш.

Читайте также:  Врачи ходят по своими руками

Матрица клавиатуры настроена таким образом, что каждый клавишный переключатель в строке подключен, и каждый клавишный переключатель в столбце подключен. Когда мы хотим увидеть, какие клавиши нажаты, мы «активируем» первую строку, а затем проверяем каждый столбец. Если активен конкретный столбец, мы знаем, что была нажата клавиша в этом столбце и строке 1. Затем мы деактивируем строку 1 и активируем строку 2, затем снова проверяем все столбцы. После того, как все строки были активированы, мы просто начинаем снова с первого ряда.

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

Для всех строк также обычно установлено значение HIGH, что предотвращает соединение выводов столбца с выводами строки независимо от того была, нажата кнопка или нет.

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

Матрица клавиатуры требует количества контактов, равного квадратному корню из числа клавиш, но в данной конструкции клавиатуры всего 11 контактов (а должно быть 16). Контактов 11 потому что в конструкции используется сдвиговый регистр 74HC595. Этот регистр позволяет использовать только три контакта ввода / вывода Arduino для управления до 8-ми выходных контактов. Эти три контакта позволяют отправить байт (восемь бит) в регистр сдвига, который устанавливает для своих восьми выходных контактов значение HIGH или LOW. Используя регистр сдвига для выводов выходной строки, мы экономим 5 полных выводов ввода / вывода.

Можно использовать регистр сдвига и для входных контактов, но здесь нужен другой тип регистра. Такой детали у мастера не было в наличии. К тому же использование сдвигового регистра для ввода также усложняет чтение столбцов и может вызвать проблемы с дребезгом клавиш.
schematic.pdf


Шаг второй: дизайн печатной платы
Теперь, когда есть понимание работы клавиатуры, мастер разрабатывает печатную плату в KiCAD. Он просто поместил символ кнопки и символ диода, затем скопировал и вставил их, пока не получил сетку из 64 ключей. Затем я добавил два символа разъемов 1×8: один для строк и один для столбцов. Одна сторона кнопок была соединена в столбцы, а другая сторона кнопок была соединена в ряды.

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

Обращаем особое внимание на номера контактов. У KiCAD есть проблема, когда номера выводов условного обозначения диода не совпадают с номерами выводов посадочного места. Это приводит к тому, что диоды находятся в обратном порядке, что является серьезной проблемой, учитывая их полярность. Чтобы решить эту проблему мастеру пришлось создать специальную посадочную площадку для диода с зеркальными местами контактов.

Создав схему и назначив символы, мастер перешел к разводке печатной платы. Контур платы был создан в Autodesk Fusion 360, экспортирован как DXF, а затем импортирован в KiCAD на слое Edge Cuts. Большая часть работы после этого заключалась в простом расположении кнопок так, чтобы их расположение было похоже на обычную клавиатуру.

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

Читайте также:  Вышитые узоры своими руками



Шаг четвертый: подключение клавиатуры к Arduino
Подключение выглядит сложно, но на самом деле все довольно просто.
Восемь перемычек идут от контакта столбца прямо к следующим контактам Arduino:
Column 1 > A0
Column 2 > A1
Column 3 > A2
Column 4 > A3
Column 5 > A4
Column 6 > A5
Column 7 > 5
Column 8 > 6
Затем устанавливаем сдвиговый регистр 74HC595 на макетную плату. Точка указывает на контакт 1. Регистр сдвига имеет два контакта, подключенных к 5 В, и два контакта, подключенных к земле.

Для подключения сдвигового регистра к Arduino нужно всего три провода:
Shift (Clock) 11 > 4
Shift (Latch) 12 > 3
Shift (Data) 14 > 2
По какой-то глупой причине выходные контакты сдвигового регистра расположены нелогично. Обратите особое внимание на схему распиновки сдвигового регистра при подключении их к выводам.
Row 1 > Shift (Q0) 15
Row 2 > Shift (Q1) 1
Row 3 > Shift (Q2) 2
Row 4 > Shift (Q3) 3
Row 5 > Shift (Q4) 4
Row 6 > Shift (Q5) 5
Shift 7 > Shift (Q6) 6
Shift 8 > Shift (Q7) 7
К контактам Arduino 0 и 1 ничего не подключается. Эти контакты используются для последовательного порта и вызывают конфликты.



Шаг пятый: прошивка
В статье приводится два кода. Первый старый, второй доработанный с учетом недостатков. Вводная часть работает для обоих кодов.
Все в коде имеет подробные комментарии. В основном, контакты настраиваются как входы и выходы. Основной цикл просто содержит функцию таймера. Каждые 5 мс он вызывает функцию сканирования клавиатуры. Эта функция вызывает отдельную функцию для установки регистра сдвига перед проверкой каждого столбца. Нажатые клавиши выводят свое значение в Serial.

Если вы хотите изменить то, что печатается при нажатии клавиши, просто измените Serial.print («_»); в операторе if, соответствующем условию. Например, вы можете установить, что будет печататься, когда вы удерживаете FN и нажимаете N. То же самое верно для любой другой клавиши с каждым модификатором.

Многие ключи вообще ничего не делают в этом коде, потому что он просто печатает в Serial. Это означает, что клавиша Backspace не действует, потому что вы не можете удалить из последовательного монитора — эти данные уже получены. Однако вы можете изменить это если хотите.
Эта клавиатура предназначена для создания прототипов более сложных проектов. Вот почему легко изменить ее функциональность. Если, например, вы хотите распечатать набранный текст на OLED-экране, вы можете просто заменить каждый Serial.print ( на display.print ( или все, что требуется для вашего конкретного дисплея). Инструмент Replace All в Arduino IDE отлично подходит для замены всех этих значений одним быстрым шагом.

Новый код полностью переписан и работает лучше, чем исходный код. В основном это было сделано для решения проблемы с алгоритмом, который не позволял вводить символы при каждом нажатии клавиши. Исходный код проверял, чтобы конкретная клавиша была нажата не последней . Это вызывало проблему, если удерживались 2 или более клавиши, что приводило к вводу чего-то вроде «fgfgfgfgfgfgfgfgfgfg». Это также не позволяло вводить одну и ту же клавишу снова и снова очень быстро, например, когда вы набираете две буквы m в слове «bummer.».
Новый код решает обе эти проблемы. Вместо того, чтобы отслеживать последнюю нажатую клавишу, устройство проверяет состояние всей клавиатуры и сравнивает его со всем состоянием клавиатуры в последнем цикле. Это означает, что цикл может выполняться намного быстрее, и можно очень быстро вводить один и тот же ключ снова и снова. Производительность значительно улучшена. Все символы также находятся в массивах вверху, поэтому можно легко их найти и изменить. Для каждого модификатора есть независимые массивы. Код также намного короче.
Единственным недостатком этого нового кода является то, что он использует больше динамической памяти, хотя и использует значительно меньше места для программы. На Arduino Uno теперь используется: 3532 байта (10%) пространства для хранения программ и 605 байтов (29%) динамической памяти.

Источник

Оцените статью