Ардуино плавное включение rgb светодиода от кнопки. Управление яркостью светодиода при помощи потенциометра. Описание программы для Arduino

В этом эксперименте мы добавляем порцию яркости светодиоду одной кнопкой и убавляем другой.

СПИСОК ДЕТАЛЕЙ ДЛЯ ЭКСПЕРИМЕНТА

- 1 плата Arduino Uno;

- 1 беспаечная макетная плата;

- 2 тактовых кнопки;

- 1 резистор номиналом 220 Ом;

- 1 светодиод;

- 7 проводов «папа-папа».

ПРИНЦИПИАЛЬНАЯ СХЕМА

СХЕМА НА МАКЕТНОЙ ПЛАТЕ

ОБРАТИТЕ ВНИМАНИЕ

  • Если вы переделываете схему из схемы предыдущего эксперимента, обратите внимание, что на этот раз нам нужно подключить светодиод к порту, поддерживающему ШИМ.

СКЕТЧ

скачать скетч для Arduino IDE
#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); } // Собственная функция с 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); // если был клик, меняем яркость в пределах от 0 до 255 if (!isUp) brightness = constrain(brightness + delta, 0, 255); } return isUp; // возвращаем значение обратно, в вызывающий код }

ПОЯСНЕНИЯ К КОДУ

  • Мы можем пользоваться не только встроенными функциями, но и создавать собственные. Это обоснованно, когда нам нужно повторять одни и те же действия в разных местах кода или, например, нужно выполнять одни и те же действия над разными данными, как в данном случае: обработать сигнал с цифровых портов 2 и 3.
  • Определять собственные функции можно в любом месте кода вне кода других функций. В нашем примере, мы определили функцию после loop .
  • Чтобы определить собственную функцию, нам нужно:
    • Объявить, какой тип данных она будет возвращать. В нашем случае это boolean . Если функция только выполняет какие-то действия и не возвращает никакого значения, используйте ключевое слово void
    • Назначить функции имя — идентификатор. Здесь действуют те же правила, что при именовании переменных и констант. Называть функции принято в том же стиле какПеременные .
    • В круглых скобках перечислить передаваемые в функцию параметры, указав тип каждого. Это является объявлением переменных, видимых внутри вновь создаваемой функции, и только внутри нее. Например, если в данном эксперименте мы попробуем обратиться к wasUp или isUp из loop() получим от компилятора сообщение об ошибке. Точно так же, переменные, объявленные в loop , другим функциям не видны, но их значения можно передать в качестве параметров.
    • Между парой фигурных скобой написать код, выполняемый функцией
    • Если функция должна вернуть какое-то значение, с помощью ключевого слова return указать, какое значение возвращать. Это значение должно быть того типа, который мы объявили
  • Так называемые глобальные переменные, т.е. переменные, к которым можно обратиться из любой функции, обычно объявляются в начале программы. В нашем случае — это brightness .
  • Внутри созданной нами функции handleClick происходит всё то же самое, что в эксперименте .
  • Поскольку при шаге прироста яркости 35 не более чем через восемь нажатий подряд на одну из кнопок значение выражения brightness + delta выйдет за пределы интервала . С помощью функции constrain мы ограничиваем допустимые значения для переменной brightness указанными границами интервала.
  • В выражении plusUp = handleClick(PLUS_BUTTON_ PIN , plusUp, +35) мы обращаемся к переменной plusUp дважды. Поскольку = помещает значение правого операнда в левый, сначала вычисляется, что вернет handleClick . Поэтому когда мы передаем ей plusUp в качестве параметра, она имеет еще старое значение, вычисленное при прошлом вызове handleClick .
  • Внутри handleClick мы вычисляем новое значение яркости светодиода и записываем его в глобальную переменную brightness , которая на каждой итерации loop просто передается в analogWrite .

ВОПРОСЫ ДЛЯ ПРОВЕРКИ СЕБЯ

  1. Что означает ключевое слово void ?
  2. Как ведет себя программа при упоминании одной переменной с разных сторон от оператора присваивания = ?

ЗАДАНИЯ ДЛЯ САМОСТОЯТЕЛЬНОГО РЕШЕНИЯ

  1. Доработайте код таким образом, чтобы шаг изменения яркости настраивался в одном месте.
  2. Создайте еще одну функцию и переделайте код так, чтобы одна функция отвечала за отслеживание нажатий, а другая — за вычисление яркости светодиода и возвращала его в analogWrite .

Теперь же разберемся с многоцветным светодиодом, который часто называют сокращенно: RGB-светодиод . RGB — это аббревиатура, которая расшифровывается как: Red — красный, Green — зеленый, Blue — синий. То есть внутри этого устройства размещается сразу три отдельных светодиода. В зависимости от типа, RGB-светодиод может иметь общий катод или общий анод.

1. Смешение цветов

Чем RGB-светодиод, лучше трех обычных? Всё дело в свойстве нашего зрения смешивать свет от разных источников, размещенных близко друг к другу. Например, если мы поставим рядом синий и красный светодиоды, то на расстоянии несколько метров их свечение сольется, и глаз увидит одну фиолетовую точку. А если добавим еще и зеленый, то точка покажется нам белой. Именно так работают мониторы компьютеров, телевизоры и уличные экраны. Матрица телевизора состоит из отдельно стоящих точек разных цветов. Если взять лупу и посмотреть через нее на включенный монитор, то эти точки можно легко увидеть. А вот на уличном экране точки размещаются не очень плотно, так что их можно различить невооруженным глазом. Но с расстояния несколько десятков метров эти точки неразличимы. Получается, что чем плотнее друг к другу стоят разноцветные точки, тем меньшее расстояние требуется глазу чтобы смешивать эти цвета. Отсюда вывод: в отличие от трех отдельностоящих светодиодов, смешение цветов RGB-светодиода заметно уже на расстоянии 30-70 см. Кстати, еще лучше себя показывает RGB-светодиод с матовой линзой.

2. Подключение RGB-светодиода к Ардуино

Поскольку многоцветный светодиод состоит из трех обычных, мы будем подключать их отдельно. Каждый светодиод соединяется со своим выводом и имеет свой отдельный резистор. В уроке мы используем RGB-светодиод с общим катодом, так что провод к земле будет только один. Принципиальная схема
Внешний вид макета

3. Программа для управления RGB-светодиодом

Составим простую программу, которая будет по очереди зажигать каждый из трех цветов. const byte rPin = 3; const byte gPin = 5; const byte bPin = 6; void setup() { pinMode(rPin, OUTPUT); pinMode(gPin, OUTPUT); pinMode(bPin, OUTPUT); } void loop() { // гасим синий, зажигаем красный digitalWrite(bPin, LOW); digitalWrite(rPin, HIGH); delay(500); // гасим красный, зажигаем зеленый digitalWrite(rPin, LOW); digitalWrite(gPin, HIGH); delay(500); // гасим зеленый, зажигаем синий digitalWrite(gPin, LOW); digitalWrite(bPin, HIGH); delay(500); } Загружаем программу на Ардуино и наблюдаем результат. Your browser does not support the video tag. Немного оптимизируем программу: вместо переменных rPin, gPin и bPin применим массив. Это нам поможет в следующих заданиях. const byte rgbPins = {3,5,6}; void setup() { for(byte i=0; i<3; i++) pinMode(rgbPins[i], OUTPUT); } void loop() { digitalWrite(rgbPins, LOW); digitalWrite(rgbPins, HIGH); delay(500); digitalWrite(rgbPins, LOW); digitalWrite(rgbPins, HIGH); delay(500); digitalWrite(rgbPins, LOW); digitalWrite(rgbPins, HIGH); delay(500); }

4. Семь цветов радуги

Теперь попробуем зажигать одновременно по два цвета. Запрограммируем такую последовательность цветов:
  • красный
  • красный + зеленый = желтый
  • зеленый
  • зеленый + синий = голубой
  • синий
  • синий + красный = фиолетовый
Оранжевый цвет мы для упрощения опустили. Так что, получилось шесть цветов радуги 🙂 const byte rgbPins = {3,5,6}; const byte rainbow = { {1,0,0}, // красный {1,1,0}, // жёлтый {0,1,0}, // зелёный {0,1,1}, // голубой {0,0,1}, // синий {1,0,1}, // фиолетовый }; void setup() { for(byte i=0; i<3; i++) pinMode(rgbPins[i], OUTPUT); } void loop() { // перебираем все шесть цветов for(int i=0; i<6; i++){ // перебираем три компоненты каждого из шести цветов for(int k=0; k<3; k++){ digitalWrite(rgbPins[k], rainbow[i][k]); } delay(1000); } } В результате работы программы получается: Your browser does not support the video tag.

5. Плавное изменение цвета

Мы не зря подключили RGB-светодиод к выводам 3, 5 и 6. Как известно, эти выводы позволяют генерировать ШИМ сигнал разной скважности. Другими словами, мы можем не просто включать или выключать светодиод, а управлять уровнем напряжения на нем. Делается это с помощью функции analogWrite . Сделаем так, что наш светодиод будет переходить между цветами радуги не скачкообразно, а плавно. const byte rgbPins = {3,5,6}; int dim = 1; void setup() { for(byte i=0; i<3; i++){ pinMode(rgbPins[i], OUTPUT); } // начальное состояние - горит красный цвет analogWrite(rgbPins, 255); analogWrite(rgbPins, 0); analogWrite(rgbPins, 0); } void loop() { // гасим красный, параллельно разжигаем зеленый for(int i=255; i>=0; i--){ analogWrite(rgbPins, i/dim); analogWrite(rgbPins, (255-i)/dim); delay(10); } // гасим зеленый, параллельно разжигаем синий for(int i=255; i>=0; i--){ analogWrite(rgbPins, i/dim); analogWrite(rgbPins, (255-i)/dim); delay(10); } // гасим синий, параллельно разжигаем красный for(int i=255; i>=0; i--){ analogWrite(rgbPins, i/dim); analogWrite(rgbPins, (255-i)/dim); delay(10); } } Переменная dim определяет яркость свечения. При dim = 1 имеем максимальную яркость. Загружаем программу на Ардуино. Your browser does not support the video tag.

Задания

  1. Индикатор температуры. Добавим в схему термистор и подключим его к аналоговому входу. Светодиод должен менять свой цвет в зависимости от температуры термистора. Чем ниже температура, тем более синий цвет, а чем выше, тем более красный.
  2. RGB лампа с регулятором. Добавим в схему три переменных резистора и подключим их к аналоговым входам. Программа должна непрерывно считывать значения резисторов и менять цвет соответствующей компоненты RGB-светодиода.

На этом примере Вы научитесь изменять яркость светодиода, используя резисторы с различным сопротивлением.

Для данного примера вам понадобятся

1 светодиод диаметром 5 мм

1 резистор на 270 Ом (красный, фиолетовый, коричневый)

1 резистор на 470 Ом (желтый, фиолетовый, коричневый)

1 резистор на 2.2 кОм (красный, красный, красный)

1 резистор на 10 кОм (коричневый, черный, оранжевый)

Светодиоды - общие сведения

Светодиоды отлично служат в устройствах для разного рода индикации. Они потребляют мало электричества и при этом долговечны.

В данном примере мы используем самые распространенные светодиды диаметром 5 мм. Также распространены светодиоды диаметром 3 миллиметра, ну и большие светодиоды диаметром 10 мм.

Подключать светодиод напрямую к батарейке или источнику напряжения не рекомендуется. Во-первых, надо сначала разобраться, где именно у светодиода отрицательная и положительная ноги. Ну а во вторых, необходимо использовать токоограничивающие резисторы, иначе светодиод очень быстро перегорит.

Если вы не будете использовать резистор со светодиодом, последний очень быстро выйдет из строя, так как через него будет проходить слишком большое количество тока. В результате светодиод нагреется и контакт, генерирующий свет, разрушится.

Различить позитивную и негативную ноги светодиода можно двумя способами.

Первый – позитивная нога длиннее.

Второй – при входе в корпус самого диода на коннекторе негативной ноги есть плоская кромка.

Если вам попался светодиод, на котором плоская кромка на более длинной ноге, длинная нога все равно является позитивной.

Резисторы - общие сведения

Resist – сопротивление (англ.)

Из названия можно догадаться, что резисторы сопротивляются потоку электричества. Чем больше номинал (Ом) резистора, тем больше сопротивление и тем меньше тока пройдет по цепи, в которой он установлен. Мы будем использовать это свойство резисторов для регулирования тока, который проходит через светодиод и, таким образом, его яркость.

Но сначала погорим немного о резисторах.

Единицы, в которых измеряется сопротивление – Ом, которые во многих источниках обозначаются греческой буквой Ω – Омега Так как Ом – маленькое значение сопротивления (практически незаметное в цепи), мы часто будем оперировать такими единицами как кОм - килоом (1000 Ом) и МОм мегаом (1000000 Ом).

В данном примере мы будем использовать резисторы с четырьмя различными номиналами: 270 Ω, 470 Ω, 2.2 кΩ и 10 кΩ. Размеры этих резисторов одинаковы. Цвет тоже. Единственное, что их различает – цветные полоски. Именно по этим полоскам визуально определяется номинал резисторов.

Для резисторов, у которых три цветные полоски и последняя золотистая, работают следующие соответствия:

Коричневый 1

Красный 2

Оранжевый 3

Зеленый 5

Фиолетовый 7

Первые две полоски обозначают первые 2 числовых значения, так что красный, филетовый означает 2, 7. Следующая полоска – количество нулей, которые необходимо поставить после первых двух цифр. То есть, если третья полоска коричневая, как на фото выше, будет один нуль и номинал резистора равен 270 Ω.

Резистор с полосками коричневого, черного, оранжевого цветов: 10 и три нуля, так что 10000 Ω. То есть, 10 кΩ.

В отличии от светодиодов, у резисторов нет положительной и и отрицательной ног. Какой именно ногой подключать их к питанию/земле – неважно.

Схема подключения

Подключите в соответствии со схемой, приведенной ниже:

На Arduino есть пин на 5 В для питания периферийных устройств. Мы будем его использовать для питания светодиода и резистора. Больше вам от платы ничего не потребуется, только лишь подключить ее через USB к компьютеру.

С резистором на 270 Ω, светодиод должен гореть достаточно ярко. Если вы вместо резистора на 270 Ω установите резистор номиналом 470 Ω, светодиод будет гореть не так ярко. С резистором на 2.2 кΩ, светодиод должен еще немного затухнуть. В конце-концов, с резистором 10 кΩ, светодиод будет еле виден. Вполне вероятно, чтобы увидеть разницу на последнем этапе вам придется вытянуть красный переходник, использовав его в качестве переключателя. Тогда вы сможете увидеть разницу в яркости.

Кстати, можно провести этот опыт и при выключенном свете.

Разные варианты установки резистора

В момент, когда к одной ноге резистора подключено 5 В, вторая нога резистора подключается к позитивной ноге светодиода, а вторая нога светодиода подключена к земле. Если мы переместим резистор так, что он будет располагаться за светодиодом, как показано ниже, светодиод все равно будет гореть.

Мигание светодиодом

Мы можем подключить светодиод к выходу Arduino. Переместите красный провод от пина питания 5V к D13, как это показано ниже.

Теперь загрузите пример “Blink”, который мы рассматривали . Обратите внимание, что оба светодиода – встроенный и установленный вами внешний начали мигать.

Давайте попробуем использовать другой пин на Arduino. Скажем, D7. Переместите коннектор с пина D13 на пин D7 и измените следующую строку вашего кода:

Загрузите измененный скетч на Arduino. Светодиод продолжит мигать, но на этот раз, используя питание от пина D7.

На предыдущих уроках мы познакомились с простейшими схемами — сборкой и . Сегодня собираем модель с потенциометром (переменным резистором) и светодиодом. Такая модель может использоваться для управления роботом.

Потенциометр — это переменный резистор с регулируемым сопротивлением. Потенциометры используются в робототехнике как регуляторы различных параметров — громкости звука, мощности, напряжения и т.п. В нашей модели от поворота ручки потенциометра будет зависеть яркость светодиода. Это также одна из базовых схем.

Видео-инструкция сборки модели:

Для сборки модели нам потребуется:

  • плата Arduino (или аналоги);
  • Breadboard;
  • 6 проводов и/или перемычек “папа-папа”;
  • светодиод;
  • потенциометр (переменный резистор);
  • резистор на 220 Ом;
  • среда Arduino IDE, которую можно скачать с сайта Arduino .

Что понадобится для подключения потенциометра и светодиода на Arduino?

Схема подключения модели Arduino с потенциометром и светодиодом:

Схема подключения модели Arduino с потенциометром и светодиодом

Для работы этой модели подойдет следующая программа (программу вы можете просто скопировать в Arduino IDE):

// даём имена пинов со светодиодом
// и потенциометром
#define led 9
#define pot A0
void setup()
{
// пин со светодиодом - выход
pinMode(led, OUTPUT);
// пин с потенциометром - вход
pinMode(pot, INPUT);
}
void loop()
{
// объявляем переменную x
int x;
// считываем напряжение с потенциометра:
// будет получено число от 0 до 1023
// делим его на 4, получится число в диапозоне
// 0-255 (дробная часть будет отброшена)
x = analogRead(pot) / 4;
// выдаём результат на светодиод
analogWrite(led, x);
}

Так выглядит собранная модель Arduino потенциометра со светодиодом:

Модель Arduino с потенциометром и светодиодом в собранном виде

На этом третий урок “Arduino для начинающих” закончен. Продолжение следует!

Посты по урокам:

  1. Первый урок: .
  2. Второй урок: .
  3. Третий урок: .
  4. Четвертый урок: .
  5. Пятый урок: .
  6. Шестой урок: .
  7. Седьмой урок: .
  8. Восьмой урок: .
  9. Девятый урок:

И попробуем выполнить новую задачу. Думаю, что все видели новогодние витринные гирлянды, в которых плавно мигают светодиоды. Допустим, что мы хотим сделать нечто подобное.
Мы уже рассматривали функцию digitalWrite() и знаем, что значение, которое она записывает, может быть двух вариантов - высокий или низкий уровень. В данном случае нам поможет функция analogWrite(). "Формулировки" функций различаются только начальными приставками, поэтому их легко запомнить.

Функция analogWrite(), так же как и digitalWrite(), содержит в скобках два аргумента и работает по тому же словесному принципу: "куда, что". Главным различием является возможность записи широкого диапазона значений вместо привычного LOW или HIGH. Это и позволит нам регулировать яркость светодиода. Главное замечание, которое необходимо учитывать, это то, что данная функция работает только на определенных контактах. Эти контакты обозначены символом "~". Этот символ означает, что это PWM-контакт. PWM (pulse-width modulation) звучит по-русски как ШИМ (широтно-импульсная модуляция). Принцип работы основан на изменении длительности импульса. Графически это можно изобразить так:

Давайте попробуем разобраться как это работает, рассмотрев простой пример. Для этого необходимо подключить светодиод к PWM-контакту через резистор номиналом 150 Ом и "зашить" в Arduino простенькую программу. Схема подключения и код скетча представлены ниже:


void setup()
{
pinMode(led,OUTPUT);
}

void loop()
{
for(int i=0; i<=255; i++)
{
analogWrite(led,i);
delay(10);
}
for(int i=255; i>=0; i--)
{
analogWrite(led,i);
delay(10);
}
}


Думаю, что в целом код понятен, но необходимо уделить немного внимания циклу for(). Существует такое понятие как разрешение. Поскольку мы работаем с 8-битным разрешением (это будет рассмотрено несколько позднее), то минимальному значению будет соответствовать 0, а максимальному - 255. В конце каждой итерации мы установили временную задержку в 10мс.

Давайте вернемся к схеме из предыдущего урока и попробуем сделать аналогичную гирлянду с использованием функции analogWrite().


int buttonPin = 2;
int pins = {3,5,6,9,10,11};

boolean lastButton = LOW;
boolean currentButton = LOW;
boolean enable = false;

void setup()
{
pinMode(buttonPin, INPUT);
for(int mode = 0; mode <= 5; mode++) pinMode(pins, OUTPUT);
}

boolean debounce(boolean last)
{
boolean current = digitalRead(buttonPin);
if(last != current)
{
delay(5);
current = digitalRead(buttonPin);
}
return current;
}

void loop()
{
currentButton = debounce(lastButton);
if(lastButton == LOW && currentButton == HIGH)
{
enable = !enable;
}

If(enable == true)
{
for (int i=0; i<=5; i++)
{
for (int brightness = 0; brightness <= 255; brightness++)
{
delay(1);
}
delay(40);
}
for (int i=0; i<=5; i++)
{
for (int brightness = 255; brightness >= 0; brightness--)
{
analogWrite(pins[i], brightness);
delay(1);
}
delay(40);
}
}

If(enable == false)
{
for(int i = 0; i <= 5; i++) digitalWrite(pins[i], LOW);
}

LastButton = currentButton;
}


Визуально скетч стал несколько сложнее. На самом деле здесь все просто и давайте в этом разберемся. Нам необходимо идентифицировать все подключенные светодиоды, но вместо привычного int led мы используем массив, каждый элемент которого является PWM-контактом на Arduino. В теле функции void setup() мы тоже поступили хитрым образом. "Перечислять" все контакты мы доверили циклу for(), с каждой итерацией которого производится конфигурация соответствующего контакта на OUTPUT. Переходим к функции void loop(). Функция debounce() и начальное условие if() остается без изменений. У нас по-прежнему идет проверка уровней двух переменных: предыдущее значение (изначально LOW) и текущее состояние кнопки. При выполнении этих условий значение переменной enable инвертируется. Учитывая это, мы добавили еще два простых условия if(). Если enable = true, то гирлянда включается, плавностью "перетекания" которой управляет цикл for(). Если же enable = false, то все светодиоды выключены. По окончанию условий переменная lastButton принимает текущее состояние кнопки.
Тестируя нашу программу, мы заметили, что все работает не должным образом. Помните, в прошлом уроке мы сделали поправку, что при большом значении временной задержки кнопка срабатывает по её истечению? В прошлом примере, при включенной гирлянде, суммарная задержка в теле функции void loop() составляла 85мс. Это давало нам возможность успеть "попасть" в определенной отрезок времени. В данном скетче, при том же условии, задержка отличается в несколько раз. Возможно, при желании выключить гирлянду напрашивается слово "прервать". Это и будет являться решением данной задачи!

Надеюсь, что эта статья была для Вас полезной. В следующем уроке мы рассмотрим прерывания в Arduino и добьемся должного результата.




Top