Использование 8-битных портов в качестве 8-битной переменной ввода-вывода (при использовании USB, I2C, SPI и последовательного порта) — клавиатура
Я ищу HW.
Я хотел бы сделать клавиатуру с расширенными функциями (подсветка RGB, макросы, запрограммированные профили и т. д.), управляемую небольшим микроконтроллером (Arduino Micro Pro или чем-то подобным).
Для поддержки связи необходимо использовать I2C и SPI (для дисплея и других устройств), использовать USB (для связи с ПК ) и используйте Serial для связи с другими Arduino/MCU.
Основной функцией будет сканирование матрицы клавиатуры (от 8x8 до 16x8 в максимальном варианте). В матрице будут использоваться диоды для NKRO (не ореол, возможна любая комбинация клавиш).
Было бы очень приятно иметь HW, где я мог бы использовать 3 полных порта в качестве ввода (или в качестве вывода) с преимуществом чтения/записи их с помощью только одной инструкции сборки для 8-битных манипуляций, чтобы не циклически перебирать массив контактов и манипулировать каждым из них независимо (digitalRead/digitalWrite, которые используют множество инструкций для определения портов и контактов, а затем объединяют их вместе для получения одной 8-битной переменной). Что-то вроде:
byte dataout,datain1,datain2;
PORT_A=dataout;
datain1=PORT_B;
datain2=PORT_C;
Кто-нибудь знает, есть ли такое недорогое MCU и какого оно типа?
На типичном Arduino каждый порт «загрязнен» некоторыми важными коммуникационными контактами, поэтому ни один из них не может использоваться как полноценный 8-битный ввод-вывод.
Второй вопрос: есть ли причина, по которой наиболее часто используемые коммуникационные контакты распределены по разным портам и не собираются на одном порту, а другие порты остаются пригодными для использования с полным 8-битным GPIO?
Спасибо за все ответы.
@gilhad, 👍-1
Обсуждение2 ответа
Лучший ответ:
Я бы выбрал Mega2560. До 86 IO, если вы используете плату, которая разбивает все контакты IO, в противном случае 70 в версии Arduino. Уделив немного внимания физическому отображению контактов чипа на плате, вы можете иметь несколько полных 8-битных портов, а также использовать SPI, I2C и последовательный порт через один из 4 UART. Я бы рекомендовал оставить Tx(0)/Rx(0) свободными для связи с ПК через USB-адаптер для загрузки/отладки кода. Tx1/Rx1, Tx2/Rx2, Tx3/Rx3 свободны для связи уровня 0/5 В или других уровней через USB-адаптер, адаптер RS232 и т. д.
Расширитель MCP23S17 (spi) с CS является хорошим расширением (16 настраиваемых входов/выходов). Это должно сделать это!
- Как сбросить или отформатировать Arduino?
- Разница между этими двумя платами NodeMCU?
- Управление дисководом гибких дисков с помощью Arduino
- Esp8266 Vin контакт
- Отправка ИК-сигналов (NEC) с помощью Arduino
- Помогите с идентификацией деталей стартового комплекта Arduino с aliexpress.
- Какие диоды использовать в матричном вводе кнопок/клавиш? (Изготовление игровой клавиатуры)
- Как работает последовательная связь на Arduino?
Кажется, в основном проблема в том, сколько контактов вам нужно для вашей клавиатуры. Вы не указали, сколько пинов вам нужно. Кажется, вам нужен MCU с родной поддержкой USB., @chrisl
Дайте определение "недорого"..., @Majenko
Лично я фанат PIC32. Он имеет 16-битные порты ввода-вывода, а не 8-битные (хотя не все контакты заняты на всех портах), поэтому вы можете
LATE = dataout; datain = PORTB;
например., @Majenko@chrisl Да, я хочу сделать USB-клавиатуру для ПК (а также использовать ее для других целей, поэтому нужно также поддерживать I2C, SPI и UART). Кроме этого, я хочу для клавиатуры 8+8 контактов (для матрицы 64 клавиши) или лучше 8+16 контактов (для полной клавиатуры с дополнительными клавишами, такими как макросы, мультимедиа, переключатели раскладки и т. д.), @gilhad
Лично я не вижу необходимости сохранять какие-то инструкции. В основном вам нужны комбинированные порты для достижения высокой производительности, но клавиатура обычно управляется человеком, что ОЧЕНЬ медленно по сравнению со сканированием всех клавиш MCU. Или вам нужна микросекундная задержка?, @Michel Keijzers
Вы можете использовать сдвиговые регистры (как с параллельным входом, так и с последовательным выходом), подключенные к шине SPI. Затем вы можете передать один или два байта по SPI, что очень быстро (тактовая частота 8 МГц даже на самых простых Arduino). Вы можете последовательно подключить два сдвиговых регистра, если вам нужно 16 входов. Как уже упоминалось, вам не нужно беспокоиться о скорости человеческих устройств ввода., @tttapa
@Majenko недорогой - я использую несколько Arduinos от aliexpress, около 2-3 евро каждый, и в худшем случае я могу добавить регистр сдвига за несколько центов, чтобы увеличить количество выводов и иметь возможность выполнять работу. В магазине Arduino такие же стоят около 8-20$. Оба работают хорошо. Так что что-то в этом диапазоне (скажем, 1-30$?, а не 100+$), @gilhad
tttapa+MichelKeijzers: Я знаю это, но я также думал о некоторой «изящности кода», например, зачем делать 8 циклов примерно по 50 инструкций каждый для того, что можно было бы сделать всего двумя инструкциями (то есть примерно в 200 раз меньше). Я знаю, что я все равно могу сделать это как-нибудь и все остальные задачи тоже как-нибудь (например, USB и манипуляции с 20+ WS2812B Светодиодные и OLED-дисплеи и гниют. encoder и кто знает, с чем еще я пришел), чтобы не быть чрезмерно медленным, но вместе он считается быстрым, и я хотел бы на этот раз сделать его эффективным, а не просто нагромождать библиотеку на библиотеку и компенсировать ненужную неэффективность более быстрым HW., @gilhad
Вы можете прочитать весь порт и применить маску, чтобы остались только те биты, которые вас интересуют. Чуть больше кода, но быстрее, чем 16 digitalReads. Но я рассчитываю, что вам понадобится 32 контакта GPIO плюс USB, поэтому я думаю, что это проблема, на которой вы должны сосредоточиться., @Gerben
@Majenko, есть какой-нибудь PIC32, который вы бы порекомендовали мне для начала? Мне достаточно иметь USB и побитый AVR32U4, чтобы попробовать :) (Так что, вероятно, какой-нибудь более дешевой модели будет более чем достаточно), @gilhad
@Gerben для моей текущей попытки это 2 (дисплей I2C + связь PD0-1) + 4 SPI (PB0-3) + USB (D + D-) + 2 последовательных (PD2-3) + 16 GPIO (PB4-7, PD4) -7, PC6-7,PF0-1,4-7 ) - из этих 16 GPIO я бы использовал 8 как входы, 1 для светодиодов, 3 как выходы для декодера 3-в-8 (т.к. только 1 ряд активен на каждом время) и иметь 4 свободных, или я бы использовал 7 как выходы для матрицы 8x7, которая работает на обычной клавиатуре (128 клавиш, без внешнего чипа)., @gilhad
@gilhad Вы можете сделать хуже, чем Fubarino SD, @Majenko
@Majenko спасибо :) Выглядит интересно :) Попробую :), @gilhad
Если вы используете матрицу клавиш, разделенную диодами, я не вижу способа нажимать две или три клавиши одновременно, если вы не реализуете алгоритм защиты от ореолов в своем контроллере. Для работы захват штифтов должен быть очень быстрым. Почти сразу. И микроконтроллер должен быть достаточно быстрым, чтобы найти даже очень короткую задержку нажатия двух-трех клавиш. Если есть задержка, мы, предположим, что человек нажал клавиши. Это анти-призрак. Дорогостоящим способом избежать фантомных ключей является чтение всех ключей по отдельности в цепочку сдвиговых регистров. Или создайте ЦАП с цепочкой резисторов и прочитайте аналоговое значение. Один канал = 10 бит, @Peter Paul Kiefer
Чтобы ответить на ваш второй вопрос: установка контактов зависит от внутренней компоновки чипа. Легче иметь функциональные группы в своих собственных блоках, например, тактовая логика и регистры сдвига. Производитель выбирает положение штифта таким образом, чтобы проводка золотых проводов была максимально короткой, а также чтобы провода не пересекались., @Peter Paul Kiefer
@PeterPaulKiefer Ввод ключевой матрицы читается таким образом, что вы прикрепляете сигнал к одной строке, а затем читаете все столбцы, чтобы увидеть, есть ли сигнал. Если он есть, то нажата клавиша пересечения строки и столбца. Затем продолжайте с другой строкой, и после того, как вы проверите все строки, вы знаете, какие клавиши нажаты. Двоение происходит, если нет диодов и пользователь нажимает клавиши на 3-х пересечениях, образующих прямоугольник. Тогда даже для ненажатого крестика есть сигнал, так как он проходит по остальным 3 и обнаруживается "призрачная клавиша", так как мы видим там сигнал, даже если клавиша не нажата. Тут никакая скорость не поможет., @gilhad
Если диоды ЕСТЬ, то нажатие клавиши 3 не освобождает место для клавиши 4. так как диоды не позволяют сигналу свободно перемещаться в другие ряды. Даже медленный mcu может прочитать это безопасно (пока он делает это быстрее, тогда человек освобождает клавиши - скажем, за 0,1 с = вечность для mcu. Более быстрый mcu может получить более точное время нажатия, не более того). Здесь тоже не нужен специальный алгоритм. Обычная матрица работает нормально. См. также этот ответ: https://arduinoprosto.ru/q/66691/what-kind-of-diodes-i-should-use-in-buttons-keys-matrix-input-making-gaming-k/66710 №66710, @gilhad
Было поздно, я устал, извините, я забыл «нельзя»: я хотел написать: «Если вы не используете ключевую матрицу с диодным разделением, ....». Вы правы, что вам нужно нажать как минимум 3 клавиши, чтобы получить эффект призрака. И, естественно, две из нажатых клавиш должны находиться в строке, которая питается «призрачно» от третьей нажатой клавиши. Mea culpa, думать во время письма полезно. ;-) Клавиатуры я, кстати, уже сделал, это не основное мое дело, но время от времени... . Им приходится работать в суровых условиях. Иногда по каким-то причинам мне не разрешают размещать диоды в ключевой матрице., @Peter Paul Kiefer
Один из этих проектов требовал, чтобы я позволял пользователю нажимать максимум четыре клавиши из шестидесяти четырех, и мне не разрешалось использовать диоды. В конце концов мы решили эту проблему, используя 16-битный регистр сдвига. Мы запитывали строки и считывали столбцы, и нам приходилось обрабатывать фантомные ключи. Мы использовали алгоритм, который в изученной нами литературе называется алгоритмом защиты от ореолов. Это проверяет, приходят ли сигналы нажатых клавиш достаточно быстро, чтобы интерпретировать их как фантомный сигнал, или действительно ли пользователь нажимал клавиши., @Peter Paul Kiefer
Мы не проверяли, насколько быстро пользователь отпускал клавишу, мы проверяли очень быстрое время, когда мощность переходит от одной строки к «призрачной» строке. Чем меньше проверяемые интервалы времени, тем надежнее распознавание ключей. И что вы мечтаете об испытаниях в наносекундном масштабе. Но даже с этим алгоритмом чтение было ненадежным, потому что иногда мы были недостаточно быстры или клавиши нажимались в неудачном порядке. Мы определяем нажатые пользователем клавиши как призрачные. Затем мы попытались собрать ЦАП на основе резисторов. с 7 каналами для чтения 64 ключей. Это отлично работает, но не удалось в производстве., @Peter Paul Kiefer
Он вышел из строя из-за сильных электромагнитных помех. И аналоговые входы стали ненадежными. В конце концов мы капитулировали и использовали четыре из шестнадцати битных регистров сдвига для чтения каждого ключа отдельно. Это была длинная история короткого комментария выше. Я не стал учить вас, как работают клавиатуры. Я просто хочу показать вам, что мы сделали, чтобы использовать это для ваших решений. Я не носитель английского языка. На самом деле мой английский очень плохой. Поэтому я не осознавал, что допустил некоторые ошибки, и не писал с той точностью, с которой писал бы, если бы писал тексты на немецком языке. Но я обещаю, я буду практиковаться, @Peter Paul Kiefer
@PeterPaulKiefer Да, «не надо» иногда может иметь большое значение :) Мой английский тоже далек от совершенства (4. выученный язык) - и я из Чехии. Ваш ответ смутил меня, поэтому я пошел на более подробное объяснение. В конце концов, между нами нет никаких разногласий :), @gilhad
Да все верно ! И забыл: спасибо, что указали мне на ошибки. ........ И есть еще одно но. Вы написали, что хотите подключить клавиатуру по USB (помимо других способов). Если вы намерены использовать клавиатуру в качестве HID-устройства (что вам следует ;-) ), выбранная вами плата должна быть способна на это. Я знаю, что Леонардо и DUE имеют эту функцию. Вот ссылка, объясняющая использование клавиатуры: https://www.arduino.cc/reference/en/language/functions/usb/keyboard/, @Peter Paul Kiefer
И если вы выберете, например, Mega, как предложено в одном ответе, это видео может быть полезным: https://www.youtube.com/watch?v=bTlM27jzOIQ, @Peter Paul Kiefer
@PeterPaulKiefer Пока я использую Micro, у которого также есть возможность HW USB :) http://micro-corner.gilhad.cz/blog/Arduino/progs/KlikiMouse3/images/klikimouse.s.jpg http://micro- Corner.gilhad.cz/blog/Arduino/progs/KlikiMouse3/2019-04-29-Arduino-progs-Klikimouse3.html, так как это довольно дешево с Aliexpress :), @gilhad
Забавно, я так часто видел эту деталь в интернет-магазинах, но не знал об этой функции. Он имеет 32u4 MCU. Спасибо, что указали мне на это. То есть вы будете использовать его в дополнение к более крупному микроконтроллеру, который может считывать ввод с клавиатуры? Или вы планируете использовать сдвиговые регистры (также известные как расширители портов, такие как MCP23S17)?, @Peter Paul Kiefer
Если вас интересуют другие бренды: знаете ли вы серию STM32 Nucleo F? Это платы с микроконтроллерами STM32 ARM M0-M4 в ценовом диапазоне от 10 до 20 долларов с разъемами arduino и собственными разъемами (Morpho) с полной распиновкой ~55 IO Pin. Они также имеют богатый набор коммуникационных интерфейсов. Вот ссылка на MCU серии F3 https://www.st.com/en/microcontrollers-microprocessors/stm32f3-series.html. (О, и у них есть гибкая матрица межсоединений. Выбирайте контакты ;-)), @Peter Paul Kiefer
@PeterPaulKiefer Я бы, вероятно, использовал гораздо более дешевые 74HC138 или 74HC595 для вывода или 74HC165 для ввода :) или просто использовал Blue Pill, как я делал для старой клавиатуры PS/2 :) http://download.gilhad.cz/STM-keyboard.s .jpg, @gilhad