Снова подниму эту тему. Сразу прошу прощения кому надоел. Сут в том, что значения все таки стали адекватно считываться, но пришлось поменять резисторы 10КОм на 200 ом и 2 и 3 пины поменять местами, относительно схемы, иначе значения ни в какую не считывались. Проблема в другом: считывание происходит с запозданием на 1 значение. Если 2 и 3 пины оставить как на схеме, то запоздания нет, но считывание не корректно. Подскажите, какую строку в скетче изменять, что бы считывание происходило сразу?
Там принцип как у энкодера? Два прерывателя по очереди контачат с плюсом или что? Антидребезг то добавили?
Нет, один контакт разомкнут при любом положении диска, кроме исходного, другой даёт количество импульсов равное номеру.
Я уж думал никто не отзовётся) #include <Bounce.h> #define PIN_SW_COUNTER 3 // Выход DC3 - на этом выходе считаем прервывания счетчика #define PIN_SW_REVERSE 2 // Выход DC2 - на этом выходе отмечаем конец набора цифры #define PIN_SW_HANGUP 4 // Выход DC4 - сюда подключаем рычаг сброса #define PIN_LED_PASS 8 // Выход DC8 - сюда сигналим в случае Успешного ввода кода #define PIN_LED_FAIL 12 // Выход DC12 = сюда сигналим в случае ошибочного кода #define LEN_PASSCODE 4 // Определяем длину кода const uint8_t pass[LEN_PASSCODE] = {1,1,1,1}; // Код для проверки uint8_t code[LEN_PASSCODE]; // в этом массиве будем запоминать введенные цифры uint8_t n_digits = 0; // счетчик кол-ва введенных цифр int valH = 0; int valC = 0; int valR = 0; int C_DEBOUNCE = 1000; // Задержка в млСек для обработки дребезга контактов прервывания Счетчика int R_DEBOUNCE = 40; // Задержка в млСек для обработки дребезга контактов прервывания Реверса volatile unsigned long last_miC; // таймстемп для обработки задержки внутри прерывания volatile unsigned long last_miR; // таймстемп для обработки задержки внутри прерывания volatile bool vSuccess = false; // Победа или Играем дальше volatile bool vSignal = false; // Сигнал давать? или нет? volatile int vPinState = HIGH; // Состояние выхода int vCount = 0; void setup() { Serial.begin(9600); // Определяем скорость соединения с монитором attachInterrupt(digitalPinToInterrupt(PIN_SW_REVERSE),iRevers,RISING); // Определяем процедуру обработки прерывания Реверса attachInterrupt(digitalPinToInterrupt(PIN_SW_COUNTER),iCounter,RISING); // Определяем процедуру обработки прерывания Счетчика 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() { digitalWrite(PIN_LED_PASS, vPinState); // Состояние по умолчанию HIGH - Работает нормально ЗАмкнутый контакт Реле DS2 digitalWrite(PIN_LED_FAIL, HIGH); // Состояние по умолчанию HIGH - Работает нормально РАЗомкнутый контакт Реле DS1 if (!digitalRead(PIN_SW_HANGUP)) // Если на этом выходе земля { for (uint8_t i = 0; i < n_digits; i++) code = 0; // чистим массив введенного кода valH = digitalRead(PIN_SW_HANGUP); // пишем в монитор Serial.print("HANGUP :"); Serial.println(valH); n_digits = 0; // начинаем считать сначала } if (vSignal) // если в результате обработки Прерывания Реверс нужно дать сигнал { if (vSuccess) // и если вдруг Победа, то { vPinState = LOW; // меняем сигнал на выходе победа digitalWrite(PIN_LED_PASS, vPinState); // реле клацает в DS2 начинает работать нормально РАЗомкнутый контакт - светодиод тушится Serial.print(vPinState); delay(3000); // ждем три секунды (можно либоо вообще не включать назад либо изменить и ждать больше - по желанию) vPinState = HIGH; digitalWrite(PIN_LED_PASS, vPinState); // зажигаем Победный светодиод снова (реле клацает в нормально DS2 ЗАмкнутое положение) } else { // если Играем дальше, то digitalWrite(PIN_LED_FAIL, LOW); // клацаем Реле DS1 в нормально РАЗомкнутое положение = Светодиод Ошибки горит первый раз delay(300); // ждем digitalWrite(PIN_LED_FAIL, HIGH); // тушим светодиод Ошибки delay(300); // ждем digitalWrite(PIN_LED_FAIL, LOW); // зажигаем светодиод Ошибки второй раз delay(300); // ждем digitalWrite(PIN_LED_FAIL, HIGH); // тушим второй Раз } vSignal = false; // возвращаем индикотор сигнала в исходное положение } } void iRevers(){ if ((long)(millis()-last_miR) >= R_DEBOUNCE){ // Задержка = обработка дребезга контактов valR = digitalRead(PIN_SW_REVERSE); if (valR == 1 && vCount > 0) { // Если реально закончили набирать цифру (физически сюда попадаем в начале и в конце набора цифры ... поэтому проверяем чтобы счетчик небыл пустым) if (vCount == 10) vCount = 0; // Обработка набора Ноля - в этом случае счетчик возвращает значение 10 code[n_digits]=vCount; // записываем очередную цифру в массив кода Serial.print("CODE:"); // выводим на монитор for (uint8_t i = 0; i < LEN_PASSCODE; i++) { Serial.print(code); } Serial.println(""); n_digits++; // считаем сколько цифр уже введено if (n_digits>=LEN_PASSCODE) // если код введен полностью { bool match = true; for (uint8_t i = 0; i < LEN_PASSCODE; i++) if (pass!=code) match = false; // по циклу проверяем каждую цифру if (match) // если Победа { //digitalWrite(PIN_LED_PASS, LOW); //digitalWrite(PIN_LED_FAIL, HIGH); Serial.println("SUCCESS!!!!"); vSuccess = true; // отмечаем Победу в переменной для следующей обработки } else // играем дальше {//digitalWrite(PIN_LED_PASS, HIGH); //digitalWrite(PIN_LED_FAIL, LOW); Serial.println("FAILED! TRY AGAIN"); vSuccess = false; // отмечаем Ошибку в переменной для следующей обработки } vSignal = true; // Взводим индикатор для того, чтобы подать сигнал либо Победа либо Ошибка Serial.print("CLEANED CODE:"); for (uint8_t i = 0; i < n_digits; i++) // Чистим Код { code = 0; Serial.print(code); } Serial.println(""); n_digits = 0; // Сбрасываем счетчик ввденных цифр кода } vCount=0; // Сбрасываем Счетчик last_miR = millis(); } } } void iCounter(){ if ((long)(millis()-last_miC) >= C_DEBOUNCE){ // Задержка для обработки дребезга контактов vCount++; // Если реально щелчек - то увеличиваем значение текущей цифры valC = digitalRead(PIN_SW_COUNTER); //Serial.print("COUNT :"); //Serial.println(vCount); last_miC = millis(); } }