Вопрос POT+LED+BUTTON

Тема в разделе "Arduino & Shields", создана пользователем Morkou, 10 июл 2016.

  1. Morkou

    Morkou Нуб

    Всем привет!
    Добрался в книге Блума до потенциометра и решил совместить на данном этапе предыдущие уроки про кнопки, РГБ светодиоды и, собственно, потенциометры.
    Общий принцип сборки следующий. По кнопке можно включать/выключать светодиод и менять его цвет на красный, синий, зелёный и белый. Потенциометром можно менять его яркость от 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);    //физически изменить состояние светодиода
    }

    Заранее спасибо!
     

    Вложения:

  2. DIYMan

    DIYMan Гуру

    Tomasina нравится это.
  3. yul-i-an

    yul-i-an Гик

    Добавить фильтр
    Код (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);     //вывод значения переменной яркости диода в последовательный порт
    }