Возникла необходимость управлять 5 реле аналоговой клавиатурой.
Клавиатура состоит из 6 кнопок, которые сидят на аналоговом пине А2. Сигналы 6 кнопок дают следующие значения: 557, 594, 637, 686, 743, 811.
Задача следующая: 5 кнопок при нажатии должны включать/отключать 5 реле. При нажатии кнопки 6 все реле должны разом отключаться/включаться.
Собрал схему, загрузил скетч, но почему то реле отрабатывают через раз. Прошу глянуть скетч, может я что то накосячил в нем.
unsigned const short int KEYPAD_PIN = A2; // аналоговый порт для клавиатуры
const int relayPin1 = 2;
const int relayPin2 = 3;
const int relayPin3 = 4;
const int relayPin4 = 5;
const int relayPin5 = 6;
boolean relay1On = false; // текущее состояние реле
boolean relay2On = false; // текущее состояние реле
boolean relay3On = false; // текущее состояние реле
boolean relay4On = false; // текущее состояние реле
boolean relay5On = false; // текущее состояние реле
void setup() {
Serial.begin(9600);
pinMode(relayPin1, OUTPUT);
pinMode(relayPin2, OUTPUT);
pinMode(relayPin3, OUTPUT);
pinMode(relayPin4, OUTPUT);
pinMode(relayPin5, OUTPUT);
digitalWrite(relayPin1, HIGH);
digitalWrite(relayPin2, HIGH);
digitalWrite(relayPin3, HIGH);
digitalWrite(relayPin4, HIGH);
digitalWrite(relayPin5, HIGH);
}
void loop() {
int sensorValue = analogRead(KEYPAD_PIN);
int pressedButton = getPressedKeypadButton();
if (pressedButton == 1) {
relay1On = !relay1On;
digitalWrite(relayPin1, relay1On ? HIGH : LOW);
} else if (pressedButton == 2) {
relay2On = !relay2On;
digitalWrite(relayPin2, relay2On ? HIGH : LOW);
} else if (pressedButton == 3) {
relay3On = !relay3On;
digitalWrite(relayPin3, relay3On ? HIGH : LOW);
} else if (pressedButton == 4) {
relay4On = !relay4On;
digitalWrite(relayPin4, relay4On ? HIGH : LOW);
} else if (pressedButton == 5) {
relay5On = !relay5On;
digitalWrite(relayPin5, relay5On ? HIGH : LOW);
} else if (pressedButton == 6) {
// Включаем или выключаем все реле одновременно
relay1On = !relay1On;
relay2On = !relay2On;
relay3On = !relay3On;
relay4On = !relay4On;
relay5On = !relay5On;
digitalWrite(relayPin1, relay1On ? HIGH : LOW);
digitalWrite(relayPin2, relay2On ? HIGH : LOW);
digitalWrite(relayPin3, relay3On ? HIGH : LOW);
digitalWrite(relayPin4, relay4On ? HIGH : LOW);
digitalWrite(relayPin5, relay5On ? HIGH : LOW);
}
Serial.print("Analog Value: ");
Serial.print(sensorValue); // выводим значение аналогового сигнала в монитор порта
Serial.print(" Pressed Button: ");
Serial.println(pressedButton); // выводим номер нажатой кнопки в монитор порта
delay(500); // добавляем небольшую задержку для стабилизации и избежания множественных срабатываний
}
int getPressedKeypadButton() {
const int OCCURACY = 25;
int sensorValue = analogRead(KEYPAD_PIN);
int keys[] = {557, 594, 637, 686, 743, 811};
if(sensorValue > -OCCURACY && sensorValue < OCCURACY) {
return 0;
}
for (short int i = 0; i < 6; i++) {
if (sensorValue > (keys[i] - OCCURACY) && sensorValue < (keys[i] + OCCURACY)) {
return i + 1;
}
}
return 0;
}
Держите кнопку нажатой не менее полусекунды - будет срабатывать.
Но сравнивать надо не с окупаси, а с серединой между центральными значениями кнопок.
И, кстати, давайте схему. Я вот например, не знаю, если ли у Вас конденсатор на пине кнопок - от него тут много чего зависит. Да и вообще, без схемы трудно.
Как-то у Вас плохо подобраны кнопки. Значения должны начинаться 0 и следовать с примерно одинаковым интервалом.
Ну и, кроме того, Вам нужно сравнивать не с этими величинами, а с границами между кнопок, т.е. примерно с средним арифметическим между этими значениями.
При правильной резистивной матрице у меня работают 12 кнопок, без глюков, нажатие двух и более кнопок возможно, диапазоны значений:
35-70, 75-110, 115-150, 180-220, 290-330, 390-450, 530-580, 675-720, 770-810, 855-900, 905-945, 950-1023
Да, какие были резисторы в наличии. Вроде посчитал, что разница 40-50 единиц между значениями разных кнопок. Думал этого будет достаточно для корректной отработки. В принципе если оставляю только отработку кнопок и вывод в сериал значения кнопок - то значения кнопок отрабатывались вполне корректно, но когда в скетч добавляю обработку реле - тут уже начинает какая то туфта.
И такой вариант пробовал:
const int relayPin1 = 2;
const int relayPin2 = 3;
const int relayPin3 = 4;
const int relayPin4 = 5;
const int relayPin5 = 6;
boolean relay1On = false;
boolean relay2On = false;
boolean relay3On = false;
boolean relay4On = false;
boolean relay5On = false;
byte key() {
int val = analogRead(A2);
if (val < 250) return 0;
else if (val < 574) return 1;
else if (val < 617) return 2;
else if (val < 660) return 3;
else if (val < 700) return 4;
else if (val < 760) return 5;
else if (val < 830) return 6;
else return 0;
}
void setup() {
Serial.begin(9600);
pinMode(relayPin1, OUTPUT);
pinMode(relayPin2, OUTPUT);
pinMode(relayPin3, OUTPUT);
pinMode(relayPin4, OUTPUT);
pinMode(relayPin5, OUTPUT);
}
void loop() {
int button = key();
Serial.print("Кнопка ");
Serial.println(button);
switch (button) {
case 1:
relay1On = !relay1On;
digitalWrite(relayPin1, !relay1On);
break;
case 2:
relay2On = !relay2On;
digitalWrite(relayPin2, !relay2On);
break;
case 3:
relay3On = !relay3On;
digitalWrite(relayPin3, !relay3On);
break;
case 4:
relay4On = !relay4On;
digitalWrite(relayPin4, !relay4On);
break;
case 5:
relay5On = !relay5On;
digitalWrite(relayPin5, !relay5On);
break;
case 6:
relay1On = false;
relay2On = false;
relay3On = false;
relay4On = false;
relay5On = false;
digitalWrite(relayPin1, !relay1On);
digitalWrite(relayPin2, !relay2On);
digitalWrite(relayPin3, !relay3On);
digitalWrite(relayPin4, !relay4On);
digitalWrite(relayPin5, !relay5On);
break;
}
delay(100);
}