Эмуляция матричной клавиатуры
- Войдите на сайт для отправки комментариев
Пнд, 25/06/2018 - 17:39
Всем привет!
Имеется контроллер с матричной клавиатурой 4х4. Есть возможность управления этим контроллером только через клавиатуру. Доступа к прошивке нет.
Стоит задача удаленно вводить команды на этот контроллер.
Для эмуляции клавиатуры решил взять ESP32s и подключить параллельно.
Написал прошивку, но както работает криво. Вводит значения невпопад.
//Сорри код не причесан и не оптимизирован. Писал для теста char keys[4][4]={ {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'}}; byte rowPin[4]={13,12,14,27}; byte colPin[4]={26,25,33,32}; char testInput[] = "123456789*0#"; int cur = 0; //Cursor void setup() { Serial.begin(115200); Serial.println("Hello!"); //Init pins for(byte row : rowPin) { pinMode(row, OUTPUT); digitalWrite(row, HIGH); } for(byte col : colPin) { pinMode(col, INPUT_PULLUP); } } int pos[2] = {-1, -1}; //Current position of char in keys matrix (row, column) long delayTime = 100; long startTime = 0; void loop() { if (cur < sizeof(testInput)) { char toInput = testInput[cur]; findPosition(toInput, pos); int row = pos[0]; int column = pos[1]; if (row >= 0) { if(!digitalRead(colPin[column])) { if (startTime == 0) { startTime = millis(); digitalWrite(rowPin[row], LOW); } else { if (millis() - startTime > delayTime) { digitalWrite(rowPin[row], HIGH); startTime = 0; cur++; } } } else { digitalWrite(rowPin[row], HIGH); } } } } void findPosition(char c, int result[]) { result[0] = -1; result[1] = -1; for(int row = 0; row < sizeof(keys); row++) { for(int col = 0; col < sizeof(keys[row]); col++) { if (c == keys[row][col]) { result[0] = row; result[1] = col; } } } }
Решил попробовать другой подход - замыкать контакты транзисторами. Придется взять 16 транзисторов и задействовать 16 управляющих пинов на контроллере...
Можно както уменьшить количество задействованных пинов?
Заранее спасибо
Отца русской демокартии спасёт любой 16-битовый демультиплексор или сдвиговый регистр (например, SN54LS673), ну или два восьмибитовых (хоть тех же 74HC595) - каскадом.
Невпопад потому что несинхронно с опросом рядов/колонок ?
Замыкать линии кнопок лучше не транзисторами, а оптронами. Делали уже не раз.Все 16 кнопок нужны? Тогда как писал ЕвгенийП.
Если там стандарная схема (по 4 выходным линиям бегает "1" или "0", которая замыкается кнопкой на одну из четырех входных), то никакие доп. детали не нужны. Считывайте ардуиной 4 бита и в нужное время подавайте 1 или 0 на соответствующую входную линию контроллера.
Добавлено: без мультиплексоров нужно 8 пинов.
это для эха или эмуляции, для того и другого сразу нужно 12 пин
я бы даже PCF8574 посоветовал, он двунаправленный и работает по i2c. В один ниббл пишешь бегущий 0, из другого ниббла читаешь кнопку. у него ить еще и прерывание есть по изменению входа.
Ну, если переходить на последовательные, то может MCP23S17? 16 бит, двунаправленный на SPI
это для эха или эмуляции, для того и другого сразу нужно 12 пин
я бы даже PCF8574 посоветовал, он двунаправленный и работает по i2c. В один ниббл пишешь бегущий 0, из другого ниббла читаешь кнопку. у него ить еще и прерывание есть по изменению входа.
м.б.
что совой об пень, что пнем об сову.
Невпопад потому что несинхронно с опросом рядов/колонок ?
Думаю да. Хотя почему так? Ведь я читаю состояние ряда и если на нем 0, то в этот же момент отправляю 0 нужному столбцу
Замыкать линии кнопок лучше не транзисторами, а оптронами. Делали уже не раз.Все 16 кнопок нужны? Тогда как писал ЕвгенийП.
Почему оптроны? Чем они лучше транзисторов?
Если там стандарная схема (по 4 выходным линиям бегает "1" или "0", которая замыкается кнопкой на одну из четырех входных), то никакие доп. детали не нужны. Считывайте ардуиной 4 бита и в нужное время подавайте 1 или 0 на соответствующую входную линию контроллера.
В теории это правильно. Тогда почему не работает у меня? Я считываю состояние ряда и если там 0, то в этот же момент подаю 0 на столбец. Решил всетаки замыкать контакты транзисторами или оптронами. Так надежней. Малейший рассинхрон и может ввести чтото не то.
я бы даже PCF8574 посоветовал, он двунаправленный и работает по i2c. В один ниббл пишешь бегущий 0, из другого ниббла читаешь кнопку. у него ить еще и прерывание есть по изменению входа.
Круто! Но считывать клавиатуру задача не стоит) Надо сделать как можно проще и надежней))
Для управления, по совету ЕвгенийП, решил взять пару 74HC595(есть в наличии). В качестве ключей сначала подумал взять четыре транзисторных сборки ULN2003AN, но потом прикинул что по габаритам сборка больше чем 4 отдельных транзистора в корпусе ТО-92
Есть сборки на 8 транзисторов, например, ULN2803
Есть сборки на 8 транзисторов, например, ULN2803
Там общий эмитер. Из восьми транзисторов получится использовать только 4 - общий на ряд и 4 вывода на каждый столбец
Если там стандарная схема (по 4 выходным линиям бегает "1" или "0", которая замыкается кнопкой на одну из четырех входных), то никакие доп. детали не нужны. Считывайте ардуиной 4 бита и в нужное время подавайте 1 или 0 на соответствующую входную линию контроллера.
В теории это правильно. Тогда почему не работает у меня?
для начала добавь какой-нибудь делэй200 в цикл - м.б, контроллер просто не успевает за ардуиной. если не взлетит - попробуй вместо сомнительного цикла по testInput эмулировать одну кнопку и т.д.
Если там стандарная схема (по 4 выходным линиям бегает "1" или "0", которая замыкается кнопкой на одну из четырех входных), то никакие доп. детали не нужны. Считывайте ардуиной 4 бита и в нужное время подавайте 1 или 0 на соответствующую входную линию контроллера.
В теории это правильно. Тогда почему не работает у меня?
Это и есть самая интересная часть вопроса :) Наверно надо бы начать с определения параметров сканирования клавиатуры. строб там 0 или 1? какова его длительность? А электронику пилять в слепую не стоит.
Это и есть самая интересная часть вопроса :) Наверно надо бы начать с определения параметров сканирования клавиатуры. строб там 0 или 1? какова его длительность? А электронику пилять в слепую не стоит.
Если там используется стандартная либа Keypad то пины столбцов инициализированы как OUTPUT, a ряды INPUT_PULLUP
При сканировании подается сигнал LOW
В реальности можно только гадать что там используется. Осцилографа нет.
Это и есть самая интересная часть вопроса :) Наверно надо бы начать с определения параметров сканирования клавиатуры. строб там 0 или 1? какова его длительность? А электронику пилять в слепую не стоит.
В реальности можно только гадать что там используется. Осцилографа нет.
Сделал эмулятор неизвестно чего, "Написал прошивку, но както работает криво. Вводит значения невпопад." - ну как же не удивиться?
ну как же не удивиться?
Реальный контроллер находится за 100 км от меня и это не простая ардуинка, а устройство на чипе ATmega 2560. Это устройство управляет топливо-раздаточной колонкой на АЗС склада. Там вэб сервер, БД, интерфейсы RS-232, RS-485, и контроль доступа по картам RFID. Взять его для изучения и тестов на долгое время не получится.
Я предположил что там используется стандартная либа Keypad и собрал макет из Arduino UNO и Esp23s. Програмно эмулировать клавиатуру не получилось, да и если б както получилось, то возможно, приехав на объект для тестирования пришлось бы удивляться что это не работает.
Поэтому выбрал реально универсальное и надежное решение спаять схему на ключах.
схему этого универсального решения мы наверно так и не увидим
в реальности можно только гадать что там используется. Осцилографа нет.
Зачем же гадать. Подключаем ардуину к стробам. Считываем состояние стробов ардуиной и ждем изменений. Как только хоть один строб хоть как изменится - состояние стробов и время из миллиса выводим в сириал. Потом монитором принимаем этот поток и мозгами анализируем как и насколько быстро там стробирование идет. Пол часа и все понятно. Но если сильно быстро все работает, то будет затык, сириал не будет успевать. Не беда, обявляем буфер в 1К, сохраняем инфу в нем, как заполнится то неспеша выводим.
del
схему этого универсального решения мы наверно так и не увидим