Под катом будет рассказ о сборке и прошивке — даже дребезг логическим анализатором посмотрим
Итак, я принял решение собрать эту клавиатуру. Начать решил с компонентов — digispark(маленькая платка с attiny85 и обвязкой для usb, которую можно вставить прямо в компьютер) пусть отлавливает нажатия и эмулирует клавиатуру. Теперь кнопки — нормальных механических кнопок для клавиатуры у меня нет, а ждать не хочется, поэтому возьмем тактовые smd кнопки. Вот такие:
Определились с компонентами, теперь нарисуем лицевую панель, чтобы в дальнейшим распечатать на принтере. Размеры 45mm * 21mm, размеры накладок на кнопики 10mm* 10mm
Что-нибудь напишем вверху и внизу.
Получилось как-то так:
Следующая проблема — кнопки smd, значит их надо впаять на какую нибудь плату. Так как травить плату ради такого дела не имеет смысла — процарапаем текстолит буквой T:
Расстояние между центрами кнопок — 15mm. Припаяем их на импровизированную плату.
Паяем три провода. Когда кнопка будет нажата она будет замыкать один из крайних проводов на центральный.
Далее берем первый попавшийся кусок пвх пластика и приклеиваем на него нашу лицевую панель, а на кнопки клеим их насадки. Единственное что я не учел, так это то, что у тактовых кнопок сама часть которая давит на мембрану вращается. Если вы хотите улучшить конструкцию — используйте нормальные переключатели.
В итоге должно получиться то, что вы видели в начале статьи. Другой ракурс.
Три провода подключаем в digispark.
Схема «клавиатуры»
Далее нам надо заставить digispark притвориться клавиатурой и по нажатию на кнопку отправлять СTRL+C/CTRL+V.
Итак, нам надо отловить нажатие. Начнем с того, что если центральный провод подключить к +5V, а боковые провода подключить к пинам, настроенным на вход, то при нажатой кнопке, да, на пине будет 1, но при ненажатой пин будет ловить помехи и не получится отследить, что есть нажатие, а что помеха. Решается такая проблема удивительно просто — нужно подтянуть через резистор большого номинала ( десятки кОм) пины к земле. Открыв даташит на микроконтроллер можно увидеть, что внутри него можно включить подтяжку, но только к VCC(+ питания). Собственно, это не проблема — требуется всего лишь подключить центральный пин к GND(земле) и инвертировать логику работы.
Представить можно так:
Но есть еще одна проблема. Мы живем в неидеальном мире, где у кнопок механический контакт.
И он неидеален. А контроллер у нас быстрый — и так получается, что в момент переключения кнопка не моментально замыкается, а несколько миллисекунд ее сопротивление скачет — это называется дребезг. Из-за дребезга контроллер может решить, что кнопка нажата не один раз, а, например, 10. Вот иллюстрация этого явления из интернета:
Но так же неинтересно! Может у нас и нет никакого дребезга. Чтобы это узнать я расчехлил логический анализатор. Сейчас и посмотрим… Собираем тестовую установку — подтяжка 10 ком, 16 миллионов измерений в секунду
Видим что нажатие длилось 0,1176 ms
Приближаем момент отпускания кнопки(выделено красным)
Сбоку есть некоторые измерения «выбросов», а всего дребезг длился около 0,1435ms. Да я знаю, это мало, но стоит учесть что у меня кнопки только из ленты, контакты еще не успели окислиться или изменить форму. А со временем ситуация будет только ухудшаться. Как же бороться с дребезгом? Есть три основных способа:
- Триггер Шмидта + RC-цепь — позволяет получить идеальный сигнал
- RC-цепь — позволяет сделать из выбросов горку(плавно возрастающий сигнал)
Но у нас же целый микроконтроллер — и поэтому нам доступен 3 способ: задержки
Один из способов «в лоб» бороться с дребезгом это проверять, все еще нажата ли кнопка через время, заведомо большее дребезга. Если реализовывать через задержки то код будет блокирующий, но как это делается правильно можно посмотреть в сотнях статей про борьбу с дребезгом и arduino.
Итак, поняли мы, что кнопка нажата — что же дальше? Сказать компьютеру, что нажато CTRL+C/V.
Делается это с помощью стандартной библиотеки для digispark'a.
Итоговый код вышел таким:
#include "DigiKeyboard.h" // library for emulate keyboard
#define COPY 2 // copy button pin
#define PASTE 0// paste button pin
#define GND 1// center must be connected to ground
void setup() {
pinMode(COPY, INPUT); // set pin to input
digitalWrite(COPY, HIGH);// turn on pullup
pinMode(PASTE, INPUT);
digitalWrite(PASTE, HIGH);
pinMode(GND, OUTPUT); // set pin to output
digitalWrite(GND, LOW);// and set on pin GND
}
void loop() {
// if something COPY or PASTE clicked
if (!digitalRead(COPY) || !digitalRead(PASTE)) {
delay(30); // wait(debounce)
if (!digitalRead(COPY)) { // if copy still pressed send CTRL+C
DigiKeyboard.sendKeyStroke(KEY_C , MOD_CONTROL_LEFT);
delay(30);
}
else if (!digitalRead(PASTE)) {// if paste still pressed send CTRL+V
DigiKeyboard.sendKeyStroke(KEY_V , MOD_CONTROL_LEFT);
delay(200);
}
}
}
Вот такой проект за 3 часа у меня получился. Не бойтесь копировать чужой код!
200sx_Pilot
Избыточно, ИМХО.
Достаточно было бы одной клавиши.
Первое нажатие — КОПИРОВАТЬ, второе нажатие ВСТАВИТЬ.
Если хочется задействовать третий вывод — повесить на него светодиод зелёный.
Пусть загорается после операции КОПИРОВАТЬ, индицируя наличие данных в буфере обмена.
ZEvS_Poisk
А если надо в несколько мест вставить?
vasiaplaton Автор
Или скопировал не то.
TIMOHIUS
Ну например в линуксе, достаточно выделить текст, а потом в нужном месте нажать колесико мыши)
pproger
все верно. только не в линуксе, а в иксах. и не в любом месте, а там, где иксы явно управляют отрисовкой текста.
engine9
Удобнейшая фича.
200sx_Pilot
Длинное нажатие.
Данные вставляются но остаются в буфере.
Следующий вопрос?
algotrader2013
Не. Лучше нажал кнопку -> ctrl+c. Отпустил -> ctrl+v. Drag and drop на стероидах)
IgorPie
"Вставить" можно на ножную педаль (футсвич)