Хочу создать кодовую панель с помощью дискового номеронабирателя старого телефона. Сам дисковый набиратель имеет 3 контакта, один из них общий. Первый замыкается однократно в течении всего обратного прокручивания диска. Второй замыкается столько, сколько выбрал на диске (имею ввиду цифру). Допустим, код имеет четырехзначное число. После введения правильной комбинации, пускай, например, включается светодиод №1. При введении неправильной комбинации включается светодиод №2. Также есть кнопка сброса, при которой один из включенных светодиодов выключается. Каким образом реализовать такое ?
По сути тот же энкодер, точнее его половина. Можно сделать на прерываниях, но проще и быстрее на подсчете импульсов (с дребезгодавом).
Общий контакт номеронабирателя на землю, два остальных на входы, сброс аналогично. Код (C++): #define PIN_SW_COUNTER 2 #define PIN_SW_REVERSE 3 #define PIN_SW_HANGUP 4 #define PIN_LED_PASS 5 #define PIN_LED_FAIL 6 #define LEN_PASSCODE 4 #define DELAY_DEBOUNCE 20 const uint8_t pass[LEN_PASSCODE] = {9,8,7,6}; uint8_t code[LEN_PASSCODE]; uint8_t n_digits = 0; void setup() { pinMode(PIN_SW_COUNTER, INPUT_PULLUP); pinMode(PIN_SW_REVERSE, INPUT_PULLUP); pinMode(PIN_SW_HANGUP, INPUT_PULLUP); pinMode(PIN_LED_PASS, OUTPUT); pinMode(PIN_LED_FAIL, OUTPUT); } void loop() { if (!digitalRead(PIN_SW_HANGUP)) { n_digits = 0; for (uint8_t i = 0; i < n_digits; i++) code[i] = 0; digitalWrite(PIN_LED_PASS, LOW); digitalWrite(PIN_LED_FAIL, LOW); } if (!digitalRead(PIN_SW_COUNTER)) { code[n_digits]++; delay(DELAY_DEBOUNCE); while (!digitalRead(PIN_SW_COUNTER)); delay(DELAY_DEBOUNCE); } if (!digitalRead(PIN_SW_REVERSE)) { n_digits++; delay(DELAY_DEBOUNCE); while (!digitalRead(PIN_SW_REVERSE)); delay(DELAY_DEBOUNCE); } if (n_digits>=LEN_PASSCODE) { bool match = true; for (uint8_t i = 0; i < LEN_PASSCODE; i++) if (pass[i]!=code[i]) match = false; if (match) digitalWrite(PIN_LED_PASS, HIGH); else digitalWrite(PIN_LED_FAIL, HIGH); n_digits = 0; for (uint8_t i = 0; i < n_digits; i++) code[i] = 0; } }
Спасибо! Подключил, но постоянно выдает неверный код. Светодиоды на разных пинах. Все время загорается PIN_LED_FAIL. Проблема наверное в том, что контакт COUNTER в спокойном состоянии постоянно замкнут с землей. Только при прокручивании диска, он размыкается и замыкается. Попробовал в ручную набивать код перемычкой по земле. при этом не забывая о замыкании/размыкании REVERSE, все равно выводит ложный код.
Перенес все на макетную плату. Оказалось, что скетч исполняется правильно, если сначала замыкается COUNTER, а потом только REVERSE. Но на дисковом набирателе эти контакты замыкаются наоборот: сналало REVERSE, а потом только COUNTER. Где подправить скетч? Заранее благодарен за ответ!
Например, набираем цифру 5. Сначало контактирует с землей - REVERSE, потом COUNTER. Далее COUNTER выполняет остальные 4 замыкания. После последнего отмыкания COUNTER от земли , отмыкается REVERSE.
Добрый день! Сломал голову как правильно инвертировать REVERSE, чтобы скетч заработал. Что только не добавлял. Опишу проблему еще раз: COUNTER в спокойном положении замкнут с землей, REVERSE - разомкнут. При прокручивании диска REVERSE замыкается с землей. Когда диск идет обратно, COUNTER замыкается N количество раз. Далее он опять переходит в состояние HIGH, а REVERSE в состояние LOW. Получается COUNTER должен считать не замыкания, а размыкания. Не могу допилить скетч чтобы и COUNTER, и REVERSE взаимодействовали одновременно. Пожалуйста, ткните носом меня, где именно поменять скетч))))
Код (C++): void loop() { if (digitalRead(PIN_SW_HANGUP)&&digitalRead(PIN_SW_REVERSE)) { n_digits = 0; for (uint8_t i = 0; i < n_digits; i++) code[i] = 0; digitalWrite(PIN_LED_PASS, LOW); digitalWrite(PIN_LED_FAIL, LOW); } if (digitalRead(PIN_SW_COUNTER)) { code[n_digits]++; delay(DELAY_DEBOUNCE); while (digitalRead(PIN_SW_COUNTER)); delay(DELAY_DEBOUNCE); } if (!digitalRead(PIN_SW_REVERSE)) { n_digits++; delay(DELAY_DEBOUNCE); while (!digitalRead(PIN_SW_REVERSE)); delay(DELAY_DEBOUNCE); Добрый день! Вот так попробовал объяснить, что в начале трубка положена и реверс разомкнут, код ниже не привожу, не могу понять где он упоротый
Добрый день! Итак, очередной день идет неравный бой с программой. Кто силен в программировании, пожалуйста, пролейте свет на вопрос правильно ли построено выражение, которое с переменной. Есть подозрение у меня, что оно верное, но для других компиляторов. Доказать не могу (. Но чуйка есть )
Добрый день! Удалось запустить дисковый телефон в режиме кодовой панели. Определенные трудности возникли по причине старости самого аппарата, пришлось немало потереть "накипи" на контактах, потом еще была отладка дребезга. Я так понимаю, что у пользователей, которые захотят воспользоваться кодом, который я прилагаю, возникнут такие же потребности отладки. Это зависит от конкретного экземпляра телефона.