Здараствуйте! Долго ломаю голову как это сделать! Помогите, пожалуйста, кому не сложно. Задание: Создайте еще одну функцию и переделайте код так, чтобы одна функция отвечала за отслеживание нажатий, а другая — за вычисление яркости светодиода и возвращала его в analogWrite. Схема: Исходный скетч: #define PLUS_BUTTON_PIN 2 #define MINUS_BUTTON_PIN 3 #define LED_PIN 9 int brightness = 100; boolean plusUp = true; boolean minusUp = true; void setup() { pinMode(LED_PIN, OUTPUT); pinMode(PLUS_BUTTON_PIN, INPUT_PULLUP); pinMode(MINUS_BUTTON_PIN, INPUT_PULLUP); } void loop() { analogWrite(LED_PIN, brightness); plusUp = handleClick(PLUS_BUTTON_PIN, plusUp, +35); minusUp = handleClick(MINUS_BUTTON_PIN, minusUp, -35); } boolean handleClick(int buttonPin, boolean wasUp, int delta) { boolean isUp = digitalRead(buttonPin); if (wasUp && !isUp) { delay(10); isUp = digitalRead(buttonPin); if (!isUp) brightness = constrain(brightness + delta, 0, 255); } return isUp; }
Если понимать буквально, то вынести analogWrite(LED_PIN, brightness); в отдельную функцию и все. А смысл?
Пример полностью не дописал, попробуй, догадайся, что за handleClick? Взят отсюда http://shagir.ru/urok-11-svetilnik-s-knopochnym-upravleniem Не ломай голову – она еще пригодится! Код (Text): #define PLUS_BUTTON_PIN 2 #define MINUS_BUTTON_PIN 3 #define LED_PIN 9 int brightness = 100; boolean plusUp = true; boolean minusUp = true; void setup() { pinMode(LED_PIN, OUTPUT); pinMode(PLUS_BUTTON_PIN, INPUT_PULLUP); pinMode(MINUS_BUTTON_PIN, INPUT_PULLUP); } void loop() { analogWrite(LED_PIN, brightness); // реагируем на нажатия с помощью функции, написанной нами plusUp = handleClick(PLUS_BUTTON_PIN, plusUp, +35); minusUp = handleClick(MINUS_BUTTON_PIN, minusUp, -35); brightness = bright(plusUp, +35); // присваиваем новое значение } // Собственная функция с 3 параметрами: номером пина с кнопкой // (buttonPin), состоянием до проверки (wasUp) и градацией // яркости при клике на кнопку (delta). Функция возвращает // (англ. return) обратно новое, текущее состояние кнопки boolean handleClick(int buttonPin, boolean wasUp, int delta) { boolean isUp = digitalRead(buttonPin); if (wasUp && !isUp) { delay(10); isUp = digitalRead(buttonPin); } return isUp; // возвращаем значение обратно, в вызывающий код } int bright(boolean wasUp, int delta) { int value = delta; // сохраняем принятое значение, если не было клика if (!wasUp) { // если был клик, вычисляем яркость value = constrain(brightness + delta, 0, 255); } return value; // возвращаем новое значение }
Спасибо, получилось, но не совсем как хотел. Удалось заставить менять яркость светодиода только при отпускании кнопки. Может подскажите как всё таки это реализовать, чтобы функция срабатывала именно при нажатии? вот что у меня вышло: Код (Text): #define PLUS_BUTTON_PIN 2 #define MINUS_BUTTON_PIN 3 #define LED_PIN 9 int brightness = 100; boolean plusUp = true; boolean minusUp = true; void setup() { pinMode(LED_PIN, OUTPUT); pinMode(PLUS_BUTTON_PIN, INPUT_PULLUP); pinMode(MINUS_BUTTON_PIN, INPUT_PULLUP); } void loop() { analogWrite(LED_PIN, brightness); plusUp = handleClick(PLUS_BUTTON_PIN, plusUp); minusUp = handleClick(MINUS_BUTTON_PIN, minusUp); brightness = bright(plusUp, +35); brightness = bright(minusUp, -35); } boolean handleClick(int buttonPin, boolean wasUp) { boolean isUp = digitalRead(buttonPin); if (wasUp && !isUp) { delay(10); isUp = digitalRead(buttonPin); return !isUp; } } int bright(boolean wasUp, int delta) { int value = brightness; if (!wasUp) { value = constrain(brightness + delta, 0, 255); } return value; }
Как вариант прерывания и аппаратное подавление дребезга. Если нужен сам факт нажатия кнопки, то можно и не давить дребезг, выполнять действие на факт нажатия и уже потом делать delay, либо не делать вовсе.