Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

64-клавишная матрица клавиатуры для прототипирования для Arduino

Компоненты и расходные материалы

Arduino UNO
× 1
1N4148 - быстрое переключение общего назначения
× 64
Тактильный переключатель, срабатывающий сверху
× 64
Заголовки контактов
× 1
Регистр сдвига 74HC595
× 1

Необходимые инструменты и машины

Паяльник (общий)

Приложения и онлайн-сервисы

IDE Arduino

Об этом проекте


<рисунок>

Обновление:я улучшил код, см. «Обновление» в конце.

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

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

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

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

Примечание относительно размера программы:

Код, который я предоставляю, довольно большой, потому что он вообще не использует какие-либо существующие библиотеки. Я написал этот код полностью с нуля, чтобы обеспечить необходимую мне настраиваемость. В Arduino UNO это будет использовать 9100 байтов (28%) пространства для хранения программ, а глобальные переменные используют 394 байта (19%) динамической памяти.

Мой код, вероятно, мог бы быть более эффективным, и там библиотеки и эскизы для клавиатур, безусловно, меньше, но это единственный способ, который я мог придумать, чтобы обеспечить полную гибкость для каждой клавиши с каждым модификатором. Также учитывается использование клавиатуры в реальном мире. Например, в моем коде нажатие клавиши Shift при включенном Caps Lock приведет к появлению строчной буквы, как и должно быть. По умолчанию нажатие клавиши FN при нажатии ESC ничего не делает. Но это поведение полностью настраивается, поэтому вы можете изменить его, как хотите.

Расходные материалы:

  • Специальная печатная плата
  • Тактильные кнопки мгновенного действия 6x6x5 мм (x64)
  • переключающие диоды 1N4148 (x64)
  • Разъемы 1x8, розетка или вилка (x2)
  • Регистр сдвига 74HC595
  • Перемычки
  • Макет
  • Arduino Uno или любая плата разработки для микроконтроллеров, совместимых с Arduino.

Шаг 1. Как работает матрица клавиатуры

<рисунок> <рисунок>

Зачем нужна матрица клавиатуры?

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

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

Как мы сканируем матрицу клавиатуры:

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

Микроконтроллер ATmega328P, используемый в Arduino UNO, не имеет встроенных резисторов, только подтягивающих резисторов. Итак, мы используем их. Подтягивающие резисторы подключают каждый входной контакт к 5 В, гарантируя, что они всегда показывают ВЫСОКИЙ уровень, пока не будет нажата кнопка.

Для всех строк также обычно установлено значение HIGH, что предотвращает соединение выводов столбца с выводами строки независимо от того, была нажата кнопка или нет. Но когда мы готовы проверить строку, мы можем установить для нее значение НИЗКИЙ . . Если нажать кнопку в этой строке, это обеспечит путь, по которому входной вывод будет прижат к земле, в результате чего в этом столбце теперь будет значение НИЗКОЕ . .

Итак, подведем итог:мы устанавливаем для строки значение LOW, а затем проверяем, какие выводы столбца теперь показывают значение LOW. Они соответствуют нажатым кнопкам. Этот процесс происходит очень быстро, поэтому мы можем сканировать всю клавиатуру много раз в секунду. Мой код ограничивает это значение до 200 раз в секунду, что уравновешивает производительность, подпрыгивание и отслеживание каждого нажатия клавиши.

Диоды, ореолы и одновременное нажатие клавиш n:

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

Сохранение выводов со сдвиговым регистром:

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

«Так почему бы не использовать сдвиговый регистр и для входных контактов?» ты спрашиваешь. Самый простой ответ заключается в том, что для ввода требуется другой тип сдвигового регистра, и у меня не было этого типа под рукой. Но использование сдвигового регистра для ввода также усложняет чтение столбцов и может вызвать проблемы с шумом и «подпрыгиванием». Достаточно сказать, что это головная боль, с которой мне не пришлось справляться в данном случае.

schematic.pdf

Шаг 2. Дизайн печатной платы

<рисунок> <рисунок> <рисунок>

Схематический дизайн

Теперь, когда вы понимаете, как работает матрица клавиатуры, моя печатная плата должна быть простой. Я разработал печатную плату в KiCAD (извините, судьи Eagle) и начал со схемы. Я просто поместил символ кнопки и символ диода, затем скопировал и вставил их, пока не получил сетку из 64 ключей. Затем я добавил два символа заголовка 1x8:один для строк и один для столбцов. Одна сторона кнопок была соединена в столбцы, а другая сторона кнопок была соединена в ряды.

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

Следы и номера контактов

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

Схема печатной платы

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

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

Производство печатных плат

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

Вот ссылка на файлы Gerber печатной платы:https://drive.google.com/file/d/10YriLLtghV0Sb84Wm ...

Шаг 3. Сборка печатной платы

<рисунок>

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

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

Шаг 4. Подключите клавиатуру к Arduino

<рисунок> <рисунок> <рисунок>

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

Восемь перемычек выйдут из заголовка столбца прямо на следующие контакты Arduino:

  • Столбец 1> A0
  • Столбец 2> A1
  • Столбец 3> A2
  • Столбец 4> A3
  • Столбец 5> A4
  • Столбец 6> A5
  • Столбец 7> 5
  • Столбец 8> 6

Затем поместите сдвиговый регистр 74HC595 на макетную плату между средним разрывом. Обратите внимание на ориентацию чипа! Точка указывает на контакт 1

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

Для подключения сдвигового регистра к Arduino нужно всего три провода. Это:

  • Shift (Часы) 11> 4
  • Shift (защелка) 12> 3
  • Shift (данные) 14> 2

По какой-то глупой причине выходные контакты сдвигового регистра расположены нелогично. Обратите особое внимание на схему распиновки сдвигового регистра при подключении их к выводам вашей строки. Это:

  • Ряд 1> Shift (Q0) 15
  • Строка 2> Сдвиг (Q1) 1
  • Строка 3> Сдвиг (2 квартал) 2
  • Ряд 4> Shift (Q3) 3
  • Строка 5> Сдвиг (4 квартал) 4
  • Строка 6> Shift (Q5) 5
  • Shift 7> Shift (Q6) 6
  • Shift 8> Shift (Q7) 7

Ничего не подключено к контактам Arduino 0 или 1, потому что они также используются для последовательного порта и вызывают конфликты.

Шаг 5. Прошивка кода Arduino

<рисунок>

Запрограммируйте Arduino с помощью кода, приведенного здесь. В этом нет ничего особенного, просто загрузите код, как и в любом другом проекте Arduino.

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

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

Многие ключи вообще ничего не делают в этом коде, потому что он просто печатает в Serial. Это означает, что клавиша Backspace не действует, потому что вы не можете удалить из последовательного монитора - эти данные уже получены. Однако вы можете использовать это изменение, если хотите.

Использование клавиатуры в собственных проектах

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

Спасибо, что прочитали это, и я надеюсь, что эта клавиатура поможет вам в ваших проектах!

ProtoKeyboardV1.1-Shifted.ino



Обновление от 30.01.21:

Этот новый код полностью переписан и работает лучше, чем исходный код. В основном это было сделано для решения проблемы с моим алгоритмом, который не позволял вводить символы при каждом нажатии клавиши. Исходный код проверял, не был ли конкретный ключ последним клавишу, которую нужно нажать. Это вызывало проблему, если удерживались 2 или более клавиши, что приводило к вводу чего-то вроде "fgfgfgfgfgfgfgfgfgfg". Это также не позволяло вам вводить одну и ту же клавишу снова и снова очень быстро, например, когда вы набираете две буквы m в слове «облом».

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

Единственным недостатком этого нового подхода является то, что он использует больше динамической памяти, хотя и использует значительно меньше места для программы. На Arduino Uno теперь используется:3532 байта (10%) пространства для хранения программ и 605 байтов (29%) динамической памяти.

В качестве дополнительного бонуса этот код также хорошо работает на быстрых микроконтроллерах, таких как ARM Cortex-M4. Интервальный таймер для проверки клавиатуры находится в микросекундах, поэтому он будет работать одинаково на любой плате. Вы также можете легко настроить частоту проверки клавиатуры. По умолчанию он запускает один цикл каждые 500 микросекунд. Для проверки клавиатуры требуется 8 циклов, что в сумме составляет 4000 микросекунд (4 миллисекунды или 250 раз в секунду), хотя это может занять больше времени, если микроконтроллер недостаточно быстр для столь быстрого выполнения кода.

Код

  • ProtoKeyboardV1.1-Shifted.ino
  • ProtoKeyboardV1-Bits.ino
ProtoKeyboardV1.1-Shifted.ino Arduino
 Нет предварительного просмотра (только загрузка). 
ProtoKeyboardV1-Bits.ino Arduino
Обновленный код Arduino
 / * Sketch for Prototyping Keyboard V1.2 * by Cameron Coward 1/30/21 * * Протестировано на Arduino Uno. Требуется специальная печатная плата * и сдвиговый регистр 74HC595. * * Подробнее:https://www.hackster.io/cameroncoward/64-key-prototyping-keyboard-matrix-for-arduino-4c9531 * / const int rowData =2; // регистр сдвига Вывод данных для строкconst int rowLatch =3; // сдвиговый регистр Штифт защелки для строкconst int rowClock =4; // регистр сдвига Вывод часов для строк // это выводы нашего столбца. Выводы 0 и 1 не используются, // потому что они вызывают проблемы (предположительно из-за того, что они TX и RX) const int colA =A0; const int colB =A1; const int colC =A2; const int colD =A3; const int colE =A4; const int colF =A5; const int colG =5; const int colH =6; // shiftRow - это требуемый байт регистра сдвига для каждой строки, rowState будет содержать нажатые клавиши для каждой rowconst byte shiftRow [] ={B01111111, B10111111, B11011111, B11101111, B11110111, B11111011, B11111101, B11111110}; byte rowState [] ={B00000000, B00000000, B00000000, B00000000, B00000000}, B0000RUB0000; ] ={B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000}; // коды ASCII для клавиш без нажатых модификаторов. Модификаторы имеют значение NULL (0), // потому что мы будем проверять их отдельно, и их значения не должны выводиться. Const char key [] ={0, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 0, 9, 113, 119, 101, 114, 116, 121, 117, 105, 111, 112, 91, 93, 92, 7, 97, 115, 100, 102, 103, 104, 106, 107, 108, 59, 39, 0, 0, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0}; // коды ASCII для клавиш с нажатой клавишей Shift И активны capsconst char capsShiftKey [] ={0, 33, 64, 35, 36, 37, 94, 38, 42, 40, 41, 95, 43, 0, 9, 113, 119, 101, 114, 116, 121, 117, 105, 111, 112, 123, 125, 124, 7, 97, 115, 100, 102, 103, 104, 106, 107, 108, 58, 22, 0, 0, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0}; // коды ASCII для клавиш с нажатой клавишей shift. Const char shiftKey [] ={0, 33, 64, 35, 36, 37, 94, 38, 42, 40, 41, 95, 43, 0, 9, 81, 87, 69, 82, 84, 89, 85, 73, 79, 80, 123, 125, 124, 7, 65, 83, 68, 70, 71, 72, 74, 75, 76, 58, 22, 0, 0, 9 0, 88, 67, 86, 66, 78, 77, 44, 46, 47, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0}; // коды ASCII для клавиши с нажатой ctrl. const char ctrlKey [] ={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0}; // коды ASCII для клавиш с нажатой spcl .const char spclKey [] ={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // коды ASCII для клавиш с нажатым alt. Const char altKey [] ={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // коды ASCII для клавиш с нажатой fn. Const char fnKey [] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // коды ASCII для ключей с заглавными буквами activeconst char capsKey [] ={0, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 0, 9, 81, 87, 69, 82, 84, 89, 85 , 73, 79, 80, 91, 93, 92, 7, 65, 83, 68, 70, 71, 72, 74, 75, 76, 59, 39, 0, 0, 90, 88, 67, 86, 66 , 78, 77, 44, 46, 47, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0}; long previousKeyboardMicros =0; // сохранит время последней проверки клавиатуры // следующие переменные являются длинными, потому что время, измеренное в миллисекундах, // быстро станет большим числом, чем может быть сохранено в int.long keyboardInterval =500; // интервал проверки клавиатуры (микросекунды) int rowToCheck =0; // Мы проверяем одну строку за цикл checkKeyboard (), это в сочетании с keyboardInterval // дает shiftRegister время для полного обновления между проверками строкbool caps =false; // включен ли Caps Lock? bool shift =false; // нажат ли сдвиг влево или вправо? bool capsShift =false; // активны ли сдвиг И заглавные буквы? bool ctrl =false; // нажата ли клавиша ctrl? bool spcl =false; // нажата ли клавиша spcl? bool alt =false; // нажата клавиша alt? bool fn =false; // нажата ли функциональная клавиша? void setup () {Serial.begin (9600); // настраиваем все выводы столбца как входы с внутренними подтягивающими резисторами pinMode (colA, INPUT_PULLUP); pinMode (colB, INPUT_PULLUP); pinMode (colC, INPUT_PULLUP); pinMode (colD, INPUT_PULLUP); pinMode (colE, INPUT_PULLUP); pinMode (colF, INPUT_PULLUP); pinMode (colG, INPUT_PULLUP); pinMode (colH, INPUT_PULLUP); // выходы, необходимые для управления регистром сдвига 74HC595 pinMode (rowLatch, OUTPUT); pinMode (rowClock, ВЫХОД); pinMode (rowData, ВЫХОД); updateShiftRegister (B11111111); // убеждаемся, что сдвиговый регистр начинается с ВЫСОКОГО уровня} void loop () {mainTimer ();} void mainTimer () {unsigned long currentMicros =micros (); // сколько микросекунд работает Arduino? if (currentMicros - previousKeyboardMicros> keyboardInterval) {// если время, прошедшее с момента последней проверки, превышает интервал // сохранить время последней проверки клавиатуры previousKeyboardMicros =currentMicros; checkKeyboard (); // проверяем все ключи и распечатываем результаты в серийный номер}} void updateShiftRegister (byte row) {// эта функция устанавливает регистр сдвига в соответствии с байтом, который был передан ей digitalWrite (rowLatch, LOW); // устанавливаем низкий уровень защелки, чтобы мы могли записать сразу весь байт shiftOut (rowData, rowClock, MSBFIRST, row); // записываем этот байт digitalWrite (rowLatch, HIGH); // установить высокий уровень защелки, чтобы регистр сдвига оставался стабильным до следующего изменения} void checkKeyboard () {// установить в регистре сдвига значение байта текущей строки из байтового массива shiftRow [] updateShiftRegister (shiftRow [rowToCheck]); // Проверяем каждый столбец if (digitalRead (colA) ==LOW) {bitSet (rowState [rowToCheck], 0); } еще {bitClear (rowState [rowToCheck], 0); } если (digitalRead (colB) ==LOW) {bitSet (rowState [rowToCheck], 1); } еще {bitClear (rowState [rowToCheck], 1); } если (digitalRead (colC) ==LOW) {bitSet (rowState [rowToCheck], 2); } еще {bitClear (rowState [rowToCheck], 2); } если (digitalRead (colD) ==LOW) {bitSet (rowState [rowToCheck], 3); } еще {bitClear (rowState [rowToCheck], 3); } если (digitalRead (colE) ==LOW) {bitSet (rowState [rowToCheck], 4); } еще {bitClear (rowState [rowToCheck], 4); } если (digitalRead (colF) ==LOW) {bitSet (rowState [rowToCheck], 5); } еще {bitClear (rowState [rowToCheck], 5); } если (digitalRead (colG) ==LOW) {bitSet (rowState [rowToCheck], 6); } еще {bitClear (rowState [rowToCheck], 6); } если (digitalRead (colH) ==LOW) {bitSet (rowState [rowToCheck], 7); } еще {bitClear (rowState [rowToCheck], 7); } // устанавливаем все выводы регистра сдвига в HIGH, это сохраняет значения от "утечки" до следующего цикла updateShiftRegister (B11111111); rowToCheck =rowToCheck + 1; // переходим к следующей строке // после проверки 8-й строки, проверяем состояния (нажатия кнопок) и затем начинаем заново с 1-й строки if (rowToCheck> 7) {checkPressedKeys (); rowToCheck =0; }} void checkPressedKeys () {// проверяем, нажата ли какая-либо клавиша Shift if (bitRead (rowState [5], 1) | bitRead (rowState [6], 4)) {shift =true; } еще {сдвиг =ложь; } // проверяем, нажата ли какая-либо клавиша ctrl if (bitRead (rowState [6], 5) | bitRead (rowState [7], 3)) {ctrl =true; } еще {ctrl =false; } // проверяем, нажата ли какая-либо клавиша spcl if (bitRead (rowState [6], 6) | bitRead (rowState [7], 2)) {spcl =true; } еще {spcl =false; } // проверяем, нажата ли какая-либо клавиша alt if (bitRead (rowState [6], 7) | bitRead (rowState [7], 1)) {alt =true; } else {alt =false; } // проверяем, нажата ли клавиша FN if (bitRead (rowState [7], 4)) {fn =true; } else {fn =false; } // проверка колпачков активна и Shift нажата if (shift ==true &&caps ==true) {capsShift =true; } еще {capsShift =false; } for (int i =8; i> =0; i--) {// перебираем каждую строку for (int j =7; j> =0; j--) {// перебираем каждый бит в этой строке bool newBit =bitRead (rowState [i], j); // проверяем состояние этого бита bool prevBit =bitRead (prevRowState [i], j); // проверяем предыдущее состояние этого бита if ((newBit ==1) &&(prevBit ==0)) {// разрешает нажатие кнопки, только если состояние изменилось на true int thisChar =(i * 8) + j; // вычисляем, какую позицию в массиве символов выбрать if (capsShift ==true) {processKey (capsShiftKey [thisChar]); } иначе, если (shift ==true) {processKey (shiftKey [thisChar]); } иначе, если (ctrl ==true) {processKey (ctrlKey [thisChar]); } иначе, если (alt ==true) {processKey (altKey [thisChar]); } иначе, если (spcl ==true) {processKey (spclKey [thisChar]); } иначе, если (fn ==true) {processKey (fnKey [thisChar]); } иначе, если (caps ==true) {processKey (capsKey [thisChar]); } еще {processKey (ключ [thisChar]); }} если (newBit ==1) {bitSet (prevRowState [i], j); // устанавливаем предыдущее состояние бита в истинное значение, если нажата клавиша} else {bitClear (prevRowState [i], j); // устанавливаем предыдущее состояние бита в false, если клавиша не нажата, чтобы ее можно было нажать снова}}}} void processKey (char gotKey) {if (gotKey ==7) {// аналогичным образом проверяем наличие специальных функций как заглавные буквы (добавить новые операторы «else if») caps =! caps; } else {Serial.print (полученный ключ); // если char не соответствует специальной функции, просто распечатайте этот char}} 

Изготовленные на заказ детали и корпуса

Загрузите весь файл .zip в службу изготовления печатных плат keyplots_4xipOSLHzg.zip

Схема


Производственный процесс

  1. ЖК-панель с Arduino для симулятора полета
  2. Переключатель / светодиодная панель с Arduino для FS2020
  3. Arduino + светодиоды + MIDI-клавиатура + MuseScore =Piano Tutor
  4. Управление светодиодной матрицей с помощью Arduino Uno
  5. Мониторинг температуры SMART для школ
  6. 8-битная библиотека портов ввода-вывода для Arduino
  7. TFT Shield для Arduino Nano - запуск
  8. Изолированный аналоговый вход для Arduino
  9. Калькулятор Arduino
  10. Робот для супер-крутой навигации внутри помещений