Всем привет! Добрался в книге Блума до потенциометра и решил совместить на данном этапе предыдущие уроки про кнопки, РГБ светодиоды и, собственно, потенциометры. Общий принцип сборки следующий. По кнопке можно включать/выключать светодиод и менять его цвет на красный, синий, зелёный и белый. Потенциометром можно менять его яркость от 0 до 255. Я был бы очень благодарен, если бы опытные люди посмотрят код и дадут советы и замечания по написанию. Может что-то можно сделать лучше (всегда же можно )? В итоге все работает, но я столкнулся с некоторыми непонятностями. Я так понял, что у потенциометра есть свой дребезг. Это так? Когда я вывожу на экран значения, то в некоторых его положениях они постоянно прыгают в +-3. Причём когда включён режим белого света, то это дрожание происходит в больших положениях ручки потенциометра, чем при красном, синем или зелёном. Я снизил чувствительность вывода, игнорируя изменения показаний с потенциометра меньшие +-3. Это можно решить другим способом? Спойлер: Код скрипта Код (C++): // Программа считывания данных с потенциометра // Переключение цветов с кнопки // Управление яркостью РГБ диода с потенциометра const int BLED = 9; //Константа - номер контакта синего светодиода const int GLED = 10; //Константа - номер контакта зелёного светодиода const int RLED = 11; //Константа - номер контакта красного светодиода const int BUTTON = 2; //Константа - номер контакта кнопки boolean lastButton = LOW; //Переменная для сохранения предыдущего состояния кнопки boolean currentButton = LOW; //Переменная для сохранения текущего состояния кнопки int ledMode = 0; //Счётчик состояния цвета светодиода const int POT = 0; //аналоговый вход 0 для подключения потенциометра int val = 0; //переменная для хранения значения, считанного с потенциометра int LED_POWER_CURRENT = 0; //текущее значение analogWrite передаваемое с потенциометра int LED_POWER_LAST = 0; //предыдущее значение analogWrite передаваемое с потенциометра //текстовые переменные для подписи значений char strPOT[] = "Potentiometer value:"; char strLED[] = "LED intensity:"; char strSPACE[4] = "***"; void setup() { pinMode (BLED, OUTPUT); //Конфигурируем контакт синего светодиода как выход pinMode (GLED, OUTPUT); //Конфигурируем контакт зелёного светодиода как выход pinMode (RLED, OUTPUT); //Конфигурируем контакт красного светодиода как выход pinMode (BUTTON, INPUT); //Конфигурируем контакт кнопки как вход Serial.begin(9600); // инициирование последовтельного соединения /* * В первый раз считаем и выведем значения для показаний потенциометра и яркости */ val = analogRead(POT); // считывание значения с аналогового входа и запись в переменную val LED_POWER_CURRENT = floor(val/4); LED_POWER_LAST = LED_POWER_CURRENT; Serial.println("Welcome, User! The values of variables are:"); Serial.println(strPOT); Serial.println(val); //вывод значения переменной val в последовательный порт Serial.println(strLED); Serial.println(LED_POWER_CURRENT); //вывод значения переменной яркости диода в последовательный порт } /* * Функция сглаживания дребезга кнопки, * принимает предыдущее состояние кнопки * и возвращает фактическое. */ boolean debounce(boolean last) { boolean current = digitalRead(BUTTON); //считываем состояние кнопки if (last != current) //если состояние кнопки изменилось... { delay(5); //ждём 5мс current = digitalRead(BUTTON); //считываем состояние кнопки в подтверждение return current; //выгружаем из функции булево значение текущего состояния кнопки } } /* * Конец описания функции */ /* * Функция режима светодиода * Смена цвета по значению счётчика */ void setMode(int mode, int LE) { //выключен if (mode == 0) { analogWrite(RLED, 0); analogWrite(GLED, 0); analogWrite(BLED, 0); } //красный else if (mode == 1) { analogWrite(RLED, LE); analogWrite(GLED, 0); analogWrite(BLED, 0); } //зелёный else if (mode == 2) { analogWrite(RLED, 0); analogWrite(GLED, LE); analogWrite(BLED, 0); } //синий else if (mode == 3) { analogWrite(RLED, 0); analogWrite(GLED, 0); analogWrite(BLED, LE); } //белый else if (mode == 4) { analogWrite(RLED, LE); analogWrite(GLED, LE); analogWrite(BLED, LE); } } //Конец функции /* * функция вывода информации на экран и выдача значения яркости */ int writeOnScreen (int curLedPower) { Serial.println(strSPACE); // *** разделитель Serial.println(strPOT); Serial.println(val); //вывод значения переменной val в последовательный порт Serial.println(strPOT); Serial.println(curLedPower); //вывод значения переменной яркости диода в последовательный порт int lastLedPower = curLedPower; return lastLedPower; } void loop() { // put your main code here, to run repeatedly: /* * записываю в тек. состояние состояние кнопки. * подаётся в функцию сглаживания пред состояние, сравнивается с тек-м * и записывается в переменную текущего значения */ currentButton = debounce(lastButton); //считываем состояние кнопки, "очистив" его от дребезга if (lastButton == LOW && currentButton == HIGH) //если есть нажатие { ledMode++; //инвертируем состояние светодиода } lastButton = currentButton; //передать новое состояние кнопки в следующий ЛУП if (ledMode == 5) { ledMode = 0; } /* запись значений с потенциометра на вывод функции analogWrite, чтобы регулировать яркость диода, * размазав 1024 значений сигнала с потенциометра на 256 значений функции analogWrite * с округлением в меньшую сторону */ // Считывание с потенциометра val = analogRead(POT); // считывание значения с аналогового входа и запись в переменную LED_POWER_CURRENT = floor(val/4); delay(100); //если значение на потенциометре изменилось if (LED_POWER_LAST != LED_POWER_CURRENT) //проверяем, чтобы изменилось достаточно - для игнора дрожания показаний //потенциометра в обе стороны, чаще всего на белом диоде в пределах -+3 if (LED_POWER_LAST > LED_POWER_CURRENT+3) { //вызываем функцию вывода на экран и записываем ярк-ть LED_POWER_LAST = writeOnScreen(LED_POWER_CURRENT); } else if (LED_POWER_LAST < LED_POWER_CURRENT-3) { //вызываем функцию вывода на экран и записываем ярк-ть LED_POWER_LAST = writeOnScreen(LED_POWER_CURRENT); } setMode(ledMode,LED_POWER_LAST); //физически изменить состояние светодиода } Заранее спасибо!
Самый годный класс, который я юзаю для энкодера: https://github.com/Porokhnya/GreenhouseProject/blob/master/Main/Encoder.h https://github.com/Porokhnya/GreenhouseProject/blob/master/Main/Encoder.cpp Там и дребезг учтён, и кол-во импульсов на одно изменение учитывается.
Добавить фильтр Код (C++): //вариант 1 val = analogRead(POT); // считывание значения с аналогового входа и запись в переменную val LED_POWER_CURRENT = floor(val/4); LED_POWER_CURRENT=((LED_POWER_LAST*3)+LED_POWER_CURRENT)/4;//фильтр LED_POWER_LAST = LED_POWER_CURRENT; Serial.println("Welcome, User! The values of variables are:"); Serial.println(strPOT); Serial.println(val); //вывод значения переменной val в последовательный порт Serial.println(strLED); Serial.println(LED_POWER_CURRENT); //вывод значения переменной яркости диода в последовательный порт } //вариант 2 val = analogRead(POT); // считывание значения с аналогового входа и запись в переменную val LED_POWER_CURRENT = floor(val/4); if(abs(LED_POWER_CURRENT-LED_POWER_LAST)>2){ LED_POWER_CURRENT=LED_POWER_CURRENT; LED_POWER_LAST = LED_POWER_CURRENT; } Serial.println("Welcome, User! The values of variables are:"); Serial.println(strPOT); Serial.println(val); //вывод значения переменной val в последовательный порт Serial.println(strLED); Serial.println(LED_POWER_CURRENT); //вывод значения переменной яркости диода в последовательный порт }