Автомобильный портал - Retrovaz

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

Аппаратное обеспечение:

- плата
- макетная плата
- светодиод
- резистор 220 Ом

Электрическая цепь:

Соедините анод (длинный вывод) вашего светодиода с цифровым выводом 9 Arduino через резистор 220 Ом. Соедините катод (короткий вывод) с землей (GND) Arduino.



Схема:


Код:

В функции setup() нужно назначить вывод 9 выходом.
Функция analogWrite() которую вы будете использовать в основном цикле имеет два аргумента: первый говорит функции какой вывод использовать, во второй записывают значение для ШИМ.
Для того чтобы плавно увеличить яркость светодиода, а потом плавно уменьшить вам нужно сначала увеличивать значение ШИМ от 0 (светодиод выключен) до 255 (максимальная яркость), а потом наоборот. В нашей программе переменная отвечающая за значение ШИМ будет называться brightness. В каждом цикле эта переменная будет изменятся на значение fadeAmount.
Как только brightness достигнет значения 255 или 0 fadeAmount изменит свой знак. Таким способом мы сможем поменять увеличения яркости на понижение и наоборот.
analogWrite() изменяет значение ШИМ очень быстро, потому нужна задержка для контроля скорости изменения яркости. Вы можете сами изменять значения задержки и смотреть как это скажется на работе.

Полный текст программы:

/*

Этот пример показывает как изменять яркость светодиода на выводе 9

используя функцию analogWrite().

*/

int led = 9; // вывод светодиода 9

int brightness = 0; // переменная отвечающая за яркость

int fadeAmount = 5; // переменная, которая задает скорость изменения яркости за цикл

// настройки:

void setup() {

// назначим вывод 9 выходом :

pinMode (led, OUTPUT);

// основной цикл :

void loop () {

// устанавливаем яркость светодиода на выводе 9:

analogWrite (led, brightness);

// изменим значение яркости для следующего прохода цикла:

brightness = brightness + fadeAmount;

// поменяем направление изменения яркости :

if (brightness == 0 || brightness == 255) {

fadeAmount = -fadeAmount ;

// ждем 30 миллисекунд для наблюдения эффекта диммирования:

delay (30);




- полный каталог плат

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

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

- 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 .

Список деталей для эксперимента

Для дополнительного задания

    еще 1 светодиод

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

    еще 2 провода

Принципиальная схема

Схема на макетке

Обратите внимание

    Мы подключили «землю» светодиода и переменного резистора (потенциометра) к длинной рельсе «-» макетной платы, и уже ее соединили с входом GND микроконтроллера. Таким образом мы использовали меньше входов и от макетки к контроллеру тянется меньше проводов.

    Подписи «+» и «-» на макетке не обязывают вас использовать их строго для питания, просто чаще всего они используются именно так и маркировка нам помогает

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

    Для считывания аналогового сигнала, принимающего широкий спектр значений, а не просто 0 или 1, как цифровой, подходят только порты, помеченные на плате как «ANALOG IN» и пронумерованные с префиксом A . Для Arduino Uno - это A0-A5.

Скетч

p030_pot_light.ino // даём разумные имена для пинов со светодиодом // и потенциометром (англ potentiometer или просто «pot») #define LED_PIN 9 #define POT_PIN A0 void setup() { // пин со светодиодом - выход, как и раньше... pinMode(LED_PIN, OUTPUT) ; // ...а вот пин с потенциометром должен быть входом // (англ. «input»): мы хотим считывать напряжение, // выдаваемое им pinMode(POT_PIN, INPUT) ; } void loop() { // заявляем, что далее мы будем использовать 2 переменные с // именами rotation и brightness, и что хранить в них будем // целые числа (англ. «integer», сокращённо просто «int») int rotation, brightness; // считываем в rotation напряжение с потенциометра: // микроконтроллер выдаст число от 0 до 1023 // пропорциональное углу поворота ручки rotation = analogRead(POT_PIN) ; // в brightness записываем полученное ранее значение rotation // делённое на 4. Поскольку в переменных мы пожелали хранить // целые значения, дробная часть от деления будет отброшена. // В итоге мы получим целое число от 0 до 255 brightness = rotation / 4 ; // выдаём результат на светодиод analogWrite(LED_PIN, brightness) ; }

Пояснения к коду

    С помощью директивы #define мы сказали компилятору заменять идентификатор POT_PIN на A0 - номер аналогового входа. Вы можете встретить код, где обращение к аналоговому порту будет по номеру без индекса A . Такой код будет работать, но во избежание путаницы с цифровыми портами используйте индекс.

    Переменным принято давать названия, начинающиеся со строчной буквы.

    Чтобы использовать переменную, необходимо ее объявить, что мы и делаем инструкцией:

int rotation, brightness;

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

    Функция analogRead(pinA) возвращает целочисленное значение в диапазоне от 0 до 1023, пропорциональное напряжению, поданному на аналоговый вход, номер которого мы передаем функции в качестве параметра pinA

    Обратите внимание, как мы получили значение, возвращенное функцией analogRead() : мы просто поместили его в переменную rotation с помощью оператора присваивания = , который записывает то, что находится справа от него в ту переменную, которая стоит слева

Вопросы для проверки себя

    Можем ли мы при сборке схемы подключить светодиод и потенциометр напрямую к разным входам GND микроконтроллера?

    В какую сторону нужно крутить переменный резистор для увеличения яркости светодиода?

    Что будет, если стереть из программы строчку pinMode(LED_PIN, OUTPUT) ? строчку pinMode(POT_PIN, INPUT) ?

    Зачем мы делим значение, полученное с аналогового входа перед тем, как задать яркость светодиода? что будет, если этого не сделать?

И попробуем выполнить новую задачу. Думаю, что все видели новогодние витринные гирлянды, в которых плавно мигают светодиоды. Допустим, что мы хотим сделать нечто подобное.
Мы уже рассматривали функцию 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 и добьемся должного результата.

Ардуино идеально подходит для управления любыми устройствами. Микропроцессор ATmega с помощью программы-скетча манипулирует большим количеством дискретных выводов, аналогово-цифровых входов/выводов и ШИМ-контроллерами.

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

Принцип управления нагрузкой через Ардуино

Плата Ардуино имеет два типа портов вывода: цифровой и аналоговый (ШИМ-контроллер). У цифрового порта возможно два состояния – логический ноль и логическая единица. Если подключить к нему светодиод он либо будет светиться, либо не будет.

Аналоговый выход представляет собой ШИМ-контроллер, на который подаётся сигнал частотой около 500Гц с регулируемой скважностью. Что такое ШИМ-контроллер и принцип его работы можно найти в интернете. Через аналоговый порт возможно не только включать и выключать нагрузку, а и изменять напряжение (ток) на ней.

Синтаксис команд

Цифровой вывод:

pinMode(12, OUTPUT); — задаём порт 12 портом вывода данных;
digitalWrite(12, HIGH); — подаём на дискретный выход 12 логическую единицу, зажигая светодиод.

Аналоговый вывод:

analogOutPin = 3; – задаём порт 3 для вывода аналогового значения;
analogWrite(3, значение); – формируем на выходе сигнал с напряжением от 0 до 5В. Значение – скважность сигнала от 0 до 255. При значении 255 максимальное напряжение.

Способы управления светодиодами через Ардуино

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

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

Виды транзисторных ключей

  • Биполярный;
  • Полевой;
  • Составной (сборка Дарлингтона).
Способы подключения нагрузки
Через биполярный транзистор Через полевой транзистор Через коммутатор напряжения

При подаче высокого логического уровня (digitalWrite(12, HIGH);) через порт вывода на базу транзистора через цепочку коллектор-эмиттер потечет опорное напряжение на нагрузку. Таким образом можно включать и отключать светодиод.

Аналогичным образом работает и полевой транзистор, но поскольку у него вместо «базы» сток, который управляется не током, а напряжением, ограничительный резистор в этой схеме необязателен.

Биполярный вид не позволяет регулировать мощные нагрузки. Ток через него ограничен на уровне 0,1-0,3А.

Полевые транзисторы работают с более мощными нагрузками с током до 2А. Для ещё более мощной нагрузки используют полевые транзисторы Mosfet с током до 9А и напряжением до 60В.

Вместо полевых можно использовать сборку Дарлингтона из биполярных транзисторов на микросхемах ULN2003, ULN2803.

Микросхема ULN2003 и принципиальная схема электронного коммутатора напряжения:

Принцип работы транзистора для плавного управления светодиодной лентой

Транзистор работает как водопроводный кран, только для электронов. Чем выше напряжение, подаваемое на базу биполярного транзистора либо сток полевого, тем меньше сопротивление в цепочке эмиттер-коллектор, тем выше ток, проходящий через нагрузку.

Подключив транзистор к аналоговому порту Ардуино, присваиваем ему значение от 0 до 255, изменяем напряжение, подаваемое на коллектор либо сток от 0 до 5В. Через цепочку коллектор-эмиттер будет проходить от 0 до 100% опорного напряжения нагрузки.

Для управления светодиодной лентой arduino необходимо подобрать транзистор подходящей мощности. Рабочий ток для питания метра светодиодов 300-500мА, для этих целей подойдет силовой биполярный транзистор. Для большей длины потребуется полевой транзистор.

Схема подключения LED ленты к ардуино:

Управление RGB лентой с помощью Andurino

Кроме однокристальных светодиодов, Ардуино может работать и с цветными LED. Подключив выводы каждого цвета к аналоговым выходам Ардуино можно произвольно изменять яркость каждого кристалла, добиваясь необходимого цвета свечения.

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

Аналогично построено и управление RGB лентой Arduino:

Аrduino RGB контроллер лучше собирать на полевых транзисторах.

Для плавного управления яркостью можно использовать две кнопки. Одна будет увеличивать яркость свечения, другая уменьшать.

Скетч управления яркостью светодиодной ленты Arduino

int led = 120; устанавливаем средний уровень яркости

void setup() {
pinMode(4, OUTPUT); устанавливаем 4й аналоговый порт на вывод
pinMode(2, INPUT);

pinMode(4, INPUT); устанавливаем 2й и 4й цифровой порт на ввод для опроса кнопок
}
void loop(){

button1 = digitalRead(2);

button2 = digitalRead(4);
if (button1 == HIGH) нажатие на первую кнопку увеличит яркость
{
led = led + 5;

analogWrite(4, led);
}
if (button2 == HIGH) нажатие на вторую кнопку уменьшит яркость
{
led = led — 5;

analogWrite(4, led);
}

При удержании первой или второй кнопки плавно изменяется напряжение, подаваемое на управляющий контакт электронного ключа. Тогда и произойдет плавное изменение яркости.

Модули управления Ардуино

Для создания полноценного драйвера управления светодиодной лентой можно использовать модули-датчики.

ИК-управление

Модуль позволяет запрограммировать до 20 команд.

Радиус сигнала около 8м.

Цена комплекта 6 у.е.

По радиоканалу

Четырёхканальный блок с радиусом действия до 100м

Цена комплекта 8 у.е.

Позволяет включать освещение еще при приближении к квартире.

Бесконтактное

Датчик расстояния способен по движению руки увеличивать и уменьшать яркость освещения.

Радиус действия до 5м.

Цена модуля 0,3 у.е.

Понравилась статья? Поделитесь с друзьями!
Была ли эта статья полезной?
Да
Нет
Спасибо, за Ваш отзыв!
Что-то пошло не так и Ваш голос не был учтен.
Спасибо. Ваше сообщение отправлено
Нашли в тексте ошибку?
Выделите её, нажмите Ctrl + Enter и мы всё исправим!